sbom-tools 0.2.0

Semantic SBOM diff and analysis tool
Documentation
# CRA Compliance — Standards Reverse Map

This document maps every compliance check sbom-tools surfaces under
`--standard cra` (and the related Article 24 / BSI / Annex III/IV
profiles) to the underlying regulation, harmonised standard, and
ENISA / industry guidance. Use it to:

- **Auditors / notified bodies**: locate the regulatory text behind each
  finding by Article number or Annex reference.
- **Engineers**: see which sidecar field (`CraSidecarMetadata`), SBOM
  field, or CycloneDX 1.6 [attestation]#attestation-evidence-cyclonedx-16-declarations
  clears each violation.
- **GRC / dashboards**: cross-reference SARIF `properties.standardIds`
  and `properties.standardHelpUris` to produce control-mapping reports.

> Generated and maintained alongside the sbom-tools source tree.
> If a check or article moves, send a PR — the reverse map is the
> single source of truth for both human readers and the
> `rule_meta()` registry (surfaced via `Violation::registry_standard_refs()`).

## CRA timeline anchors

| Date          | Event                                                         |
|---------------|---------------------------------------------------------------|
| 2024-12-10    | CRA enters into force (Regulation (EU) 2024/2847)                                  |
| 2026-09-11    | Article 14 reporting obligations apply (`ComplianceLevel::CraPhase1`) — Art. 71(2) |
| 2027-12-11    | Regulation applies in full (`ComplianceLevel::CraPhase2`) — Art. 71(2)             |

## Compliance levels

| `ComplianceLevel`           | sbom-tools `--standard` alias                                                                       | Scope                                                                                                            |
|-----------------------------|-----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| `CraPhase1`                 | `cra-phase1`, `cra-2026`                                                                            | CRA Phase 1 — Art. 14 reporting obligations (apply from 2026-09-11)                                                          |
| `CraPhase2`                 | `cra` (default CRA meaning), `cra-phase2`                                                           | Full CRA compliance (regulation fully applies from 2027-12-11)                                                                        |
| `CraOssSteward`             | `oss-steward`, `cra-oss-steward`, `cra-oss`, `cra-art24`, `art24`                                   | Article 24 lighter profile for open-source software stewards                                                     |
| `BsiTr03183_2`              | `bsi`, `tr-03183`, `tr03183`, `bsi-tr-03183-2`                                                      | BSI TR-03183-2 (German national CRA-aligned baseline)                                                            |
| `Cnsa2`                     | `cnsa2`, `cnsa-2`, `cnsa_2`, `cnsa2.0`                                                              | NSA CNSA 2.0 (post-quantum mandate for US national-security systems)                                             |
| `NistPqc`                   | `pqc`, `nist-pqc`, `nist_pqc`                                                                       | NIST IR 8547 + FIPS 203/204/205 (PQC migration)                                                                  |

The `--cra-product-class` flag (or sidecar `productClass`) drives the
[CRA-P3.2 calibration table](#cra-p32-product-class-severity-calibration)
that scales severity for vendor-hash, EOL, cycles, DoC, EUCC, PSIRT,
and module-attestation checks.

## Reverse map

Each row maps a sbom-tools `Violation::requirement` string to its
regulatory anchor, the harmonised-standard requirement ID
(prEN 40000-1-3 where known), the BSI section, and the canonical URL
that ends up in SARIF `properties.standardHelpUris`.

### CRA Article 13 (essential requirements & SBOM-related obligations)

> Rule citations were re-anchored in 2026-07: the SBOM-facing checks now
> cite the paragraphs and Annex points that actually carry each
> obligation in Reg. (EU) 2024/2847 (e.g., the machine-readable SBOM
> mandate lives in Annex I Part II (1), the vulnerability-reporting
> contact in Art. 13(17), and manufacturer identification in
> Art. 13(16)). The BSI column uses TR-03183-2 v2.1.0 numbering.

| Requirement string                                              | CRA anchor                        | prEN 40000-1-3      | BSI TR-03183-2 § | sidecar field that clears it                              |
|-----------------------------------------------------------------|-----------------------------------|---------------------|------------------|-----------------------------------------------------------|
| `CRA Art. 13(2): Documented risk assessment`                    | Art. 13(2)                        ||| `riskAssessmentUrl` + `riskAssessmentMethodology`         |
| `CRA Art. 13(7) / Annex I Part II (1): SBOM freshness`          | Art. 13(7); Annex I Part II (1)   | PRE-7-RQ-04         | §3.1             | regenerate SBOM on each release                           |
| `CRA Annex I Part II (1): Machine-readable SBOM format`         | Annex I Part II (1)               | PRE-7-RQ-04         | §4               | parse-time check (CycloneDX 1.4+ / SPDX 2.3+)             |
| `CRA Art. 13(5): Third-party due diligence (license tracking)`  | Art. 13(5)                        | PRE-7-RQ-05         | §5.2.2           | populate component `license` fields                       |
| `CRA Art. 13(17): Vulnerability disclosure contact`             | Art. 13(17); Annex I Part II (6); Annex II (2) | RLS-2-RQ-01 | §5.2.5 (opt.) | `securityContact` / `vulnerabilityDisclosureUrl`          |
| `CRA Annex I Part II (5): Coordinated vulnerability disclosure policy` | Annex I Part II (5); Art. 13(8) | RLS-2-RQ-02      || `coordinatedDisclosurePolicyUrl`                          |
| `CRA Art. 13(8): Support period / lifecycle management`         | Art. 13(8)                        | PRE-7-RQ-06         || `supportEndDate` + EOL enrichment                         |
| `CRA Art. 13(8) / 13(19): Support period disclosure`            | Art. 13(8); Art. 13(19); Annex II (7) | PRE-7-RQ-06     || `supportEndDate`                                          |
| `CRA Annex I Part II (1): Documented vulnerability information` | Annex I Part II (1)               | RLS-2-RQ-04         || OSV / KEV / VEX enrichment                                |
| `CRA Annex II (7): Component lifecycle monitoring/status`       | Art. 13(8); Annex II (7)          | PRE-7-RQ-06         || EOL enrichment + transitive supplier coverage             |
| `CRA Art. 13(15): Product identification`                       | Art. 13(15); Annex II (3)         | PRE-7-RQ-06         | §5.2.2           | SBOM `metadata.component.name` + sidecar `productName`    |
| `CRA Annex I Part II (1): Component version`                    | Annex I Part II (1)               | PRE-7-RQ-06         | §5.2.2           | component `version` fields                                |
| `CRA Annex I Part II (1): Component supplier information`       | Annex I Part II (1)               | PRE-7-RQ-03         | §5.2.2           | component `supplier` fields                               |
| `CRA Annex I Part II (4): Vulnerability metadata completeness`  | Annex I Part II (4)               ||| vulnerability severity/CVSS + remediation detail          |
| `CRA Art. 13(16): Manufacturer identification`                  | Art. 13(16); Annex II (1)         || §5.2.1           | `manufacturerName` + `manufacturerEmail`                  |

### CRA Article 14 (reporting obligations, applicable from 2026-09-11)

| Requirement string                                          | CRA Article    | prEN 40000-1-3      | sidecar field                         |
|-------------------------------------------------------------|----------------|---------------------|---------------------------------------|
| `CRA Art. 14: PSIRT contact for external vulnerability reports` | Art. 14    | RLS-2-RQ-03         | `psirtUrl`                            |
| `CRA Art. 14(2)(a): 24-hour early-warning channel`          | Art. 14(2)(a) / 14(4)(a) | RLS-2-RQ-03 | `earlyWarningContact`                 |
| `CRA Art. 14(2)(b): 72-hour notification channel`           | Art. 14(2)(b) / 14(4)(b) | RLS-2-RQ-03 | `incidentReportContact`               |
| `CRA Art. 14(7): ENISA single reporting platform`           | Art. 14(7)     | RLS-2-RQ-03-RE      | `enisaReportingPlatformId`            |

Pre-deadline findings are emitted as `Info`; post-deadline they become
`Warning` (or `Error` at `ImportantClass2`/`Critical` per the
[product-class calibration](#cra-p32-product-class-severity-calibration)).
The 2026-09-11 deadline is compared against the *evaluation instant* — the
wall clock by default, or `--as-of <RFC 3339>` for reproducible CI runs.

Art. 14(7) is the exception: the ENISA single reporting platform has no
published endpoint yet, so the missing-`enisaReportingPlatformId` finding
stays `Info` on both sides of the deadline.

### CRA Annexes

| Requirement string                                          | CRA Annex                | prEN 40000-1-3      | What clears it                                          |
|-------------------------------------------------------------|--------------------------|---------------------|---------------------------------------------------------|
| `CRA Annex I Part II / prEN 40000-1-3 [PRE-7-RQ-07-RE]: Vendor hash carry-through` | Annex I Part II | PRE-7-RQ-07-RE | strong (SHA-256+) hash on vendor-supplied components |
| `CRA Annex I / prEN 40000-1-3 [PRE-7-RQ-07]: Unique component identifier` | Annex I         | PRE-7-RQ-07         | PURL / CPE / SWID / SWHID on each component             |
| `CRA Annex I Part II: Supply chain transparency`            | Annex I Part II          | PRE-7-RQ-01,03      | supplier on direct + transitive deps                    |
| `CRA Annex I Part I (2)(f): Document signature/integrity`   | Annex I Part I (2)(f)    || serial number / digital signature / attestation hash    |
| `CRA Annex I Part I (2)(f): Component integrity information (hash)` | Annex I Part I (2)(f) || cryptographic hash (SHA-256+) per component             |
| `CRA Annex IV: EUCC reference (Common Criteria certificate)`| Annex IV                 || sidecar EUCC evidence fields, a `Certification`/`Attestation` external ref with `eucc`/`common-criteria` URL, or a [CDXA attestation]#attestation-evidence-cyclonedx-16-declarations naming EUCC / Common Criteria |
| `CRA Annex VII: Technical documentation`                    | Annex VII                || run `sbom-tools cra-docs <sbom> --output dossier/`     |
| `CRA Annex V: EU Declaration of Conformity reference`       | Annex V                  || `Attestation`/`Certification` external ref OR `ceMarkingReference` |
| `CRA Annex VIII: <Module> attestation reference`            | Annex VIII (Module B+C/H/EUCC) || Module-specific `Attestation`/`Certification` external ref |
| `CRA prEN 40000-1-3 [PRE-8-RQ-02]: Hardware component inventory` | Annex I Part II   | PRE-8-RQ-02         | producer + identifier + firmware version on hardware    |

### Article 24 — open-source software steward floor

| Requirement string                                          | CRA reference  | Cleared by                                            |
|-------------------------------------------------------------|----------------|-------------------------------------------------------|
| `CRA Art. 24: Vulnerability-handling process (steward floor)` | Art. 24      | `SecurityContact` / `Advisories` / `VulnerabilityAssertion` external ref OR `psirtUrl` / `vulnerabilityDisclosureUrl` |
| `CRA Annex I Part II (5): Coordinated vulnerability disclosure policy` (relaxed to Warning under steward) | Annex I Part II (5) | `Advisories` external ref OR `coordinatedDisclosurePolicyUrl` |

Article 24 *suppresses* manufacturer-only checks (Art. 13(16) email,
Annex V DoC, Annex VIII attestation, Article 14 channels, hardware
[PRE-8-RQ-02], vendor-hash carry-through).

## CRA-P3.2 product-class severity calibration

When `--cra-product-class` (or sidecar `productClass`) is set, the
severity of certain checks scales per Annex III/IV class. Selecting a
class also implies a default conformity-assessment route (Annex VIII),
overridable via sidecar `conformityAssessmentRoute`.

| Check                          | Default | Important-1 | Important-2 | Critical |
|--------------------------------|---------|-------------|-------------|----------|
| Vendor-hash coverage threshold | 50%     | 80%         | 80%         | 100%     |
| Vendor-hash severity           | Warning | Warning     | Error       | Error    |
| EOL components                 | Warning | Warning     | Error       | Error    |
| Cycles                         | Warning | Warning     | Error       | Error    |
| Annex V DoC reference          | Info    | Warning     | Error       | Error    |
| EUCC reference                 | n/a     | n/a         | Info        | Error    |
| PSIRT documented               | Warning | Warning     | Error       | Error    |
| Module attestation reference   | n/a     | Warning (B+C) | Error (B+C/H) | Error (EUCC) |

Default conformity routes per class:

| Class             | Default route       |
|-------------------|---------------------|
| Default           | Module A (self-assessment) |
| ImportantClass1   | Module A (self-assessment, B+C optional) |
| ImportantClass2   | Module B+C          |
| Critical          | EUCC                |

## Attestation evidence (CycloneDX 1.6 `declarations`)

Added 2026-07: the CRA checks also read machine-readable CDXA evidence.
On a CycloneDX document with `specVersion >= 1.6` carrying a root-level
`declarations` block plus `definitions.standards`, a standard whose
name/description/owner mentions the *Cyber Resilience Act* (or carries the
bare token `cra`) is classified into the CRA rule family, and an
attestation that fully supports one of its requirements can clear a CRA
check on its own. The EUCC-specific rows need the stricter subset: a
CRA-family standard that *also* names EUCC / Common Criteria.

Every sidecar field and external-reference path listed in the reverse map
above remains valid as the self-declared fallback, and a document with no
`declarations` behaves exactly as before — including byte-identical
violation messages.

### What attestation evidence reaches

| Surface                                                          | CDXA can satisfy it | Evidence needed                                     |
|------------------------------------------------------------------|---------------------|-----------------------------------------------------|
| `SBOM-CRA-ANNEX-IV` — EUCC / Common Criteria reference (only fires at Important-2 / Critical) | yes | CRA-family standard that also names EUCC / Common Criteria |
| `SBOM-EUCC-CERTREF` (under `--standard eucc`)                      | yes                 | same as above                                       |
| `conformity_summary` → "EU Declaration of Conformity" row          | yes                 | any CRA-family attestation                          |
| `conformity_summary` → Module B / Module C / Module H rows          | yes                 | any CRA-family attestation                          |
| `conformity_summary` → EUCC certificate + Target-of-Evaluation rows | yes                 | CRA-family standard that also names EUCC / Common Criteria |
| `SBOM-CRA-ANNEX-V` — Annex V DoC violation                         | no                  | `Attestation`/`Certification` external ref or sidecar `ceMarkingReference` |
| `SBOM-CRA-ANNEX-VIII` — module attestation violation               | no                  | `Attestation`/`Certification` external ref          |
| `SBOM-EUCC-PP` / `-TOE` / `-ITSEF` / `-VALIDITY`                   | no                  | dedicated sidecar EUCC fields                       |
| `SBOM-CRA-ART-14` channels + the `conformity_summary` PSIRT row     | no                  | sidecar fields                                      |

The `conformity_summary` block is the Annex VIII checklist emitted next to
`violations` by `validate --standard cra -o json`. It only appears once a
product class is pinned — via `--cra-product-class` or the sidecar
`productClass` — since the class picks the conformity route whose rows are
listed. A row strengthened by attestation names the level it was satisfied
at:

```text
Annex V — manufacturer's signed declaration. Provide via Attestation/Certification
external ref or sidecar ceMarkingReference. Satisfied by machine-readable CDXA
attestation (signature-present evidence); external-reference/sidecar presence
remains the self-declared fallback.
```

### When an attestation counts (fail-closed)

All of the following must hold at the evaluation instant (wall clock, or
`--as-of`):

- the attestation map entry declares a full `conformance.score` (`1.0`) —
  any score below 1.0 is partial and never auto-satisfies, and a missing
  score fails closed too;
- the entry carries no counter-claims and cites at least one claim;
- a cited claim resolves, targets a resolvable element, carries no
  counter-evidence, and cites at least one resolvable evidence item that is
  fresh (created at or before the instant, and not past its `expires`).

Unresolvable refLinks are kept as dangling and can never help satisfy a
requirement. When a matching attestation exists but trips one of these
gates, the violation still fires and the message names the reason:

```text
[CRA Annex IV / EUCC] Product class Critical requires (or strongly recommends)
a reference to a Common Criteria / EUCC certificate or Target of Evaluation
— CDXA attestation covering an EUCC / Common Criteria certification found but
rejected: declared conformance is partial (score 0.5); partial conformance
never auto-satisfies
```

### Structural verification only

**No signature is ever cryptographically verified.** JSF signature objects
on the declarations, attestations, claims, evidence, affirmation, and
signatories are parsed for *presence* — algorithm, `keyId`, signer count,
signatory identity — and nothing more. The evidence ladder is
`SelfDeclared < Structural < SignaturePresent < SignatureVerified`; a
satisfied row reports `SignaturePresent` when the declarations block, the
attestation, or a supporting claim/evidence item carries a signature
object, and `Structural` otherwise. `SignatureVerified` exists only for
output-schema stability and is unreachable today.

For a notified body this means an attestation-satisfied row asserts *"the
document says so, in the schema's shape, and nobody in the document
contradicts it"* — not that a signature, a certificate chain, or the
underlying claim was validated. Ingestion of external in-toto / DSSE
attestation bundles (SLSA provenance/VSA and friends) is a later phase with
no surface today; only in-document `declarations` are read.

## BSI TR-03183-2 — quick mapping

`ComplianceLevel::BsiTr03183_2` implements **v2.1.0 (2025-08-20)**: the §4
format gate, the §5.2.1/§5.2.2 required fields, the §5.2.4 additional tier,
§6.1 licence naming, and the §3.1 vulnerability-information prohibition.
SARIF rule prefix: `SBOM-BSI-TR-03183-2-*`. Canonical URL:
[bsi.bund.de/dok/TR-03183-en](https://bsi.bund.de/dok/TR-03183-en).

| BSI section    | Signal (severity)                                                        | Cleared by                                                    |
|----------------|---------------------------------------------------------------------------|---------------------------------------------------------------|
| §4 (+§7)       | CycloneDX ≥ 1.6 or SPDX ≥ 3.0.1 for newly generated/updated SBOMs (Error) | regenerate in an eligible format (v2.0.0 grace ended 2026-02-20) |
| §5.2.1         | Creator of the SBOM with email, or URL if no email (Error / Warning)      | `metadata.authors[].email` / SPDX `creator`                    |
| §5.2.1         | Timestamp of the SBOM data compilation (Error)                            | `metadata.timestamp` / SPDX `created`                          |
| §5.2.2         | Component name (Error) and version (Error)                                | `name` + `version` (filename / RFC 3339 date fallbacks)        |
| §5.2.2         | Distribution licence(s) per component (Error)                             | `licenses[]` with SPDX identifiers                             |
| §5.2.2         | Hash of the deployable component **as SHA-512** (Error when only other algorithms; Warning when absent, §3.2.1) | SHA-512 hash per component |
| §5.2.2         | Component creator (Warning, presence-level)                               | `supplier` / `author` per component                            |
| §5.2.2         | Dependencies (Error) + completeness clearly indicated (Warning)           | `dependencies` graph + `compositions[].aggregate`              |
| §5.2.4 (add.)  | Other unique identifiers — purl/CPE (Warning)                             | one of `purl` / `cpe` / `swid` / `swhid` per component         |
| §6.1           | Licences named by SPDX identifier/expression (Warning)                    | valid SPDX expressions (text is not a substitute)              |
| §3.1           | No vulnerability information inside the SBOM (Warning)                    | publish advisories separately (e.g. CSAF)                      |

Not modeled (no rule emitted): filename of the component, and the
executable / archive / structured properties (`bsi:component:*`
CycloneDX taxonomy). The TR mandates **no generation-tool field and no
signature** in any tier.

## CSAF v2.0 (ISO/IEC 20153:2025)

CSAF advisories ingest into `VexEnricher` alongside OpenVEX and
CycloneDX VEX. Format auto-detection: `document.csaf_version` starts
with `2.`. CSAF emit support: `sbom-tools vex export --format csaf`
(see the [CLI cheat sheet](#cli-cheat-sheet)).

| CSAF field                                | Internal mapping                              |
|-------------------------------------------|-----------------------------------------------|
| `vulnerabilities[].cve`                   | `Vulnerability.id`                            |
| `vulnerabilities[].ids[].text` (fallback) | `Vulnerability.id` (e.g., GHSA)               |
| `product_status.known_affected`           | `VexState::Affected`                          |
| `product_status.known_not_affected`       | `VexState::NotAffected`                       |
| `product_status.fixed`, `first_fixed`, `last_affected` | `VexState::Fixed`                |
| `product_status.under_investigation`      | `VexState::UnderInvestigation`                |
| `product_status.recommended`              | `VexState::Affected` (with note)              |
| `product_tree.full_product_names[].product_identification_helper.purl` | `(vuln_id, purl)` lookup key |

## CLI cheat sheet

```bash
# Multi-standard validate with CRA + BSI + NTIA in one pass
sbom-tools validate sbom.json --standard cra,bsi,ntia

# CRA Phase 2 with product-class calibration via sidecar
sbom-tools validate sbom.json --standard cra --cra-sidecar sbom.cra.yaml

# CRA validation with explicit product class
sbom-tools validate sbom.json --standard cra --cra-product-class important-class-2

# Article 24 steward profile
sbom-tools validate sbom.json --standard oss-steward

# Pin the evaluation clock (Art. 14 deadline, SBOM age, EUCC / attestation
# expiry) so CI runs are reproducible
sbom-tools validate sbom.json --standard cra --as-of 2027-01-01

# SARIF output for CI (with helpUri populated)
sbom-tools validate sbom.json --standard cra -o sarif -O compliance.sarif

# Generate CRA conformity dossier (Annex V DoC + Annex VII technical documentation)
sbom-tools cra-docs sbom.json --output dossier/ --cra-sidecar sbom.cra.yaml

# Curated standards-watch catalogue (prEN, BSI, CSAF, EUCC, …)
sbom-tools cra-standards-watch --format json

# Apply CSAF advisories to enrich SBOM with VEX data
sbom-tools vex apply sbom.json --vex advisory.csaf.json

# Emit the SBOM's VEX state as a CSAF v2.0 advisory
sbom-tools vex export sbom.json --format csaf -O advisory.csaf.json
```

## Sidecar example

```yaml
manufacturerName: "Example Corp"
manufacturerEmail: "legal@example.com"
productName: "Example Product"
productVersion: "1.0.0"
ceMarkingReference: "EU-DoC-2026-001"
supportEndDate: "2030-12-31T00:00:00Z"

productClass: "important-class-1"
conformityAssessmentRoute: "module-a"

riskAssessmentUrl: "https://example.com/risk-assessment.pdf"
riskAssessmentMethodology: "ISO/IEC 27005:2022"

securityContact: "security@example.com"
psirtUrl: "https://example.com/psirt"
coordinatedDisclosurePolicyUrl: "https://example.com/security/cvd-policy"
earlyWarningContact: "ew@example.com"
incidentReportContact: "incidents@example.com"
enisaReportingPlatformId: "EU-MFR-12345"

isOssSteward: false
```

Auto-discovered next to the SBOM at any of:
`<stem>.cra.{json,yaml,yml}`, `<stem>-cra.{json,yaml}`, with multi-extension
stems also tried (`app.cdx.json` → `app.cra.json` works).

## Standards bibliography

| Standard / regulation              | URL                                                                                                                                                |
|------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| CRA — Regulation (EU) 2024/2847    | https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng                                                                                                 |
| prEN 40000-1-3 (in development)    | (CEN-CENELEC JTC 13 — paywalled draft; URLs unstable)                                                                                              |
| BSI TR-03183-2 (v2.1.0)            | https://bsi.bund.de/dok/TR-03183-en                                                                                                                |
| ENISA SBOM Implementation Guidance | https://www.enisa.europa.eu/publications/sbom-implementation-guidance                                                                              |
| NIST SP 800-218 SSDF               | https://doi.org/10.6028/NIST.SP.800-218                                                                                                            |
| EO 14028                           | https://www.federalregister.gov/d/2021-10460                                                                                                       |
| FDA premarket cybersecurity (final, 2026-02-03) | https://www.fda.gov/media/119933/download                                                                                          |
| NTIA SBOM minimum elements         | https://www.ntia.gov/report/2021/minimum-elements-software-bill-materials-sbom                                                                     |
| CSAF v2.0 (ISO/IEC 20153:2025)     | https://docs.oasis-open.org/csaf/csaf/v2.0/csaf-v2.0.html                                                                                          |
| OpenVEX                            | https://github.com/openvex/spec                                                                                                                    |
| CISA KEV                           | https://www.cisa.gov/known-exploited-vulnerabilities-catalog                                                                                       |
| OSV.dev                            | https://osv.dev                                                                                                                                    |
| EUCC (Reg. (EU) 2024/482)          | https://eur-lex.europa.eu/eli/reg_impl/2024/482/oj/eng                                                                                             |
| CycloneDX Attestations (CDXA)      | https://cyclonedx.org/capabilities/attestations/                                                                                                   |

## Where this map lives in the code

- `rule_meta()` in `src/quality/compliance/registry.rs` (via `Violation::registry_standard_refs()`) —
  string → `(StandardKind, id)` mapping. Drives SARIF
  `properties.standardIds`.
- `StandardKind::canonical_help_uri()` in `src/quality/compliance/mod.rs`  `(StandardKind, id)` → URL. Drives SARIF `helpUri` and
  `properties.standardHelpUris`.
- `rule_help_uri()` in `src/reports/sarif.rs` — rule-ID prefix → URL
  for `runs[].tool.driver.rules[].helpUri`.
- `ComplianceChecker::class_severity()` in `src/quality/compliance/mod.rs`  P3.2 calibration table.
- `cli::run_cra_docs` in `src/cli/cra_docs.rs` — Annex V DoC + Annex VII tech-doc dossier
  generator.
- `AttestationRuleFamily::classify()` in `src/model/attestation.rs`  `definitions.standards` entry → CRA / SSDF / EO 14028 rule family;
  `AttestationDeclarations::supported_requirements()` — the fail-closed
  filter behind "when an attestation counts".
- `ComplianceContext::evidence_for()` in `src/quality/compliance/context.rs`  the query the CRA / EUCC checks call.
- `ComplianceChecker::build_conformity_summary()` and
  `check_class_eucc_reference()` in `src/quality/compliance/cra.rs`,
  `standard_references_eucc()` / `cdxa_note()` in
  `src/quality/compliance/ssdf.rs` — the CRA-side attestation integration
  points.