From esp-idf-sbom to Annex VII: what your firmware SBOM covers for the CRA — and what it doesn't

23 July 2026 · SBOMReady · 6 min read

If you build on ESP-IDF, generating a spec-compliant SBOM for your firmware takes one command and a few minutes. Building the evidence file the Cyber Resilience Act actually wants takes a lot longer than that — and the gap between the two is where most small manufacturers get a false sense of security. This article walks through what esp-idf-sbom gives you today, maps it against the CRA's technical documentation requirements (Annex VII), and is explicit about the parts no SBOM tool generates for you.

What one command actually gives you

esp-idf-sbom is a separate tool (not yet bundled with ESP-IDF itself, install it with pip install esp-idf-sbom) that reads the project_description.json your build already produces and emits an SPDX 2.2 file:

idf.py build
esp-idf-sbom create -o sbom.spdx build/project_description.json

By default this creates one SPDX Package per component that took part in the build — including components that were compiled but never actually linked into the final image, because nothing in them was referenced. If you want the SBOM to match what's really running on the device rather than what was merely compiled, there's a flag for that:

esp-idf-sbom create --rem-unused --rem-config -o sbom.spdx build/project_description.json

This solves, at the tool level, a problem that keeps coming up in embedded forums: people writing scripts to scan build/ for .o files to guess what actually made it into the firmware. --rem-unused does the equivalent job from data the build system already has, which is more reliable than directory scanning and doesn't need maintaining.

Where it lands against the NTIA minimum elements

The CRA doesn't yet specify an exact SBOM data schema (the Commission can still do that via implementing acts under Article 13(24)), so the working reference is the NTIA minimum elements: supplier name, component name, version, other unique identifiers, dependency relationship, author of the SBOM data, and timestamp. esp-idf-sbom covers most of this out of the box — component name, version, and the dependency relationships between packages come straight from the build graph, and the SPDX document itself carries the creation timestamp and tool identity.

The field that needs your attention is identifiers and supplier/originator data for vendored and patched components — which, in embedded firmware, is most of them. esp-idf-sbom supports manifest files (sbom.yml) where you can set an explicit purl override and separate supplier/originator fields — originator being the upstream author of code you then patched, supplier being whoever ships the final component. If you skip that manifest step, your SBOM is technically valid SPDX but the vendored libraries carry weak or missing identifiers, which is exactly what makes vulnerability scanners either false-positive against upstream CVEs or silently miss the match. This is the same gap that keeps surfacing in the C/C++ SBOM discussions on r/embedded and in the ORC Working Group's FAQ threads: generating the document is the easy part, making it match something is the part that takes deliberate work.

What Annex VII asks for beyond the components list

This is the part that a components list, however accurate, doesn't cover. Annex VII lists eight categories of content for the technical file, and the SBOM is explicitly just one line item inside category 2: a general description of the product (intended purpose, the software versions that affect compliance, photos/diagrams if it's hardware, the Annex II user instructions); a description of design, development and production, including system architecture and "necessary information and specifications of the vulnerability handling processes... including the software bill of materials, the coordinated vulnerability disclosure policy, evidence of the provision of a contact address for the reporting of vulnerabilities, and a description of the technical solutions chosen for the secure distribution of updates"; a cybersecurity risk assessment showing how the essential requirements in Annex I Part I apply; the reasoning behind your chosen support period; the list of harmonised standards you applied; the test reports proving conformity; and a copy of the EU declaration of conformity.

There's a nuance worth knowing here: Annex VII's last item clarifies that the full SBOM itself only has to be handed over "further to a reasoned request from a market surveillance authority" — it's not necessarily something you keep bundled at full detail in the standing file at all times, only something you have to be able to produce, complete and current, the moment it's asked for. That doesn't lower the bar much in practice: if generating it on demand means re-running a script you haven't touched in six months against a codebase that has moved on, you've already failed the "current" part.

Two things worth being precise about beyond the Annex VII list itself, straight from Article 13: the cybersecurity risk assessment "shall be" included in the technical documentation required under Article 31 and Annex VII, and separately, "manufacturers shall include the information that was taken into account to determine the support period" in that same documentation — and that support period "shall be at least five years" unless the product's expected use is shorter. Neither of those is something a build-time SBOM tool produces. They are decisions you make and write down.

The practical takeaway

If your toolchain already generates an SBOM — ESP-IDF, Zephyr's west spdx, Yocto's create-spdx — you are further ahead than the CRA headlines suggest, because that step is close to free. What still needs deliberate work, in roughly the order it will get asked for: fixing the identifier quality on your vendored components (manifest overrides, not guesswork); writing the coordinated vulnerability disclosure policy and publishing a real contact point (security.txt is a cheap way to make the second one auditable); documenting how your OTA update mechanism actually gets signed and distributed; a short risk assessment that says, in plain terms, which Annex I requirements apply to your product and why; and a one-paragraph justification for your chosen support period. None of these are exotic. All of them are the kind of thing that's easy to keep putting off until an auditor — or the 11-September-2026 reporting clock — asks for it first.

Want to see where your SBOM already stands? Upload the SBOM your toolchain generates (or paste it, or try the built-in ESP32 sample — we never store it) and get your open CVEs, exploitation flags, and a checklist of what's still missing for the CRA / EN 18031 technical file: run the free check.

This article is an engineering-oriented overview, not legal advice. Primary sources: Regulation (EU) 2024/2847 (CRA), Articles 13 and 31 and Annex VII; the esp-idf-sbom project documentation (Espressif); NTIA, "The Minimum Elements for a Software Bill of Materials (SBOM)".