SBOM generation for hardware and firmware products

Firmware and embedded systems require a different SBOM generation approach compared to software. This guide explains how to generate accurate SBOMs for hardware products.

Why build-system SBOMs are more accurate

When you scan a compiled firmware binary with a tool like Syft, coverage depends entirely on what metadata survived the build process. Embedded Linux firmware often lacks package manager databases (dpkg, rpm, apk), so Syft relies on binary signatures, which leads to significant coverage gaps.

For CRA compliance, your SBOM must accurately represent all components in your product. The most accurate SBOM comes from your build system, not from binary scanning.

Source Coverage Recommended
Yocto SPDX (build-time) Complete ✅ Yes
Buildroot legal-info Complete ✅ Yes
Custom manifest Complete ✅ Yes
Syft on firmware rootfs Partial ⚠️ Fallback only
Syft on container image Good ✅ Yes (containers)

Yocto has built-in SPDX SBOM generation since Kirkstone (4.0). No additional tools required.

Enable SPDX generation in your conf/local.conf or distribution config:

INHERIT += "create-spdx"

Generate the SBOM during your normal build:

bitbake your-image

The SBOM is written to tmp/deploy/images/<machine>/ as a .spdx.json file (CycloneDX output is also available via SPDX_PRETTY = "1").

Upload to CRA Evidence:

craevidence upload-sbom \
  --product my-router \
  --version 2.1.0 \
  --file tmp/deploy/images/raspberrypi4/my-image-raspberrypi4.spdx.json \
  --product-type hardware

Buildroot

Buildroot generates a component list via its legal infrastructure:

make legal-info

This produces output/legal-info/manifest.csv with all packages, versions, and licences. You can convert this to SPDX or CycloneDX using a tool like sbom-tool or upload the manifest directly.

Upload to CRA Evidence:

craevidence upload-sbom \
  --product my-firmware \
  --version 1.4.2 \
  --file output/legal-info/buildroot.spdx.json \
  --product-type hardware

Binary scanning (fallback)

If you do not have access to build-system-generated SBOMs, you can use Syft to scan a firmware rootfs directory:

craevidence upload-sbom \
  --product my-router \
  --version 2.1.0 \
  --source ./build/rootfs/ \
  --product-type hardware

Warning: Syft coverage on embedded firmware rootfs is lower than on container images. Many components embedded in firmware do not have package manager metadata. Use this only as a starting point and supplement with your build system manifest.

CI/CD integration

For Yocto in a CI pipeline:

# GitHub Actions example
- name: Build firmware
  run: bitbake my-image

- name: Upload SBOM
  run: |
    craevidence upload-sbom \
      --product ${{ env.PRODUCT_SLUG }} \
      --version ${{ env.VERSION }} \
      --file tmp/deploy/images/${{ env.MACHINE }}/my-image.spdx.json \
      --product-type hardware \
      --scan
  env:
    CRA_EVIDENCE_API_KEY: ${{ secrets.CRA_EVIDENCE_API_KEY }}
    CRA_EVIDENCE_URL: https://api.craevidence.com

Next steps

Last updated April 21, 2026
Was this page helpful?
Thanks for your feedback!

Help us improve. What was missing or unclear?