Skip to main content

Compliance: the Cyber Resilience Act (CRA)

Pro. For “what must I report under the CRA, and what is in my AI-BOM?”
NIS2 is covered in compliance-nis2.md. The Cyber Resilience Act, Regulation (EU) 2024/2847, puts security duties on manufacturers of products with digital elements, which includes software you sell or make available in the EU. Most of it applies from 11 December 2027. The reporting duty in Article 14 has applied since 11 September 2026 (Art. 71(2)), and it also covers products placed on the market before December 2027 (Art. 69(3)). Penthera helps with two pieces of CRA evidence, offline: Penthera does not make you CRA compliant and does not certify anything. The drafts are not the ENISA platform’s official form, and none of this is legal advice.

Article 14 reporting helper

What the regulation asks

Checked on 2026-10-19 against the Official Journal text and the ENISA Single Reporting Platform (SRP) FAQ.
  • Where to send it. Through the ENISA Single Reporting Platform, using the end-point of the CSIRT designated as coordinator in the Member State of your main establishment. ENISA receives it at the same time (Art. 14(1), 14(3), 14(7)). For the Netherlands that CSIRT is NCSC-NL, per ENISA’s list of CSIRTs designated as coordinators.
  • Inform your users. After becoming aware, inform impacted users (and where appropriate all users), with mitigations they can deploy, where appropriate in a machine-readable format (Art. 14(8)).
  • One notification per vulnerability or incident, even across subsidiaries (ENISA SRP FAQ). The CSIRT may ask for an intermediate report (Art. 14(6)).
  • An actively exploited vulnerability is one with reliable evidence that a malicious actor exploited it without the system owner’s permission (Art. 3(42)). An incident is severe if it can harm the availability, authenticity, integrity or confidentiality of sensitive or important data or functions, or can lead to malicious code in the product or a user’s systems (Art. 14(5)).

Use it

cra-reports.md holds the timeline (UTC and your local time), a status per report (due in 21h 30m, submitted, submitted late, OVERDUE, waiting for a fix), a draft of each report with NEEDS INPUT for every fact still missing, and a draft user advisory for Art. 14(8). Record what you’ve sent in submitted.early_warning / submitted.notification / submitted.final_report and re-run. For a severe incident, the final report then counts from the actual submission time instead of the 72-hour deadline. Prefill from your scan and SBOM. Name the affected dependency in component.name and point prefill at Penthera output (paths relative to cra.json):
From the SBOM it fills the product name and version and the component’s version and purl. From the scan it fills matching CVE ids, the scanner severity and the finding titles. Prefilled values are marked verify in the draft, and anything you wrote yourself is never overwritten. A full example is in tests/fixtures/cra/ in the repository.

How the deadlines are counted

  • Hours are elapsed hours from aware_at. If the clocks change in between, the local due time shifts (24 hours from 09:00 CEST on 24 October 2026 is 08:00 CET on 25 October).
  • Days and months are calendar periods in your timezone (default Europe/Amsterdam), ending at the same clock time. One month from 31 January ends on 28 (or 29) February, following Regulation 1182/71 Art. 3(2)(c).
  • A timestamp without an offset is read in timezone. Use ISO 8601.
  • This is the strict reading. Regulation 1182/71 can give a little more time (a period runs to the end of the hour or day, and a days or months period that ends on a weekend or public holiday moves to the next working day). Don’t plan on that; report early.
The helper warns if aware_at is before 11 September 2026, if main_establishment is not the Netherlands (so NCSC-NL is not your CSIRT), and if the type or time zone is unknown.

AI-BOM (CycloneDX 1.6)

Customers and auditors ask what AI a product contains: which providers get your data, which models, which agent tooling. --aibom inventories it from the repo, offline:
Every item hangs off the root component in dependencies. The BOM covers only AI components. Use --sbom for all dependencies. Spec references: the CycloneDX 1.6 JSON reference, the ML-BOM capability page, and the official schema. That schema (with its SPDX and JSF dependencies) is vendored in tests/fixtures/cyclonedx/, and the tests validate every generated AI-BOM against it without network. Penthera writes 1.6 (ML-BOM first appeared in 1.5). CycloneDX 1.7 is also published, and support for it is not built yet. Limits. A model string in code means the model is referenced, not that it runs in production. The evidence lines let a reviewer check. Model ids built at runtime (`claude-${tier}`) are not detected. The modelCard is a stub: fill in task, datasets and considerations from the provider’s model card.