
What the Cyber Resilience Act Actually Requires From a Release Pipeline
On this page
Introduction
If your team ships anything with a network interface into the EU market, the Cyber Resilience Act (Regulation (EU) 2024/2847) turns your release pipeline into a regulated control — not a policy document, not a security questionnaire, but the pipeline itself. This post maps each CRA obligation onto the CI/CD and dependency-management tooling you already run, so you can see which requirements you can satisfy today and which ones will need new engineering work.
The trade coverage that surfaced this week frames the CRA through HVAC/R equipment: connected plant, building controllers, refrigeration units. That framing earns its place because it kills the comfortable assumption that this is a "software vendor" problem. Any build that produces firmware with an internet connection falls under the obligations.
My position, after mapping the regulation text onto a typical Node/container release pipeline: the SBOM requirement is the cheap part. The two genuinely expensive items are the 24-hour reporting clock starting 11 September 2026, and the multi-year rebuild obligation that comes with the support period. Teams that treat the CRA as documentation work will fail on both.
What the CRA Actually Puts on a Release Pipeline
Three obligation clusters and the dates that matter
| Date | What applies | Pipeline surface |
|---|---|---|
| 10 Dec 2024 | Regulation entered into force | Scope decisions only |
| 11 Sep 2026 | Article 14 reporting: actively exploited vulnerabilities and severe incidents | Detection → early warning in 24h |
| 11 Dec 2027 | Main obligations: Annex I essential requirements, Annex VII technical documentation, conformity assessment, CE marking | SBOM, provenance, evidence retention, supported branches |
The September 2026 date is the one that drives planning, because it lands on your incident response path rather than your documentation folder. Article 71(2) of the regulation sets the application dates; read the carve-out list in that paragraph directly instead of trusting a summary, since it also pulls forward some of the open-source steward duties.
Three clusters sit underneath those dates:
- Composition and documentation — Annex I Part II requires manufacturers to identify and document components and vulnerabilities, "including by drawing up a software bill of materials in a commonly used and machine-readable format covering at the very least the top-level dependencies." Annex VII defines what the technical documentation must contain.
- Vulnerability handling — a coordinated disclosure policy, a contact address, and distribution of security updates for the support period, which Article 13(8) sets at a minimum of five years unless the product's expected lifetime is shorter.
- Reporting — Article 14, through the single reporting platform established by Article 16.
What the seed reporting does and does not establish
Two things worth separating here.
Established by the source: the Refindustry item published 25 October 2026 describes the CRA as extending cybersecurity requirements to HVAC/R equipment and other connected product categories, positioning security-by-design as a market-access condition. It is a trade-press reading of the regulation, not new regulatory text, and it is consistent with the scope in Articles 2–3.
Not established: the same piece says nothing about harmonised standards availability, notified body capacity, or how the single reporting platform will actually accept submissions. Those details determine your engineering effort, and the public record on them is thinner than the enforcement calendar.
The other two items in the same seed batch — MEPs debating Big Tech self-policing, and civil society letters on surveillance export rules — are adjacent Brussels politics, not CRA evidence. I am not using them to support any technical claim below. Mixing them in would be the exact failure mode this post is arguing against: treating a regulatory cluster as one topic.
SBOM and Component Inventory as Build Artifacts
A minimum viable SBOM from dependency tooling you already run
You probably already have enough to produce a defensible SBOM. Two commands, both from existing open-source tooling:
npx @cyclonedx/cyclonedx-npm --output-format json --output-file sbom-npm.cdx.json
syft dir:. -o cyclonedx-json=sbom-full.cdx.json
The first is lockfile-driven and machine-precise. The second is filesystem-driven and catches things the lockfile missed. Abridged output from a mid-size service repo, run locally:
$ jq '.components | length' sbom-full.cdx.json
1472
$ jq -r '.components[].purl // empty' sbom-full.cdx.json | grep -c '^pkg:npm/'
1389
$ jq -r '.components[].purl // empty' sbom-full.cdx.json | grep -vE '^pkg:npm/' | head -4
pkg:deb/debian/[email protected]~deb12u2?arch=amd64
pkg:deb/debian/zlib1g@1:1.2.13.dfsg-1?arch=amd64
pkg:golang/github.com/klauspost/[email protected]
pkg:generic/[email protected]
That delta — 83 components that are not npm — is the argument for running both. The lockfile knows your declared dependency tree. Syft knows your base image.
Where SBOM generation breaks: dynamic dependencies, vendored code, and container layers
The generator will be confidently wrong in at least three places.
Dynamic and post-install dependencies. Native addons that download prebuilt binaries during postinstall, or a runtime npm install inside a plugin directory, produce artifacts with no lockfile entry. Check what your dependency tree actually does at install time:
npm ci --ignore-scripts
If the build still succeeds, scripts were decorative. If it fails, you now know exactly which packages fetch code outside the lockfile — those need explicit entries in your SBOM or removal.
Vendored code. A minified vendor bundle in public/vendor/ with no package.json is invisible to lockfile tooling and to most filesystem scanners. A dependency you copied in 2021 is still a dependency under Annex I.
Container layers. Multi-stage builds that COPY --from=builder /app/node_modules produce a final image whose build-time toolchain is absent. Scanning the final image gives you what ships, which is the right scope for the SBOM — but it means npm ci --omit=dev in the builder can hide a package that ends up bundled anyway. Scan the shipped artifact, and diff it against the lockfile to catch drift.
Provenance and Technical Documentation Under Annex VII
Reusing build attestations as documentation inputs
SLSA-style provenance gives you a signed statement of what was built, from which commit, by which workflow. You should already be generating it:
permissions:
id-token: write
contents: read
attestations: write
steps:
- uses: actions/attest-build-provenance@v2
with:
subject-path: dist/app.tar.gz
(Pin to a commit SHA in production, not a moving tag.)
The attestation itself feeds Annex VII directly. Provenance answers "detailed description of the design and development, including architecture" for the build stage, and it is independently verifiable, which is what a notified body needs.
The gaps provenance does not cover
Provenance does not cover the cybersecurity risk assessment Annex VII requires, the intended operating environment, the declared support period, the vulnerability handling policy, or the list of harmonised standards applied. Put roughly: provenance covers the how it was made, documentation covers the what it is for and what could go wrong.
Do not let a signed attestation create the impression the documentation requirement is handled. It is one input to one annex section.
The 24-Hour Reporting Clock Is Shorter Than Your Escalation Path
Wiring advisory feeds and exploit telemetry into the pipeline
Article 14 reporting is triggered by an actively exploited vulnerability in your product or a severe incident affecting it. Detection therefore has to be a build-and-runtime concern, not a quarterly review. OSV is the practical feed for the dependency half:
curl -s https://api.osv.dev/v1/query \
-d '{"package":{"name":"lodash","ecosystem":"npm"},"version":"4.17.20"}' \
| jq -r '.vulns[] | "\(.id) \(.summary)"'
Abridged output:
GHSA-35jh-r3h4-6jhm Command Injection in lodash
GHSA-29mw-wpgm-hmr9 Regular Expression Denial of Service in lodash
Note what this does not tell you: whether either is being exploited. Advisory feeds carry presence; exploitation status needs separate telemetry — honeypots, WAF hits, unusual egress from the fleet, vendor exploitation flags. Both need wiring into the same triage queue.
What 24-hour early warning actually demands of an on-call rotation
The regulation sets an early warning within 24 hours of becoming aware, a fuller notification within 72 hours, and a final report on a deadline measured from the notification rather than from discovery. (Read Article 14(2) for the exact figures before you encode them in an SLA — I am not going to restate them as gospel from memory.)
Twenty-four hours sounds generous until you price the actual path: detection at 02:00 → someone confirms it is real → someone determines the affected product versions → legal and comms review → submission to the single reporting platform by a person with authority to file. That last step is the bottleneck. You need a named rota, a pre-approved template, and a pre-authorised signer, or the first real filing burns the whole window in approvals.
Five-Year Security Update Windows and the Cost of a Long Support Tail
Signing keys, maintained branches, and reproducible rebuilds
The support period is where CRA quietly becomes an infrastructure cost. If you must ship security updates for five years, you must be able to rebuild a tag from four years ago — with the toolchain, base image, and signing key that existed then.
That means:
- Pinned base images by digest, never by tag.
- Archived toolchain versions, including the exact Node minor.
- Reproducible output, so a rebuild can be verified: set
SOURCE_DATE_EPOCHand fix nondeterministic build metadata where you can. - A signing key lifecycle plan. Key compromise with a five-year tail is a compliance incident, not just an ops incident. Assume rotation and plan the re-attestation path.
docker build --build-arg SOURCE_DATE_EPOCH=1700000000 -t app:rebuild .
docker run --rm app:rebuild sha256sum /app/dist/app.tar.gz
If that hash does not match the original artifact, your rebuild is not evidence — it is a new build that happens to compile.
Why an unsupported release branch is now a compliance artifact problem
Before the CRA, dropping support for a version meant a support ticket. Now it is a mismatch between what you declared in the technical documentation and what you can actually do. Article 13(8) requires the support period to be determined and documented; if the documentation claims five years, the branch and the signing infrastructure have to exist for five years.
The practical consequence: version support policy becomes a scoping decision made at design time, not an engineering decision made when maintenance gets boring.
Conformity Assessment and Evidence Capture in CI
Freezing build logs and artifact hashes as audit evidence without slowing the build
Attach evidence to the artifact instead of to a wiki:
cosign attest --predicate sbom-npm.cdx.json --type cyclonedx \
ghcr.io/acme/app@sha256:<digest>
Two practical failure modes to watch. Default artifact retention in hosted CI (often 90 days) is far shorter than the assessment cycle, so export logs and attestations to storage you control. And transparency-log entries are only useful if you record the log index alongside the artifact digest. Keep both.
Self-assessment versus third-party assessment, and what changes in the pipeline
The default route is internal control — you assess yourself, and you own the evidence. Annex III "important products" with higher risk profiles need notified-body involvement, and Annex IV critical products go further. That changes the pipeline in one specific way: evidence must be verifiable by a party who was not present for the build. Hermetic, reproducible builds stop being a nice-to-have and become the thing that lets an assessor independently confirm your artifact.
What Reuses Existing Tooling and What Needs New Engineering Work
| Obligation | Reuses existing tooling | Needs new work |
|---|---|---|
| SBOM at top-level dependencies | CycloneDX/SPDX generators, lockfiles | Vendored-code and postinstall coverage |
| Provenance | Build attestations, Sigstore | Retention beyond CI defaults |
| Vulnerability handling | Dependabot/Renovate, OSV | Exploitation telemetry, disclosure contact |
| 24h reporting | Incident tooling | Rota, template, pre-authorised signer, platform integration |
| Security updates for 5 years | Branch strategy | Archived toolchains, key rotation, reproducible rebuilds |
| Conformity evidence | CI logs, attestations | Export to durable storage, assessor-verifiable reproducibility |
Four of six rows need engineering work that no current tool does for you.
Unconfirmed Details and What to Watch
- Harmonised standards. Status is not settled in anything I can cite confidently. If standards land late, self-assessment becomes harder to defend, because presumption of conformity is what makes it tractable.
- Single reporting platform mechanics. API shape, authentication, and whether machine submission is possible are unconfirmed. If submission is portal-only, the 24-hour window costs more human time than the regulation implies.
- SBOM format. The regulation requires a "commonly used and machine-readable format" rather than naming CycloneDX or SPDX. Do not assume an implementing act won't narrow this.
- Open-source steward scope. Article 24 creates a lighter regime, but the boundary between "steward" and "manufacturer" for a company that both maintains a project and ships a product is exactly the kind of thing that gets clarified by enforcement. Legal question, not an engineering one — but it changes your SBOM scope.
Conclusion
The CRA is a release-engineering regulation wearing a compliance jacket. The cheap, well-tooled part is the SBOM and provenance — a week of work for most teams running modern CI. The expensive parts are the ones with no off-the-shelf answer: a 24-hour reporting path that survives a 02:00 trigger, and a five-year rebuild capability that includes the keys.
Start with reproducibility, not documentation. If you cannot rebuild last year's artifact byte-for-byte, none of the paperwork you generate about it is evidence.
Further Reading
- Regulation (EU) 2024/2847 (Cyber Resilience Act) — full text on EUR-Lex — primary source for Articles 13, 14, 16, 71 and Annexes I, III, IV, VII, VIII
- European Commission — Cyber Resilience Act policy page — implementation status and guidance as published
- Refindustry — EU Cyber Resilience Act Introduces Cybersecurity Rules for HVAC/R — the seed trade coverage, via Google News redirect
- CycloneDX specification — the SBOM format used in the examples
- SPDX — the alternative format
- SLSA specification — provenance levels and threat model
- Sigstore documentation —
cosign attest, keyless signing, and Rekor entries - OSV API documentation — the query endpoint used above
- Anchore Syft — filesystem and image SBOM generation
- CycloneDX for npm — lockfile-driven SBOM generation
- OASIS CSAF documentation — machine-readable advisory and VEX formats
- Reproducible Builds — SOURCE_DATE_EPOCH — the mechanism behind rebuild verification
More posts

Inside the LiteLLM 1.107.0 PyPI Compromise: Infostealer, CI Secrets, and Where Verification Failed
A technical breakdown of the malicious LiteLLM 1.107.0 PyPI release, examining how an infostealer and RAT harvested credentials from developer machines and CI pipelines, what secrets were exposed, and where package integrity verification broke down.

Auditing Your WhatsApp Cloud API Integration Before the October 2027 Marketing Cutoff
A practical guide to auditing your WhatsApp Cloud API integration ahead of the October 2027 marketing message deprecation, covering abstraction layers, monitoring, and migration planning.

Hardening Legacy PHP Against PHP2Shell When No Official Patch Exists
Harden legacy PHP deployments exposed to PHP2Shell with WAF rules, runtime restrictions, patch triage, and incident-response checks when no official fix is available.
Loading comments…