Supported Formats¶
ca9 supports two kinds of input:
- Existing SCA reports from tools such as Snyk, Dependabot, Trivy, and pip-audit.
- Repository or environment dependency inventory scanned directly against OSV.dev with
ca9 scan. - Package inventory from manifests and
fyn.lockwithca9 inventoryandca9 vet.
It can also emit multiple output formats for humans, CI systems, code scanning, VEX workflows, and SBOM enrichment.
Input: SCA reports¶
Snyk¶
Generate a Snyk report:
Supported layouts:
- Single-project JSON with a
vulnerabilitiesarray. - Multi-project JSON with an array of project objects, each containing
vulnerabilities.
Dependabot¶
Export Dependabot alerts with the GitHub CLI:
ca9 extracts advisory IDs, aliases, CWE IDs, package names, vulnerable ranges, severities, titles, source URLs, timestamps, and dependency relationship data where present.
Trivy¶
Generate a Trivy JSON report:
ca9 reads package vulnerability findings from Trivy result entries and preserves dependency metadata when the report contains it.
pip-audit¶
Generate a pip-audit JSON report:
ca9 maps pip-audit vulnerability entries into its common Vulnerability model for reachability analysis.
pip-audit aliases are preserved so PYSEC findings can still match CVE-oriented reachability rules.
Input: Direct OSV scanning¶
ca9 scan queries OSV.dev without requiring a separate SCA tool:
The scanner prefers exact dependency versions from the repository. Dependencies without
resolved versions are skipped by default; pass --allow-env-fallback only when you
intentionally want ca9 to use versions from the current Python environment.
OSV vulnerability details populate advisory aliases, CWE/CPE IDs, source URLs, published/modified timestamps, and cache freshness metadata in JSON, SARIF, and OpenVEX outputs.
Useful scan options:
ca9 scan --repo . --offline
ca9 scan --repo . --refresh-cache
ca9 scan --repo . --max-osv-workers 16
Input: Package inventory and fyn.lock¶
ca9 inventory and ca9 vet use the normalized inventory model. When fyn.lock is
present, ca9 reads it natively and extracts resolved packages, dependency edges, artifact
URLs, artifact hashes, source registries, groups, and markers.
Without fyn.lock, ca9 falls back to native manifest readers.
Output formats¶
Table¶
Default human-readable terminal output:
Add more evidence columns with:
JSON¶
Machine-readable report with summary, verdicts, evidence, warnings, confidence scores, optional enrichment data, and ignored_results for accepted-risk or baseline findings that did not affect the gate:
ca9 inventory -f json emits ca9.inventory.v1. ca9 vet -f json emits
ca9.vet.v1, including inventory summary, supply-chain findings, policy decisions,
warnings, and artifact scan counts.
Each result also includes an advisory object with normalized identity metadata:
{
"ecosystem": "pypi",
"aliases": ["CVE-2024-12345"],
"cwes": ["CWE-79"],
"cpes": [],
"source": "osv.dev",
"url": "https://osv.dev/vulnerability/GHSA-...",
"published_at": "2024-01-01T00:00:00Z",
"modified_at": "2024-01-02T00:00:00Z",
"fetched_at": "2024-01-03T00:00:00Z",
"cache_stale": false
}
SARIF¶
Use SARIF for GitHub code scanning or SARIF-compatible security tools. Accepted-risk and baseline findings are emitted as suppressed SARIF results so audit tools can still see them:
OpenVEX¶
Generate OpenVEX exploitability statements. Policy-ignored findings remain in the VEX document with ca9.policy_ignored metadata:
Compare VEX documents over time:
Markdown and HTML¶
Generate human-readable reports for pull request comments, build artifacts, or internal review:
ca9 check snyk-report.json --repo . -f markdown -o ca9-report.md
ca9 check snyk-report.json --repo . -f html -o ca9-report.html
Remediation plan¶
Generate prioritized remediation actions:
Action plan¶
Generate a CI/CD decision object:
ca9 check snyk-report.json --repo . -f action-plan -o action-plan.json
ca9 action-plan snyk-report.json --repo . -o action-plan.json
SBOM enrichment¶
Enrich CycloneDX or SPDX JSON with ca9 reachability verdicts:
AI-BOM capability output¶
Scan for AI assets and capabilities:
Diff and gate capability changes:
ca9 cap-diff --base base-aibom.json --head head-aibom.json --md cap-diff.md
ca9 cap-gate --diff cap-diff.json --policy ca9-policy.yaml
Adding a new parser¶
ca9 uses a protocol-based parser architecture. To add support for another SCA tool:
- Create a new file in
src/ca9/parsers/. - Implement the
SCAParserprotocol. - Register the parser class in
src/ca9/parsers/__init__.py.
from typing import Any
from ca9.models import Vulnerability
class MyToolParser:
def can_parse(self, data: Any) -> bool:
return isinstance(data, dict) and "my_tool_version" in data
def parse(self, data: Any) -> list[Vulnerability]:
return [
Vulnerability(
id=item["id"],
package_name=item["package"],
package_version=item["version"],
severity=item.get("severity", "unknown"),
title=item.get("title", ""),
description=item.get("description", ""),
)
for item in data["findings"]
]