Embedded

Firmware SBOMs for embedded devices

What a useful firmware SBOM contains, how to generate one from Buildroot or Yocto, and which parts of an embedded build it will still miss.

The problem: A server-side SBOM generator expects a package manager and a lockfile. Your device ships a cross-compiled image, a bootloader, a vendor radio module and no package manager at runtime.

Why firmware SBOMs are different

  • Static linking hides dependencies inside a binary; there is no runtime package list to inspect.
  • Build systems (Buildroot, Yocto, Zephyr, vendor SDKs) already know the recipe versions — the SBOM should be an output of that build, not a separate archaeology project.
  • A meaningful share of the image is vendor blobs with no public package identity at all.
  • The same source library may be patched by the vendor, so the upstream version alone is not the whole truth.
  • The artifact you ship is a firmware image with its own hash, not a directory of files.

What to include

FieldWhy it mattersTypical mistake
metadata.component = the firmwareAnchors the SBOM to a product and versionListing only components, with no product identity
Component name, version, supplierMinimum identity for any matching or support answerSupplier set to “unknown” for every entry
purl or CPEThe only reliable way to match advisoriesDescriptive versions that cannot be resolved
Nested componentsStatically linked libraries inside dependenciesOnly top-level dependencies declared
Dependency relationshipsExplains which component pulled in whichReferences that do not resolve to a component
Hashes and licensesIntegrity and obligation reviewHashes of the SBOM instead of the components
Build metadataReproducibility and provenanceNo tool name or build timestamp

Generate it from the build

  • Yocto: use the SPDX or CycloneDX generation class in your image recipe and publish the document as a release artifact.
  • Buildroot: collect the legal-info manifests the build already produces and convert them to CycloneDX or SPDX in a post-build step.
  • Zephyr or vendor SDKs: add an explicit manifest step that lists modules with their versions and commit identifiers.
  • Always set the firmware product and version in metadata, and attach the firmware image hash.

Treat SBOM generation as a build gate. If the document is produced by hand after the release, it will describe the release someone remembers rather than the one that shipped.

Validate in CI, with the same limits as production

Validation must fail the build on the defects you care about: unsupported format versions, components with no identity, dependency references that do not resolve, and an implausible component count. Everything else should be a warning with an owner.

- format is CycloneDX 1.4+ or SPDX 2.3 JSON
- schema validation passes
- component count >= the previous release's count - expected removals
- zero components without purl, CPE or an explicit vendor-component marker
- zero broken dependency references
- firmware image hash present in metadata

What an SBOM still will not tell you

An SBOM describes declared software, not the binary reality of the image. If a component was linked in without appearing in the build manifest, the SBOM will not contain it. Binary analysis answers a different question; neither replaces the other.

The same applies to configuration: a vulnerable library that is compiled without the affected code path is still listed, and an SBOM cannot tell you whether the device is exploitable.

Scope and limits

  • This guide does not replace your build system's documentation or a binary analysis of the image.
  • A complete SBOM is a prerequisite for CRA evidence, not evidence of compliance.

Sources

Next step

Validate a firmware SBOM now