What the CRA actually requires
Annex I Part II obliges manufacturers to identify and document vulnerabilities and components contained in the product, including by drawing up a software bill of materials in a commonly used machine-readable format covering at the very least the top-level dependencies.
Two things follow. The SBOM is mandatory, and it is a process artefact, not a one-off deliverable: a new SBOM for every release. It does not have to be public — it belongs in the technical documentation and must be provided to market surveillance authorities on request.
Formats
- SPDX (ISO/IEC 5962) — strong provenance and licensing model, widely used in Linux-based products.
- CycloneDX (OWASP, ECMA-424) — security-oriented, first-class support for VEX, vulnerabilities and hardware components; the pragmatic default for embedded.
Either satisfies "commonly used machine-readable format". Pick one and be consistent across the portfolio, because your tooling and your customers' tooling both have to consume it.
Generating an SBOM from embedded builds
The hard part of embedded is that nothing comes from a package manager.
| Build system | Approach |
|---|---|
| Yocto / OpenEmbedded | create-spdx / create-spdx-2.2 class emits SPDX per image; recipes carry version and licence data already |
| Buildroot | BR2_LEGAL_INFO plus the CycloneDX generator; recipe metadata is the source of truth |
| Zephyr | Built-in SPDX generation from the CMake file dependency graph |
| Bare-metal / vendor SDK | No metadata exists — maintain a curated manifest in version control, one entry per third-party source drop, and enforce it in review |
| Binary blobs from silicon vendors | Contractually require an SBOM; where refused, record the component, version and the gap in your documentation |
Where automation cannot reach, a curated manifest checked into the repo is entirely acceptable — as long as it is reviewed on every dependency change and generated into the release artefact.
Depth: top-level is the floor, not the goal
The CRA requires at least top-level dependencies. Top-level only is close to useless for vulnerability screening in embedded, where the risk hides in a statically linked zlib three layers down. Go transitive where your build system knows the graph.
Wiring the SBOM into vulnerability management
The SBOM only earns its keep when it is continuously matched against vulnerability feeds:
- Store every release SBOM keyed by firmware build identifier, so a field device's version maps to an exact component list.
- Run a scheduled matcher against NVD/OSV and vendor advisories.
- Triage each hit: is the vulnerable code path reachable in your configuration?
- Publish the outcome as VEX (Vulnerability Exploitability eXchange), so customers can see "not affected — vulnerable function not compiled in" instead of chasing a false positive.
That pipeline is the practical mechanism by which you can claim, at release, no known exploitable vulnerabilities — and by which you learn about the next one on day zero rather than from a customer.