# nooronclouds/asv architecture

> Architecture diagram of the GitHub repository nooronclouds/asv, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nooronclouds/asv
- Repository: https://github.com/nooronclouds/asv

## Overview

ASV is an authorized, external attack-surface visibility product: users submit scoped seed domains, then review ranked findings and changes across scans. The documented scan stages are represented separately; the orchestrator owns scope enforcement, pipeline execution, persistence, and diffing. The README documents capabilities beyond the sampled source, so those stages are shown from its architecture description. Frontend-to-API wiring is represented at the product boundary; detailed page request code was not sampled.

Main entry points: [`backend/app/attack_surface/orchestrator.py`](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/orchestrator.py) (Scan orchestrator), [`frontend/app/layout.tsx`](https://github.com/nooronclouds/asv/blob/main/frontend/app/layout.tsx) (Browser UI), [`backend/app/api/routes_attack_surface.py`](https://github.com/nooronclouds/asv/blob/main/backend/app/api/routes_attack_surface.py) (ASV endpoints), [`frontend/lib/asv/api.ts`](https://github.com/nooronclouds/asv/blob/main/frontend/lib/asv/api.ts) (ASV API client)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web application"]
  node_browser["Browser UI<br/>[layout.tsx]"]
  node_scanui["Scan submission<br/>[page.tsx]"]
  node_dashboard["Posture dashboard<br/>[page.tsx]"]
  node_findingsui["Findings view<br/>[page.tsx]"]
  node_runsui["Run history<br/>[page.tsx]"]
  node_clientapi["ASV API client<br/>[api.ts]"]
end

subgraph group_api["API and identity"]
  node_app["FastAPI application<br/>[main.py]"]
  node_authroutes["Auth endpoints<br/>[routes_auth.py]"]
  node_scanroutes["ASV endpoints"]
  node_security["JWT security<br/>[security.py]"]
end

subgraph group_pipeline["Scan pipeline"]
  node_orchestrator["Scan orchestrator<br/>[orchestrator.py]"]
  node_scope["Scope gate<br/>[scope.py]"]
  node_discovery["Asset discovery<br/>[discovery.py]"]
  node_probe["HTTP and TLS probe<br/>[probe.py]"]
  node_fingerprint["Service fingerprinting<br/>[fingerprint.py]"]
  node_scoring["Finding scoring<br/>[scoring.py]"]
  node_diff["Run comparison<br/>[diff.py]"]
end

subgraph group_state["Persistence and history"]
  node_database[("SQL datastore<br/>[database.py]")]
  node_asvmodels["Scan snapshot models<br/>[models.py]"]
  node_usermodels["User model<br/>[models.py]"]
end

node_operator(("Authorized user"))
node_ct["CT log service"]
node_dns["DNS services"]
node_targets["Authorized hosts"]

node_operator -->|"uses"| node_browser
node_browser -->|"opens"| node_scanui
node_browser -->|"opens"| node_dashboard
node_browser -->|"opens"| node_findingsui
node_browser -->|"opens"| node_runsui
node_scanui -->|"submits scan"| node_clientapi
node_dashboard -->|"requests posture"| node_clientapi
node_findingsui -->|"requests findings"| node_clientapi
node_runsui -->|"requests runs"| node_clientapi
node_clientapi -->|"HTTP requests"| node_app
node_app -->|"dispatches auth"| node_authroutes
node_app -->|"dispatches ASV"| node_scanroutes
node_authroutes -->|"creates tokens"| node_security
node_authroutes -->|"reads and writes users"| node_database
node_authroutes -->|"uses model"| node_usermodels
node_scanroutes -->|"authenticates"| node_security
node_scanroutes -->|"starts scan"| node_orchestrator
node_scanroutes -->|"queries scan data"| node_database
node_scanroutes -->|"queries models"| node_asvmodels
node_orchestrator -->|"builds authorization"| node_scope
node_orchestrator -->|"runs pipeline"| node_discovery
node_discovery -->|"queries CT logs"| node_ct
node_discovery -.->|"resolves or enumerates"| node_dns
node_orchestrator -->|"probes discovered assets"| node_probe
node_probe -->|"checks HTTP and TLS"| node_targets
node_orchestrator -->|"interprets services"| node_fingerprint
node_orchestrator -->|"scores fingerprints"| node_scoring
node_orchestrator -->|"persists snapshots"| node_database
node_orchestrator -->|"uses snapshot models"| node_asvmodels
node_orchestrator -->|"compares prior findings"| node_diff
node_diff -->|"loads prior run data"| node_database
node_orchestrator -->|"returns scan summary"| node_scanroutes
node_clientapi -->|"returns API data"| node_browser

click node_browser "https://github.com/nooronclouds/asv/blob/main/frontend/app/layout.tsx"
click node_scanui "https://github.com/nooronclouds/asv/blob/main/frontend/app/(app)/scan/page.tsx"
click node_dashboard "https://github.com/nooronclouds/asv/blob/main/frontend/app/(app)/dashboard/page.tsx"
click node_findingsui "https://github.com/nooronclouds/asv/blob/main/frontend/app/(app)/findings/page.tsx"
click node_runsui "https://github.com/nooronclouds/asv/blob/main/frontend/app/(app)/runs/page.tsx"
click node_clientapi "https://github.com/nooronclouds/asv/blob/main/frontend/lib/asv/api.ts"
click node_app "https://github.com/nooronclouds/asv/blob/main/backend/app/main.py"
click node_authroutes "https://github.com/nooronclouds/asv/blob/main/backend/app/api/routes_auth.py"
click node_scanroutes "https://github.com/nooronclouds/asv/blob/main/backend/app/api/routes_attack_surface.py"
click node_security "https://github.com/nooronclouds/asv/blob/main/backend/app/core/security.py"
click node_orchestrator "https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/orchestrator.py"
click node_scope "https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/scope.py"
click node_discovery "https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/discovery.py"
click node_probe "https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/probe.py"
click node_fingerprint "https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/fingerprint.py"
click node_scoring "https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/scoring.py"
click node_diff "https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/diff.py"
click node_database "https://github.com/nooronclouds/asv/blob/main/backend/app/db/database.py"
click node_asvmodels "https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/models.py"
click node_usermodels "https://github.com/nooronclouds/asv/blob/main/backend/app/db/models.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_browser,node_scanui,node_dashboard,node_findingsui,node_runsui,node_clientapi,node_operator toneBlue
class node_app,node_authroutes,node_scanroutes,node_security toneAmber
class node_orchestrator,node_scope,node_discovery,node_probe,node_fingerprint,node_scoring,node_diff toneMint
class node_database,node_asvmodels,node_usermodels toneRose
class node_ct,node_dns,node_targets toneIndigo
```

## Components

### Web application

- [Browser UI](https://github.com/nooronclouds/asv/blob/main/frontend/app/layout.tsx): `frontend/app/layout.tsx`
- [Scan submission](https://github.com/nooronclouds/asv/blob/main/frontend/app/(app)/scan/page.tsx): `frontend/app/(app)/scan/page.tsx`
- [Posture dashboard](https://github.com/nooronclouds/asv/blob/main/frontend/app/(app)/dashboard/page.tsx): `frontend/app/(app)/dashboard/page.tsx`
- [Findings view](https://github.com/nooronclouds/asv/blob/main/frontend/app/(app)/findings/page.tsx): `frontend/app/(app)/findings/page.tsx`
- [Run history](https://github.com/nooronclouds/asv/blob/main/frontend/app/(app)/runs/page.tsx): `frontend/app/(app)/runs/page.tsx`
- [ASV API client](https://github.com/nooronclouds/asv/blob/main/frontend/lib/asv/api.ts): `frontend/lib/asv/api.ts`

### API and identity

- [FastAPI application](https://github.com/nooronclouds/asv/blob/main/backend/app/main.py): `backend/app/main.py`
- [Auth endpoints](https://github.com/nooronclouds/asv/blob/main/backend/app/api/routes_auth.py): `backend/app/api/routes_auth.py`
- [ASV endpoints](https://github.com/nooronclouds/asv/blob/main/backend/app/api/routes_attack_surface.py): `backend/app/api/routes_attack_surface.py`
- [JWT security](https://github.com/nooronclouds/asv/blob/main/backend/app/core/security.py): `backend/app/core/security.py`

### Scan pipeline

- [Scan orchestrator](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/orchestrator.py): `backend/app/attack_surface/orchestrator.py`
- [Scope gate](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/scope.py): `backend/app/attack_surface/scope.py`
- [Asset discovery](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/discovery.py): `backend/app/attack_surface/discovery.py`
- [HTTP and TLS probe](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/probe.py): `backend/app/attack_surface/probe.py`
- [Service fingerprinting](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/fingerprint.py): `backend/app/attack_surface/fingerprint.py`
- [Finding scoring](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/scoring.py): `backend/app/attack_surface/scoring.py`
- [Run comparison](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/diff.py): `backend/app/attack_surface/diff.py`

### Persistence and history

- [SQL datastore](https://github.com/nooronclouds/asv/blob/main/backend/app/db/database.py): `backend/app/db/database.py`
- [Scan snapshot models](https://github.com/nooronclouds/asv/blob/main/backend/app/attack_surface/models.py): `backend/app/attack_surface/models.py`
- [User model](https://github.com/nooronclouds/asv/blob/main/backend/app/db/models.py): `backend/app/db/models.py`

### Other components

- **Authorized user**
- **CT log service**
- **DNS services**
- **Authorized hosts**

## Connections

- Authorized user → Browser UI: uses
- Browser UI → Scan submission: opens
- Browser UI → Posture dashboard: opens
- Browser UI → Findings view: opens
- Browser UI → Run history: opens
- Scan submission → ASV API client: submits scan
- Posture dashboard → ASV API client: requests posture
- Findings view → ASV API client: requests findings
- Run history → ASV API client: requests runs
- ASV API client → FastAPI application: HTTP requests
- FastAPI application → Auth endpoints: dispatches auth
- FastAPI application → ASV endpoints: dispatches ASV
- Auth endpoints → JWT security: creates tokens
- Auth endpoints → SQL datastore: reads and writes users
- Auth endpoints → User model: uses model
- ASV endpoints → JWT security: authenticates
- ASV endpoints → Scan orchestrator: starts scan
- ASV endpoints → SQL datastore: queries scan data
- ASV endpoints → Scan snapshot models: queries models
- Scan orchestrator → Scope gate: builds authorization
- Scan orchestrator → Asset discovery: runs pipeline
- Asset discovery → CT log service: queries CT logs
- Asset discovery → DNS services: resolves or enumerates
- Scan orchestrator → HTTP and TLS probe: probes discovered assets
- HTTP and TLS probe → Authorized hosts: checks HTTP and TLS
- Scan orchestrator → Service fingerprinting: interprets services
- Scan orchestrator → Finding scoring: scores fingerprints
- Scan orchestrator → SQL datastore: persists snapshots
- Scan orchestrator → Scan snapshot models: uses snapshot models
- Scan orchestrator → Run comparison: compares prior findings
- Run comparison → SQL datastore: loads prior run data
- Scan orchestrator → ASV endpoints: returns scan summary
- ASV API client → Browser UI: returns API data
