6.8 KiB
Reachability Drift Detection - Architecture
Module: Scanner Version: 1.0 Status: Implemented (core drift engine + API; Node Babel integration pending) Last Updated: 2025-12-22
1. Overview
Reachability Drift Detection tracks function-level reachability changes between scans. It highlights when code changes create new paths to sensitive sinks or remove existing paths, producing deterministic evidence for triage and VEX workflows.
Key outcomes:
- Detect regressions when previously unreachable sinks become reachable.
- Validate mitigations when reachable sinks become unreachable.
- Provide deterministic evidence for audit and policy decisions.
2. Key Concepts
2.1 Call Graph
A directed graph of function calls:
- Nodes: functions, methods, lambdas with file and line metadata.
- Edges: call relationships (direct, virtual, dynamic).
- Entrypoints: public handlers (HTTP, CLI, background services).
- Sinks: security-sensitive APIs from the sink registry.
2.2 Reachability Analysis
Multi-source traversal from entrypoints to sinks to determine exploitability.
2.3 Drift Detection
Compares reachability between base and head scans:
became_reachable: risk increased (new path to sink).became_unreachable: risk decreased (path removed or mitigated).
2.4 Cause Attribution
Explains why drift happened by correlating code changes with paths.
3. Data Flow
flowchart TD
A[Source or binary] --> B[Call graph extractor]
B --> C[CallGraphSnapshot]
C --> D[Reachability analyzer]
D --> E[ReachabilityResult]
C --> F[Code change extractor]
E --> G[ReachabilityDriftDetector]
F --> G
G --> H[ReachabilityDriftResult]
H --> I[Storage + API]
4. Component Architecture
4.1 Call Graph Extractors
Registered extractors are configured in CallGraphServiceCollectionExtensions.
| Language | Extractor | Status | Notes |
|---|---|---|---|
| .NET | DotNetCallGraphExtractor |
Registered | Roslyn semantic model. |
| Node.js | NodeCallGraphExtractor |
Registered (placeholder) | Trace-based fallback; Babel integration pending (Sprint 3600.0004). |
| Java | JavaCallGraphExtractor |
Library present, not wired | Register extractor to enable. |
| Go | GoCallGraphExtractor |
Library present, not wired | Register extractor to enable. |
| Python | PythonCallGraphExtractor |
Library present, not wired | Register extractor to enable. |
| PHP | PhpCallGraphExtractor |
Library present, not wired | Register extractor to enable. |
| Ruby | RubyCallGraphExtractor |
Library present, not wired | Register extractor to enable. |
| JavaScript | JavaScriptCallGraphExtractor |
Library present, not wired | Register extractor to enable. |
| Bun | BunCallGraphExtractor |
Library present, not wired | Register extractor to enable. |
| Deno | DenoCallGraphExtractor |
Library present, not wired | Register extractor to enable. |
| Binary | BinaryCallGraphExtractor |
Library present, not wired | Native call edge extraction. |
4.2 Reachability Analyzer
Located in src/Scanner/__Libraries/StellaOps.Scanner.CallGraph/Analysis/.
4.3 Drift Detector
ReachabilityDriftDetector compares base and head snapshots and produces ReachabilityDriftResult with compressed paths.
4.4 Path Compressor and Cause Explainer
PathCompressorreduces paths to key nodes and optionally includes full paths.DriftCauseExplainercorrelates changes to explain why drift happened.
5. Language Support Matrix
| Capability | .NET | Node.js | Others (Java/Go/Python/PHP/Ruby/JS/Bun/Deno/Binary) |
|---|---|---|---|
| Call graph extraction | Supported | Placeholder | Library present, not wired |
| Entrypoint detection | Supported | Partial | Library present, not wired |
| Sink detection | Supported | Partial | Library present, not wired |
6. Storage Schema
Migrations are in src/Scanner/__Libraries/StellaOps.Scanner.Storage/Postgres/Migrations/.
Core tables:
call_graph_snapshots:scan_id,language,graph_digest,extracted_at,node_count,edge_count,entrypoint_count,sink_count,snapshot_json.reachability_results:scan_id,language,graph_digest,result_digest,computed_at,reachable_node_count,reachable_sink_count,result_json.code_changes:scan_id,base_scan_id,language,node_id,file,symbol,change_kind,details,detected_at.reachability_drift_results:base_scan_id,head_scan_id,language,newly_reachable_count,newly_unreachable_count,detected_at,result_digest.drifted_sinks:drift_result_id,sink_node_id,sink_category,direction,cause_kind,cause_description,compressed_path,associated_vulns.material_risk_changes: extended withbase_scan_id,cause,cause_kind,path_nodes,associated_vulnsfor drift attachments.
7. Cache and Determinism
If the call graph cache is enabled (CallGraph:Cache), cached keys follow this pattern:
callgraph:graph:{scanId}:{language}callgraph:reachability:{scanId}:{language}
Determinism is enforced by stable ordering and deterministic IDs (see DeterministicIds).
8. API Endpoints
Base path: /api/v1
| Method | Path | Description |
|---|---|---|
| GET | /scans/{scanId}/drift |
Get or compute drift results for a scan. |
| GET | /drift/{driftId}/sinks |
List drifted sinks (paged). |
| POST | /scans/{scanId}/compute-reachability |
Trigger reachability computation. |
| GET | /scans/{scanId}/reachability/components |
List components with reachability. |
| GET | /scans/{scanId}/reachability/findings |
List findings with reachability. |
| GET | /scans/{scanId}/reachability/explain |
Explain reachability for a CVE and PURL. |
See docs/api/scanner-drift-api.md for details.
9. Integration Points
- Policy gates: planned in
SPRINT_3600_0005_0001_policy_ci_gate_integration.md. - VEX candidate emission: planned alongside policy gates.
- Attestation:
StellaOps.Scanner.ReachabilityDrift.Attestationprovides DSSE signing utilities (integration is optional).
10. Performance Characteristics (Targets)
| Metric | Target | Notes |
|---|---|---|
| Call graph extraction (100K LOC) | < 60s | Per language extractor. |
| Reachability analysis | < 5s | BFS traversal on trimmed graphs. |
| Drift detection | < 10s | Graph comparison and compression. |
| Cache hit improvement | 10x | Valkey cache vs recompute. |
11. References
docs/implplan/archived/SPRINT_3600_0002_0001_call_graph_infrastructure.mddocs/implplan/archived/SPRINT_3600_0003_0001_drift_detection_engine.mddocs/api/scanner-drift-api.mddocs/operations/reachability-drift-guide.mddocs/product-advisories/archived/17-Dec-2025 - Reachability Drift Detection.mdsrc/Scanner/__Libraries/StellaOps.Scanner.ReachabilityDrift/