4.4 KiB
4.4 KiB
Reachability Drift Detection - Operations Guide
Module: Scanner Version: 1.0 Last Updated: 2025-12-22
1. Overview
Reachability Drift Detection compares call graph reachability between two scans and surfaces newly reachable or newly unreachable sinks. The API lives in the Scanner WebService and relies on call graph snapshots stored in PostgreSQL.
2. Prerequisites
2.1 Infrastructure Requirements
| Component | Minimum | Recommended | Notes |
|---|---|---|---|
| CPU | 4 cores | 8 cores | Call graph extraction is CPU heavy. |
| Memory | 4 GB | 8 GB | Large graphs need more memory. |
| PostgreSQL | 16+ | 16+ | Required for call graph + drift tables. |
| Valkey/Redis | 7.0+ | 7.0+ | Optional call graph cache. |
| .NET Runtime | 10.0 | 10.0 | Scanner WebService runtime. |
2.2 Required Services
- Scanner WebService running with storage configured.
- Call graph ingestion pipeline populating
call_graph_snapshots(Scanner Worker or external ingestion). - PostgreSQL migrations for call graph and drift tables applied (auto-migrate is enabled by default).
Optional:
- Valkey call graph cache (
CallGraph:Cache). - Signer service for drift attestations (if enabled by the integration layer).
3. Configuration
3.1 Scanner WebService
File: etc/scanner.yaml (path depends on deployment)
scanner:
storage:
dsn: "Host=postgres;Database=stellaops;Username=scanner;Password=${SCANNER_DB_PASSWORD}"
database: "scanner"
commandTimeoutSeconds: 30
autoMigrate: true
api:
basePath: "/api/v1"
scansSegment: "scans"
3.2 Call Graph Cache (Optional)
CallGraph:
Cache:
enabled: true
connection_string: "valkey:6379"
key_prefix: "callgraph:"
ttl_seconds: 3600
gzip: true
circuit_breaker:
failure_threshold: 5
timeout_seconds: 30
half_open_timeout: 10
3.3 Authorization (Optional)
scanner:
authority:
enabled: true
issuer: "https://authority.local"
requiredScopes:
- "scanner.scans.read"
- "scanner.scans.write"
4. Running Drift Analysis
- Ensure call graph snapshots exist for base and head scans.
- Compute drift by providing the base scan ID:
GET /api/v1/scans/{scanId}/drift?baseScanId={baseScanId}&language=dotnet
- Page through sinks:
GET /api/v1/drift/{driftId}/sinks?direction=became_reachable&offset=0&limit=100
If baseScanId is omitted, the API returns the most recent stored drift result for the head scan.
5. Deployment Modes
5.1 Standalone
- Run Scanner WebService with PostgreSQL reachable.
- Provide
scanner.storage.dsnandscanner.api.basePath.
5.2 Kubernetes
- Configure readiness and liveness probes (
/health/ready,/health/live). - Mount
scanner.yamlvia ConfigMap or Secret. - Ensure Postgres connectivity and schema migrations are enabled.
5.3 Air-Gapped
- Use Offline Kit flows for advisory data and signatures.
- Avoid external endpoints; configure any optional integrations to local services.
6. Monitoring and Metrics
There are no drift-specific metrics emitted by the drift endpoints yet. Recommended operational checks:
- API logs for
/api/v1/scans/{scanId}/driftand/api/v1/drift/{driftId}/sinks. - PostgreSQL table sizes and growth for
call_graph_snapshots,reachability_drift_results,drifted_sinks. - Valkey connectivity and cache hit rates if
CallGraph:Cacheis enabled.
7. Troubleshooting
| Symptom | Likely Cause | Resolution |
|---|---|---|
| 404 scan not found | Invalid scan ID | Verify scan ID or resolve by image reference. |
| 404 call graph not found | Call graph not ingested | Ingest call graph snapshot before running drift. |
| 404 drift result not found | No stored drift and no base scan provided | Provide baseScanId to compute drift. |
| 400 invalid direction | Unsupported direction value | Use became_reachable or became_unreachable. |
| 409 computation already in progress | Reachability job already running | Wait or retry later. |
8. References
docs/modules/scanner/reachability-drift.mddocs/api/scanner-drift-api.mddocs/airgap/reachability-drift-airgap-workflows.mdsrc/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/Migrations/009_call_graph_tables.sqlsrc/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/Migrations/010_reachability_drift_tables.sql