Licensing, SBOMs and Vulnerability Management

How license metadata, SPDX SBOMs, CVE checking, and vulnerability decisions fit into a Yocto release process

Earlier in the course, we mentioned compliance and SBOMs as one of the reasons Yocto is useful for product work. This lesson closes that loop.

This is not a generic cybersecurity course. The aim here is much more practical: when you ship an embedded Linux product, you need to know what software is in it, what licenses apply, where the software came from, and how you are handling known vulnerabilities.

Yocto cannot make those decisions for you, but it can give you much better evidence than trying to assemble the information by hand after the product has already shipped.

Recipe License Metadata

Every normal recipe should declare the license of the software it builds.

The two variables you see most often are:

LICENSE

The license expression for the software, preferably using SPDX license identifiers.

LIC_FILES_CHKSUM

A list of license files and checksums that BitBake uses to detect changes to the referenced license text.

A simple recipe might contain:

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

For upstream source, the license file usually comes from the source tree:

LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://LICENSE;md5=0123456789abcdef0123456789abcdef"

LIC_FILES_CHKSUM is not just bureaucratic decoration. If upstream changes the license text, BitBake can notice and stop the build so someone reviews the change. That is exactly the kind of interruption you want before release, not after.

License Manifests

When Yocto builds an image, it can produce license information for the packages included in that image. This is useful because the image contains packages, not every recipe that exists in every enabled layer.

The practical release question is:

What did we actually ship?

License manifests help answer that question. They are part of the evidence you retain with the release artifacts, along with the image, manifest, SBOM, logs, and vulnerability reports.

Do not treat license manifests as something only lawyers care about. Engineers need them too, because they connect the shipped image back to the recipes and packages that produced it.

Collecting License Information for a Shipped Product

For a release, collect license information from the exact image build you intend to ship.

That means:

  • build the release image from pinned metadata
  • keep the generated license output
  • keep the package manifest
  • keep the layer manifest or exact revisions
  • keep local patches that modify upstream software
  • record any manual license review decisions

If your product has several images, collect the data per image. A development image with debugging tools is not the same legal or security surface as a production image.

SPDX and SBOMs

An SBOM, or Software Bill of Materials, describes the software components in the product and their relationships.

Current Yocto releases can generate SPDX output for images. In Wrynose-era metadata, the usual class to look for is:

INHERIT += "create-spdx"

When enabled for an image build, the SPDX output is deployed with the image artifacts. For an image, you should expect a top-level SPDX JSON document under a path like:

tmp/deploy/images/<machine>/<image>-<machine>.spdx.json

The exact filename depends on the image and machine. The important point is that the SBOM is generated from the build metadata and build result, not from someone trying to reconstruct the product in a spreadsheet later.

What an SBOM Is Good For

An SBOM helps answer questions such as:

  • which components are in this image?
  • which versions were built?
  • which recipes and sources produced them?
  • which licenses are involved?
  • which patches or modifications were part of the build?
  • what vulnerability data was known at build time?

It is not a magic compliance shield. It is structured evidence. The quality of that evidence still depends on the quality of the recipe metadata, source pinning, patches, and release process.

CVE Checking

Yocto includes support for CVE checking through the cve-check class.

A common project-level configuration is:

INHERIT += "cve-check"

This enables vulnerability checking during the build and produces reports that can be archived with the release. You can also run the relevant tasks as part of CI depending on how the project is structured.

The output should be treated as an engineering input. It tells you what the tools matched. It does not, by itself, complete the vulnerability assessment.

Interpreting Vulnerability Results

A CVE match does not automatically mean the product is vulnerable.

It may mean:

  • the product includes a vulnerable version
  • the fix was backported without changing the upstream version number
  • the vulnerable code path is not built
  • the vulnerable feature is disabled
  • the vulnerable component is present only in a development image
  • the version matching is too broad
  • the recipe metadata needs more precise CVE information

This is why vulnerability reports need review rather than blind panic.

The opposite is also true. A clean report does not mean the product is magically secure. It means no known issue was matched by the data and tooling used at that time.

Backported Fixes

Embedded Linux products often use long-term maintained branches. Those branches may backport security fixes without changing to the latest upstream version.

That creates a common CVE-checking problem:

reported version: 1.2.3
CVE database says: fixed in 1.2.9
your vendor branch: 1.2.3 plus the security patch backported

A simple version comparison may still report the CVE. The right response is not to hide the report because it is annoying. The right response is to document why the product is or is not affected.

That documentation might reference:

  • the patch that fixes the issue
  • the vendor advisory
  • the upstream commit
  • the build configuration that disables the affected feature
  • the reason the package is not present in the production image

Document Vulnerability Decisions

For each relevant vulnerability, record the decision.

Useful categories are often:

  • fixed by update
  • fixed by backport
  • not affected because the code is not built
  • not affected because the package is not shipped
  • not affected because the vulnerable configuration is disabled
  • accepted risk with justification
  • needs investigation

The exact workflow depends on the organisation, but the engineering principle is the same: do not let vulnerability handling live only in someone’s head.

If a customer, auditor, or future engineer asks why a CVE was not patched, you should be able to answer from the release record.

Software Provenance

Software provenance means knowing where the software came from and how it was modified.

Yocto helps because recipes describe:

  • source locations
  • source revisions
  • patches
  • build dependencies
  • package outputs
  • image contents

That does not remove your responsibility to keep the metadata clean. If recipes fetch moving branches, patches have vague names, and local changes are hidden in vendor layers, provenance gets weaker very quickly.

The release maintenance lesson covered the importance of fixed SRCREV values, layer manifests, and local patch discipline: Reproducible Releases and Project Maintenance.

Fitting This Into the Release Process

For a production release, licensing and vulnerability work should happen before the release is declared done.

A practical release flow might include:

  1. Build the release image from pinned metadata.
  2. Generate and archive license manifests.
  3. Generate and archive SPDX/SBOM output.
  4. Run CVE checking.
  5. Review the vulnerability report.
  6. Document fixed, not-affected, and accepted-risk decisions.
  7. Archive the final image, SDK, logs, manifests, SBOM, and CVE reports.
  8. Tag or record the exact release inputs.

This is not about making the build process ceremonial. It is about making sure the release can be explained later.

Summary

Yocto gives you useful compliance and vulnerability evidence as part of the build system.

The main ideas from this lesson are:

  • recipes should declare LICENSE
  • LIC_FILES_CHKSUM helps detect license text changes
  • license manifests connect the shipped image back to package license data
  • SPDX output provides an SBOM for the built image
  • cve-check helps identify known vulnerability matches
  • CVE results need engineering review
  • backported fixes can confuse version-based CVE matching
  • vulnerability decisions should be documented
  • software provenance depends on clean metadata and pinned sources
  • licensing, SBOM, and CVE outputs belong in the release record

Quick quiz: licensing and SBOMs

Check how compliance data is used in a release process.

Question 1What does `LIC_FILES_CHKSUM` help BitBake detect?
Question 2Why does a CVE match not automatically mean the product is vulnerable?
Question 3Where should licensing, SBOM, and vulnerability outputs fit?