Architecture Overview¶
ca9 is designed as a layered pipeline: ingest -> analyze -> decide -> report.
High-level flow¶
graph LR
A[SCA report or OSV scan] --> B[Parser / scanner]
B --> C[Vulnerability list]
C --> D[Verdict engine]
D --> E[Reports]
N[fyn.lock / manifests] --> O[Inventory readers]
O --> P[Package inventory]
P --> Q[Supply-chain analyzers]
Q --> E
F[Repo source] --> G[AST scanner]
G --> D
H[coverage.json] --> I[Coverage reader]
I --> D
J[Vulnerability metadata] --> K[Vuln matcher + intel rules]
K --> D
L[Runtime context / OTLP traces] --> D
M[AI capability scan] --> D
Module map¶
src/ca9/
├── advisory.py # Advisory aliases, CWE/CPE extraction, purl helpers, cache freshness
├── models.py # Dataclasses: Vulnerability, Evidence, Verdict, Report
├── engine.py # Verdict engine and evidence orchestration
├── scanner.py # OSV.dev API client and dependency inventory resolution
├── report.py # Table, JSON, and SARIF output
├── vex.py # OpenVEX output
├── vex_diff.py # Continuous VEX diffing
├── remediation.py # Prioritized remediation plans
├── action_plan.py # CI/CD action-plan decisions
├── sbom.py # CycloneDX/SPDX enrichment
├── inventory.py # Normalized package inventory builder and renderers
├── supply_chain.py # Supply-chain report assembly
├── threat_intel.py # EPSS and CISA KEV enrichment
├── runtime_context.py # Deployment-aware priority adjustment
├── coverage_provider.py # Coverage discovery and generation helpers
├── cli.py # Click CLI entry point
├── analysis/
│ ├── ast_scanner.py # Static import tracing and dependency discovery
│ ├── api_usage.py # Vulnerable API usage matching
│ ├── call_graph.py # Call graph support
│ ├── coverage_reader.py # coverage.py JSON reader
│ ├── entry_points.py # Entry point detection
│ ├── exploit_path.py # Exploit path tracing
│ ├── otel_reader.py # OTLP JSON trace reader
│ └── vuln_matcher.py # Affected component extraction
├── capabilities/
│ ├── scanner.py # AI-BOM and capability scanner
│ ├── diff.py # Capability diffing
│ ├── policy.py # Capability policy gates
│ └── detectors/ # MCP, providers, prompts, egress, storage, tools
├── core/
│ ├── models.py # Package, Artifact, Finding, Evidence, Decision, Inventory
│ └── pipeline.py # Reader/analyzer/policy/reporter protocols
├── readers/
│ └── fyn_lock.py # Native fyn.lock reader
├── artifacts/
│ ├── fetch.py # Hash-aware artifact cache/download
│ └── unpack.py # Safe wheel/sdist extraction
├── analyzers/
│ ├── supply_chain.py # Registry/source/install-risk/dependency-confusion checks
│ ├── package_code.py # Static malicious package artifact heuristics
│ └── license_policy.py # Wheel/sdist metadata license policy
└── parsers/
├── base.py # SCAParser protocol
├── snyk.py # Snyk JSON parser
├── dependabot.py # Dependabot alerts parser
├── trivy.py # Trivy JSON parser
└── pip_audit.py # pip-audit JSON parser
The optional MCP server lives in ca9_mcp/.
Design principles¶
Small core dependency footprint¶
The core package depends on packaging for PEP 440 version parsing. CLI support is optional through ca9[cli], and MCP support is optional through ca9[mcp].
Conservative verdicts¶
ca9 only suppresses a vulnerability when the evidence supports that direction. In strict proof mode, weak dynamic suppressions or ambient dependency graph evidence are downgraded to INCONCLUSIVE.
Evidence-first reports¶
Verdicts carry structured evidence: import state, dependency relationship, affected component source, coverage execution, vulnerable API usage, confidence score, warnings, and optional runtime/threat/capability context.
Protocol-based parsers¶
Parsers implement the SCAParser protocol. New SCA formats can be added without changing the verdict engine.
Data flow¶
- Input - An SCA report, OSV scan inventory, or SBOM.
- Normalization - Parsers convert tool-specific findings into
Vulnerabilityobjects and preserve advisory identity metadata such as ecosystem, aliases, CWE/CPE IDs, source URLs, published/modified timestamps, and cache freshness when available. - Analysis preparation:
- AST scanner collects imports from the repository.
- Dependency inventory maps declared and transitive packages.
- Coverage reader loads executed file data if available.
- Vulnerability matcher extracts affected components.
- Intel rules identify known vulnerable API targets.
- Verdict engine - Combines evidence and proof policy for each vulnerability.
- Enrichment - Optional threat intel, runtime context, production traces, exploit paths, and capability blast radius.
- Output - Table, JSON, SARIF, OpenVEX, remediation plan, action plan, or enriched SBOM.
Supply-chain vetting flow¶
ca9 vet follows the newer package-security pipeline:
- Inventory - read
fyn.lockwhen present, otherwise native manifests. - Local metadata analysis - check source registries, missing artifact hashes, source-only install risk, mutable sources, and internal package source policy.
- Optional artifact acquisition - with
--scan-artifacts, download only hash-backed artifacts by default, verify digests, and safely unpack wheels/sdists. - Artifact analyzers - statically inspect package files for startup hooks, install-time execution, encoded payloads, credential exfiltration patterns, import-time risky behavior, and license metadata.
- Optional advisory query - with
--malware-query, query OSV for known malicious package advisories. - Decision/report - emit findings and block/warn/investigate decisions in table or JSON output.
Security constraints:
- no package install
- no package import
- no package code execution
- archive path traversal and unsafe links are rejected
- unhashed artifact downloads are refused by default
- network providers are opt-in