32blogby StudioMitsu
yocto8 min read

Yocto SBOM and CVE Management: A Practical Guide for Scarthgap

Generate SBOMs with create-spdx and scan CVEs with cve-check in Yocto Scarthgap 5.0 LTS. Covers EU CRA compliance and production workflows.

yoctoembedded-linuxsbomcvescarthgap
On this page

SBOM is everywhere in embedded Linux discussions now. The EU's new regulation mandates SBOM submission by 2027. The FDA already requires it for medical devices.

This guide walks through generating SBOMs and scanning for CVE vulnerabilities using Yocto Scarthgap 5.0 LTS (BitBake 2.8) built-in tools. From the regulatory background to practical configuration and production workflows — everything in one article.

Why SBOM Is Becoming Mandatory for Embedded

An SBOM (Software Bill of Materials) is an inventory of all software components in a product. Which libraries are included, what versions they are, and what licenses they use — recorded in a machine-readable format.

You might think "we're too small for this to matter." But if you ship products to the EU, US, or automotive markets, your team is already affected.

EU Cyber Resilience Act (CRA)

Entered into force in December 2024. Full requirements apply from December 11, 2027. It covers every business that manufactures, sells, or imports products with digital elements into the EU market. Japanese companies exporting to the EU are included.

Specific SBOM requirements:

  • Create and maintain SBOMs in machine-readable format (SPDX / CycloneDX)
  • Must be available for market surveillance authorities on request
  • Penalties up to €15 million or 2.5% of global annual revenue

Medical Devices (FDA)

The US FDA has required SBOM submission since March 2023 under FD&C Act Section 524B (PATCH Act). SBOMs are mandatory for premarket submissions. The FDA can refuse to accept applications without one.

Automotive (UN-R155 / R156)

UN-R155 doesn't explicitly mandate SBOMs. However, operating a Cyber Security Management System (CSMS) requires knowing your software composition, and vulnerability management doesn't work without it. In Japan, UN-R155 compliance has been mandatory for all new vehicle types since July 2024.

Japan

No legal mandate yet. However, METI (Ministry of Economy, Trade and Industry) has published the "Guide to Introducing SBOMs" (version 2.0, August 2024), widely seen as groundwork for future legislation. In September 2025, Japan co-signed a 15-nation international SBOM guidance document.

Generating SBOMs with create-spdx

In Scarthgap, the default Poky distro configuration (poky.conf) includes INHERIT += "create-spdx", so it's enabled by default. A normal build automatically generates SBOMs.

Check if it's enabled

bash
bitbake-getvar -r core-image-minimal INHERIT

If the output includes create-spdx, you're set. If not, add the following to conf/local.conf.

bash
# conf/local.conf — manually enable create-spdx (usually unnecessary)
INHERIT += "create-spdx"
bash
# conf/local.conf — recommended SBOM settings
SPDX_PRETTY = "1"

SPDX_PRETTY adds indentation to the JSON output, making it human-readable. File size increases, but it's worth it for debugging and review.

If you need source code traceability, add these as well.

bash
# conf/local.conf — include source info in SBOM (optional)
SPDX_INCLUDE_SOURCES = "1"
SPDX_ARCHIVE_SOURCES = "1"

Build and check the output

Run a normal build.

bash
bitbake core-image-minimal

After the build completes, the SBOM is at:

tmp/deploy/images/<MACHINE>/core-image-minimal-<MACHINE>.spdx.tar.zst

Extract and inspect the contents.

bash
cd tmp/deploy/images/qemux86-64/
mkdir spdx-output && cd spdx-output
tar -I zstd -xf ../core-image-minimal-qemux86-64.spdx.tar.zst
ls *.spdx.json | head -10

Understanding the SBOM Output

After extraction, you'll find one SPDX file per recipe. Each file is in SPDX 2.2 JSON format.

File structure

spdx-output/
├── recipe-core-image-minimal.spdx.json    ← entire image
├── recipe-busybox.spdx.json               ← individual recipe
├── recipe-glibc.spdx.json
├── recipe-openssl.spdx.json
└── ...

Key JSON fields

Opening an individual SPDX file shows a structure like this (simplified).

json
{
  "spdxVersion": "SPDX-2.2",
  "dataLicense": "CC0-1.0",
  "name": "recipe-openssl",
  "packages": [
    {
      "name": "openssl",
      "versionInfo": "3.2.1",
      "supplier": "Organization: OpenSSL",
      "downloadLocation": "https://www.openssl.org/source/openssl-3.2.1.tar.gz",
      "licenseConcluded": "Apache-2.0",
      "licenseDeclared": "Apache-2.0"
    }
  ],
  "relationships": [
    {
      "spdxElementId": "SPDXRef-Recipe",
      "relationshipType": "GENERATES",
      "relatedSpdxElement": "SPDXRef-Package-openssl"
    }
  ]
}

The key fields for compliance:

  • packages: Package name, version, license, and download location
  • relationships: Dependency chain between recipes and packages
  • licenseConcluded / licenseDeclared: License information (always reviewed in audits)

Scanning Vulnerabilities with cve-check

The cve-check class cross-references built packages against the NIST NVD (National Vulnerability Database) to detect known vulnerabilities. Unlike create-spdx, it must be enabled manually.

Enable it

bash
# conf/local.conf — enable CVE checking
INHERIT += "cve-check"

Check a specific recipe

bash
bitbake -c cve_check openssl

Check the entire image

With INHERIT += "cve-check" set, a normal build generates CVE reports automatically.

bash
bitbake core-image-minimal

Report locations

tmp/deploy/cve/
├── openssl                    ← per-recipe text
├── openssl_cve.json           ← per-recipe JSON
└── ...

tmp/deploy/images/<MACHINE>/
├── core-image-minimal-<MACHINE>.cve        ← image-wide text
└── core-image-minimal-<MACHINE>.cve.json   ← image-wide JSON

Both text and JSON formats are generated by default.

Reading the report

The text report lists each CVE with its status.

PACKAGE NAME: openssl
PACKAGE VERSION: 3.2.1
CVE: CVE-2024-XXXXX
CVE STATUS: Patched
CVE SUMMARY: ...

CVE: CVE-2024-YYYYY
CVE STATUS: Unpatched
CVE SUMMARY: ...

There are three status values:

  • Patched: Fixed by a Yocto patch
  • Unpatched: Not fixed. Needs attention
  • Ignored: Intentionally skipped (set via CVE_STATUS)

Filtering CVE Report Noise

Enabling CVE checks can flood you with results. The Linux kernel alone has thousands of registered CVEs, and the vast majority don't apply to your specific architecture or kernel configuration.

Mark individual CVEs with CVE_STATUS

When a specific CVE doesn't apply to your platform, exclude it with CVE_STATUS.

bash
# In a recipe or bbappend
CVE_STATUS[CVE-2024-12345] = "not-applicable-platform: Only affects Windows"
CVE_STATUS[CVE-2024-67890] = "not-applicable-config: Feature disabled in our config"

Status values are predefined in cve-check-map.conf. Common ones include not-applicable-platform, not-applicable-config, cpe-incorrect, and upstream-wontfix. The text after the colon documents the specific reason, making exclusions auditable. You can manage these settings in a bbappend without modifying the original recipe. If migrating from Kirkstone, you'll need to rewrite CVE_CHECK_IGNORE to CVE_STATUS — see the migration checklist.

Batch-manage with CVE_STATUS_GROUPS

When many CVEs share the same exclusion reason, group them for easier management.

bash
# conf/local.conf or a custom inc file
CVE_STATUS_GROUPS = "CVE_STATUS_WIN CVE_STATUS_ARM32"

CVE_STATUS_WIN = "CVE-2024-11111 CVE-2024-22222 CVE-2024-33333"
CVE_STATUS_WIN[status] = "not-applicable-platform: Windows-only vulnerability"

CVE_STATUS_ARM32 = "CVE-2024-44444 CVE-2024-55555"
CVE_STATUS_ARM32[status] = "not-applicable-platform: ARM32-only, we target ARM64"

Limit scan scope by layer

Useful when you only want to check your own layer.

bash
# conf/local.conf — check only your layer
CVE_CHECK_LAYER_INCLUDELIST = "meta-mylayer"

# or exclude specific layers
CVE_CHECK_LAYER_EXCLUDELIST = "meta-poky"

Use the official exclusion list

Poky ships with a pre-defined CVE exclusion list.

bash
# conf/local.conf
include conf/distro/include/cve-extra-exclusions.inc

Production Workflow

Here's how to integrate SBOM and CVE checking into your daily build flow.

bash
# conf/local.conf — SBOM + CVE recommended settings

# SBOM generation (enabled by default, but make it explicit)
INHERIT += "create-spdx"
SPDX_PRETTY = "1"

# CVE checking
INHERIT += "cve-check"

# Official CVE exclusion list
include conf/distro/include/cve-extra-exclusions.inc

Per-build flow

1. bitbake <image>
   ↓ automatic
2. SBOM generated → tmp/deploy/images/MACHINE/IMAGE.spdx.tar.zst
   ↓ automatic
3. CVE report generated → tmp/deploy/images/MACHINE/IMAGE.cve
   ↓
4. Review Unpatched CVEs
   ↓
5. Apply patches or exclude with CVE_STATUS (with documented reasons)
   ↓
6. Archive SBOM + CVE report in version control

Extract Unpatched CVEs

bash
# Extract Unpatched entries from the text report
grep -B 3 "CVE STATUS: Unpatched" \
  tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.cve

For debugging build issues that arise from patching CVEs, the build error debugging guide covers devshell and log analysis techniques.

EU CRA Compliance Checklist

#RequirementHow Yocto Handles It
1Machine-readable SBOMcreate-spdx (enabled by default)
2Known vulnerability scanningcve-check
3Vulnerability response documentationCVE_STATUS with reasons
4Regular SBOM updatesRegenerate SBOM with each release build
5Authority submission readinessArchive .spdx.tar.zst as build artifacts

Wrapping Up

SBOM and CVE management is no longer a "nice to have." The EU CRA deadline in 2027, the existing FDA mandate, the practical requirements of UN-R155 — regulation is closing in.

The good news: compliance with Yocto Scarthgap is simpler than you might think.

TaskMethodEffort
SBOM generationcreate-spdx (enabled by default)Near zero
CVE scanningINHERIT += "cve-check"One line in conf/local.conf
Noise filteringCVE_STATUS + documented reasonsOne-time setup effort
OperationsArchive SBOM + CVE report per buildAutomate via CI/CD

SBOMs are already being generated by default. CVE checking takes one line to enable. The first step toward regulatory compliance is easier than you think.

PRMastering Embedded Linux Development 4th Ed (2024)View on Amazon
PREmbedded Linux Development Using Yocto Project 3rd Ed (2023)View on Amazon
PRYocto Project Customization for Linux (Apress, 2025)View on Amazon