Capa across the supply-chain governance stack
Five frameworks set the rules for how software-bearing organisations report, audit, and remediate their codebases: the EU Cyber Resilience Act, NIS2, DORA, NIST SSDF, and OWASP SCVS. This page maps which Capa artefacts answer which clauses. It is descriptive, not legal; any conformity decision belongs to an auditor or a supervisory authority, not a compiler manual.
Who they bind
- Cyber Resilience Act. Regulation (EU) 2024/2847: the EU's manufacturer-side rule for products with digital elements.
- NIS2. Directive (EU) 2022/2555: the operator-side counterpart, scoped to essential and important entities across eighteen sectors.
- DORA. Regulation (EU) 2022/2554: the financial-sector operational resilience regulation (cybersecurity articles only).
- NIST SSDF. SP 800-218: the US federal baseline for secure software development cited by EO 14028.
- OWASP SCVS. The vendor-neutral Software Component Verification Standard, with three levels.
One source, no external scanner
Capabilities are declared in type-checked signatures; the compiler reads them and each emitter serialises its own artefact, one flag per artefact.
| Artefact | Flag | What it carries |
|---|---|---|
| Capability manifest | --manifest | Per-function declared capabilities, attributes, signatures, declassification sites. |
| CycloneDX 1.5 SBOM | --cyclonedx | The per-function capability sets carried as capa:-namespaced properties[] entries, with an optional vulnerabilities[] array. A subset of the manifest: declassification sites stay in the manifest. |
| SPDX 2.3 SBOM | --spdx | Same metadata in SPDX annotations[] shape, Linux Foundation alignment. |
| CycloneDX VEX | --vex | Per-function exploitability claims from @vex(...) attributes. |
| SLSA L1 provenance | --provenance | in-toto Statement v1 + SLSA Provenance v1.0 predicate, source SHA-256. |
| Composed product SBOM | --compose-sbom | Per-function facts rolled up the dependency tree into a per-product capability surface; an unanalyzable subtree (native, unvendored, Unsafe-crossing) composes as a distinguished authority-unknown top and fails closed. |
| Capability ceiling gate | --check-capabilities | CI gate: every package verified against its declared capa.toml [capabilities] ceiling; exits non-zero on any violation or on an authority-unknown subtree. Scope: the verdict covers the modules reachable from the entry file given, so run it over every entry point a product ships. |
| Signable authority diff | --capability-diff | Canonical, signable release-over-release changelog of capability widening / narrowing; --fail-on-widening gates on any authority increase. |
| Compliance policies | --check-policies | Organization capa-policy.toml over the composed graph (exclusion, product-subset, purity, forbid-capability, forbid-dependency, no-unresolved-dependencies, plus the declassification-aware no-declassification and no-secret-egress), fail-closed on authority-unknown; --conformance-report emits signable evidence. |
| Canonical manifest | --manifest-digest | Byte-stable, content-addressable manifest wrapped in a content-integrity envelope: a sha256 over the canonical bytes with an empty detached-signature slot for an external signer. |
| Audit pipeline | sbom_capability_audit | SBOM vs policy diff, with structural rules. |
| SBOM diff tool | sbom_diff | Two SBOMs in; per-function widening / narrowing / added / removed out. |
| Machine-checked soundness | proofs/ | λcap calculus with four Agda-checked theorems plus a noninterference proof for the λif information-flow calculus. |
Each artefact across the five frameworks
| Capa output | CRA Annex I | NIS2 Art. 21 | DORA | NIST SSDF | OWASP SCVS |
|---|---|---|---|---|---|
| Manifest | I-II(1)partial | 21(2)(d)evidence | Art. 30(2)(a)evidence | PS.1indirect | Domain 1partial |
| CycloneDX SBOM | I-II(1)partial | 21(2)(d)evidence | Art. 28(3)evidence | PS.3.2partial | Domain 2partial |
| SPDX SBOM | I-II(1)partial | 21(2)(d)evidence | Art. 28(3)evidence | PS.3.2partial | Domain 2partial |
| CycloneDX VEX | I-II(2)partial | 21(2)(e)evidence | n/a | RV.2partial | Domain 5partial |
| SLSA L1 provenance | I-I(2)(f)indirect | 21(3)evidence | Art. 28evidence | PS.2/PS.3partial | Domain 6partial |
| Composed product SBOM | I-II(1)partial | 21(2)(d)evidence | Arts. 28-30evidence | PS.3.2partial | Domain 2partial |
| Signable authority diff | I-II(2)partial | 21(2)(d)evidence | Arts. 28-30evidence | RV.1partial | Domain 2partial |
| Compliance policies | I-II(1)indirect | 21(2)(d)evidence | Arts. 28-30evidence | PW.4.4indirect | Domain 1partial |
| Audit pipeline | I-II(1)indirect | 21(2)(d)evidence | Arts. 28-30evidence | PW.4.4indirect | Domain 1partial |
| SBOM diff tool | I-II(2)indirect | 21(2)(d)evidence | Art. 29evidence | RV.1partial | Domain 2partial |
| Machine-checked soundness | I-I(2)(b)indirect | n/a | n/a | PW.4indirect | n/a |
Rebuild and diff byte-for-byte
The four supply-chain artefacts can be rebuilt and diffed: the tests pin byte-identical output for repeated runs of the same program. Between repeated runs, the field that would otherwise vary is the build timestamp; pin it with SOURCE_DATE_EPOCH.
$ SOURCE_DATE_EPOCH=1609459200 capa --cyclonedx app.capa > a.json
$ SOURCE_DATE_EPOCH=1609459200 capa --cyclonedx app.capa > b.json
$ diff a.json b.json # empty: byte-for-byte identicalA rebuild-and-diff is a check an auditor can run, not a guarantee. It is evidence toward the CRA build-integrity and NIS2 supplier-assessment clauses.
The governance artefacts go one step further and carry their own content address. --manifest-digest (and, on the same substrate, --compose-sbom, --capability-diff and --conformance-report) serialise the manifest in a byte-stable, key-sorted canonical form with no timestamps at all, then wrap it in a content-integrity envelope: a sha256 over the canonical bytes plus an empty detached-signature slot. The digest is the value an external signer signs. The compiler holds no keys and never signs in-band (SLSA L1), so "signable by construction" is a property of the artefact, not a claim about a signing step the compiler took.
The Cyber Resilience Act
In force since 10 December 2024, most obligations apply from 11 December 2027. The clauses that matter most for a compiler are Annex I Part I (essential requirements), Part II (1) (a machine-readable SBOM), and Part II (2)-(7) (vulnerability handling). The strongest fits:
- Part II (1), SBOM. The CycloneDX and SPDX documents list the program's functions with their capability sets, a per-function granularity the clause does not ask for. In 1.32.0 they do not list the program's dependencies as components, so on their own they do not cover the clause's "at the very least the top-level dependencies" floor.
- Part I (2)(b), secure by default. A function is handed no built-in capability by default, and a call on one that is not in scope is refused.
- Part I (2)(g), data minimisation. Least authority is the language model; the IFC layer adds compiler-generated records of each deliberate disclosure (the manifest's declassifications).
- Part I (2)(j), attack-surface minimisation. The function's signature is the declared attack surface.
What Capa does not address: disclosure processes, the 24-hour incident window, update distribution, and the conformity-assessment paperwork. The article-by-article deep dive is at docs/cra.md.
NIS2 and DORA
NIS2 (transposition deadline 17 October 2024) is the operator-side counterpart. Article 21(2)(d) is the heart of its supply-chain ask: an essential or important entity has to assess the security of its direct suppliers. A Capa-using supplier's SBOM gives that operator a per-function authority surface; the composed product SBOM (--compose-sbom) rolls it up the declared dependency tree and fails closed on an unanalyzable subtree; --capability-diff detects supplier widening across releases; and organization compliance policies (--check-policies) verify the composed graph against a declared capa-policy.toml. These are inputs to the entity's own supplier assessment, not the assessment itself. Incident reporting (Art. 23) and board-level accountability (Art. 20) sit outside what a compiler can affect.
DORA (applies since 17 January 2025) binds financial entities plus critical ICT third-party providers. The SBOMs are supporting evidence toward the Register of Information under Article 28(3); Articles 28-30 (ICT third-party risk) are supported by the composed product SBOM and its ceiling gate (--check-capabilities), the signable authority diff, and the organization compliance policies, with provenance supporting due-diligence. These are technical inputs a financial entity reconciles against its own register, not the register itself. The business-continuity bulk of DORA and resilience testing (Arts. 24-27) are out of a language's reach.
SBOM · VEX · provenance
Supply-chain governance literature converges on three artefacts. Capa emits all three from one source, at per-function granularity for the first two.
SBOM
What is in the box. --cyclonedx / --spdx, per function.
VEX
How the box is affected by known vulnerabilities. --vex, per function.
Provenance
Where the box came from. --provenance, bound to the source SHA-256.
The alternative today is to combine a package-level SBOM generator, a hand-written VEX, and a separate signing step. Capa packages the three together at finer granularity, with the capability content computed by the compiler from type-checked signatures rather than by a separate scanner; the VEX records the developer's @vex claims and the provenance records source digests.
See it on real programs
capa_claimdesk
An expense-reimbursement engine that puts the regulated parts under compiler checks: IBAN under IFC, reaching an HMAC-chained ledger through an audited declassify, payment authorization as a linear token, the claim lifecycle as a typestate.
capa_paymentguard
A payment-security core (PCI DSS / PSD2) that ships a generated conformity pack: manifest, CycloneDX + SPDX, VEX, provenance, and a CONFORMITY.md walking an auditor through them.
capa_cra_template
A starting template for a CRA-oriented project: a small program plus the policy file and generation steps that produce the same conformity-pack layout for your own code.
capa_governance_pack
An evidence-pack generator written in Capa: turns machine-readable artefacts into a regulator-readable Markdown audit pack plus a JSON attestation a GRC platform can ingest.
capa_supplygate
A supply-chain conformity gate: SBOM plus OSV plus policy resolve to a pass/fail decision, and the tool emits its own capability SBOM alongside the verdict.
capa_licenseaudit
A monorepo license and vulnerability auditor: it reads the audited tree through a read-only capability that declares no write method, and writes its reports to a separate directory.
capa_ci_pipeline
A CI/release orchestrator, built as a multi-package product, that dogfoods all four supply-chain controls end to end: the composed product SBOM, organization compliance policies (--check-policies), signable authority diffs (--fail-on-widening), and four untrusted third-party actions run as sandbox-confined typed foreign Wasm components. The natural home for --check-capabilities and --fail-on-widening as a CI gate.
Caveats
- Compliance is an organisational outcome combining technical artefacts with processes. Capa contributes evidence, not compliance.
- The mapping above is one reading of each instrument. An organisation's auditors may classify the same artefact differently; treat it as a starting point for an internal gap analysis, not a legal opinion.
- These frameworks evolve: CRA implementing acts are still being drafted in 2026, NIS2 transposition varies by Member State, and NIST SSDF will see further revisions. The mapping reflects mid-2026.
- Capa is a one-person project. The outputs are stable enough to integrate into compliance pipelines, but the project has not been through independent assurance.
The full mapping document, with primary-source links, is docs/regulatory.md.