Two people will read the SPDX file your Yocto build just emitted, and they will ask it different questions. The premarket cybersecurity reviewer wants to know what is in the device and whether you can track it after shipment. The open-source license reviewer wants to know what obligations attach to each component and whether you can produce the corresponding source. The file is the same. The reconciliation work is not.
This article is about that reconciliation: what the OpenEmbedded build system actually emits, what it does not, and how to close the gap between a generated IMAGE-MACHINE.spdx.json and an artifact that supports both a regulatory submission and a GPL compliance position. I am writing from the build-engineering side. Where I cannot confirm a regulatory detail from a primary source, I say so rather than smoothing it over.
What the build system actually emits
The Yocto Project Development Manual describes the OpenEmbedded build system as able to generate a description of all the components used, their licenses, their dependencies, their sources, the changes applied to them, and the known vulnerabilities that were fixed — in the form of a Software Bill of Materials using the SPDX standard. Building an image produces SPDX output in JSON as IMAGE-MACHINE.spdx.json under tmp/deploy/images/MACHINE/ in the Build Directory. A recipe-level SBOM can be generated from recipe metadata alone with bitbake <recipe> -c create_recipe_sbom, and the manual notes that recipe SBOMs are included in the image SBOM only for recipes involved in the image build. See the Yocto Project Development Tasks Manual, “Creating a Software Bill of Materials.”
Version matters here, and it matters in a way that should be recorded in your procedure rather than assumed. The 6.1-tip documentation states that the build system generates SBOM information by default by inheriting the create-spdx class in INHERIT_DISTRO, and that it can be disabled with INHERIT_DISTRO:remove = "create-spdx". The 5.1-tip documentation states the opposite default: the build system does not generate such information by default, and you must add INHERIT += "create-spdx" from a configuration file. If your SBOM procedure does not pin the release and record the inheritance state, a reader cannot tell whether a missing SBOM means “not generated” or “generated elsewhere.”
SPDX itself is an international open standard, ISO/IEC 5962:2021, with version 3.0 current and earlier versions (2.3, 2.2, 2.1, and so on) documented on the SPDX specifications page. Record which document version your tooling emits. A reviewer comparing two submissions from the same product line should not have to guess.
Why one artifact, two audiences
CISA describes an SBOM as “a nested inventory, a list of ingredients that make up software components” (CISA SBOM page). NTIA’s 2021 minimum-elements report defines it as “a formal record containing the details and supply chain relationships of various components used in building software” (NTIA, July 12, 2021). Neither definition is about licenses or about vulnerabilities specifically. Both are about inventory and relationships. That is the common substrate.
The Yocto manual is explicit that the same artifact serves the license purpose: “The SBOM tooling is often used to ensure open source license compliance by providing the license texts used in the product which legal departments and end users can read in standardized format.” It is also explicit that the artifact serves vulnerability work: “SBOM information is also critical to performing vulnerability exposure assessments, as all the components used in the Software Supply Chain are listed.”
So the practical argument is this: do not build two inventories. Build one, and reconcile it twice against two different question sets. Duplicating the work creates drift — the license spreadsheet and the cybersecurity attachment diverge the first time someone adds a recipe and updates only one of them.
What Section 524B adds, and what I can and cannot confirm
FDA’s guidance page for Cybersecurity in Medical Devices: Quality System Considerations and Content of Premarket Submissions states that the document “addresses FDA’s recommendations regarding section 524B of the FD&C Act for cyber devices,” and that it supersedes the final guidance issued June 27, 2025 (FDA guidance landing page). That is the limit of what I retrieved from FDA directly.
I could not retrieve the statutory text of 21 U.S.C. §360n-2 in this pass, and the FDA page I retrieved is a landing page, not the guidance body. So I am not going to state here what the statute’s SBOM clause requires word for word, what format FDA accepts, or what happens to a submission that omits an SBOM. Those are exactly the claims that secondary summaries assert confidently and that a submission team should verify against the current guidance PDF and the statute before relying on them. Treat any blog post — including this one — as a pointer to the primary document, not a substitute.
What I can say with confidence is narrower and still useful: the SBOM you generate for license compliance and the SBOM you attach to a premarket file should be the same underlying inventory, and the reconciliation discipline described below is what makes that possible regardless of how the regulatory text is finally read.
Reconciliation step 1: inventory completeness
The image SBOM covers recipes involved in the image build. That sentence contains the scope boundary, and the boundary is where submissions get into trouble.
Ask, explicitly, what is not a recipe in your image build:
- Bootloader stages built outside the image recipe. If your first-stage loader is a vendor binary dropped into the deploy directory, it is not a recipe and will not appear as a component with a license and source reference.
- Prebuilt firmware blobs for Wi-Fi, Bluetooth, or a modem, shipped as binary-only packages.
- Host tools used to produce the image. The manual distinguishes host tools from target packages in the context of the
SPDX_INCLUDE_SOURCESandSPDX_INCLUDE_COMPILED_SOURCESoptions; whether host tools belong in your submission inventory is a decision you should document, not a default you should assume. - Device tree sources and overlays that are patched in outside a recipe, or generated at build time by a script.
- Early userspace — initramfs contents, if your initramfs is assembled by a mechanism that does not surface as recipes in the image SBOM.
None of these are exotic. All of them are the kind of component that a binary-level audit finds and a build-time SBOM misses. The reconciliation output for this step is not a corrected SBOM; it is a written scope statement: “The image SBOM covers recipes in the image build. The following components are outside that scope and are inventoried separately: [list].” That statement is what a reviewer needs in order to trust the JSON.
Reconciliation step 2: license texts and source access
The SBOM carries license information per component. That is necessary and not sufficient for GPL compliance, because the obligation that matters in enforcement is source access, not license identification.
The 5.1-tip Yocto documentation is direct about this. It describes SPDX_ARCHIVE_SOURCES as producing compressed archives of the source files used to build host tools and target packages, and states: “Those are needed to fulfill ‘source code access’ license requirements.” That is the build system telling you which switch connects the SBOM to the obligation.
So the reconciliation question for each GPL- or LGPL-licensed component in the image is: can I produce the corresponding source, including the modifications, from the same build that produced the binary? If the answer depends on a developer’s workstation or a vendor portal, the SBOM is documenting an obligation you cannot currently discharge. The documented enforcement cases turn on exactly this gap — the binary shipped, the source offer was incomplete or absent. The SBOM’s job is to make that gap visible before shipment, not after a letter arrives.
Two practical checks:
- For every component whose SPDX license field indicates a copyleft license, confirm a source archive exists and is retrievable by someone who is not the build engineer.
- Confirm the archive corresponds to the binary in the image, not to a nearby tag. The manual’s description of the SBOM includes “the changes that were applied to them” — patches are part of the source you owe.
Reconciliation step 3: provenance and traceability
An SBOM that lists components but cannot say who supplied them or which build produced them is a static file. The create-spdx class offers fields that turn it into an auditable record:
SPDX_IMAGE_SUPPLIER,SPDX_SDK_SUPPLIER, andSPDX_PACKAGE_SUPPLIERattach supplier information to the image SBOM, SDK SBOM, or individual packages.SPDX_INCLUDE_BITBAKE_PARENT_BUILD,SPDX_INVOKED_BY, andSPDX_ON_BEHALF_OFrecord which agent invoked the build and on whose behalf it ran, for CI/CD traceability.- PURL enrichment for language ecosystems is available through the
cargo_common,go-mod,pypi,npm, andcpanclasses. SPDX_INCLUDE_KERNEL_CONFIGexports the kernelCONFIG_*parameters into the document.
All of these are documented in the Yocto manual cited above. My recommendation, clearly labeled as such: turn on supplier and build-invocation fields from the first prototype build, not the first submission build. Retrofitting provenance onto a year of builds is expensive; carrying it from the start is nearly free. The kernel config export is worth enabling for a different reason — it lets a reviewer see which drivers and subsystems are compiled in, which is often the fastest way to spot a component that should have appeared in the inventory and did not.
Reconciliation step 4: the SBOM as a living input
A one-time export at release is a snapshot. The useful discipline is regenerating the SBOM per build and diffing it, so that component changes appear as deltas. This matters for both audiences. For the license reviewer, a new recipe with a copyleft license should trigger a source-archive check the day it lands, not the week before submission. For the vulnerability reviewer, the component list is the input to monitoring — if the list is stale, the monitoring is watching the wrong software.
The diff does not need to be elaborate. Two SPDX JSON documents, a component-level comparison, and a short changelog entry per build is enough to answer “what changed since the last reviewed state.” The value is in the habit, not the tooling.
A hypothetical reconciliation worksheet
The following is a template, not a record of a real device or a real finding. It shows how a team would log the gaps between what the build emitted and what the two reviewers need.
| Check | Source of truth | Pass condition | Gap log entry |
|---|---|---|---|
| Image SBOM generated for the release build | IMAGE-MACHINE.spdx.json in tmp/deploy/images/MACHINE/ |
File exists; SPDX document version recorded; Yocto release and create-spdx inheritance state recorded |
“SBOM absent — inheritance state unknown for this release” |
| Every copyleft component has a retrievable source archive | SPDX license fields plus SPDX_ARCHIVE_SOURCES output |
Archive exists and matches the binary’s patches | “Component X: license identified, source archive not produced” |
| Components outside recipe scope are inventoried separately | Written scope statement | Each out-of-scope component listed with supplier and version | “Bootloader stage 1: vendor binary, no recipe, no source reference” |
| Supplier and build-invocation fields populated | SPDX_*_SUPPLIER, SPDX_INVOKED_BY, SPDX_ON_BEHALF_OF |
Fields present and non-empty | “Supplier field empty for N packages” |
| SBOM diffed against previous reviewed build | Two SPDX JSON documents | Every added or removed component has a disposition | “New recipe added; license review pending” |
Each row maps to a question one of the two reviewers will ask. The worksheet is the bridge between the generated file and the submission package.
What this does not solve
Two honest limitations. First, a build-time SBOM describes the build, not the deployed image. If the flash image on the prototype differs from the build output — a debug rootfs, a patched kernel, a vendor blob swapped in during manufacturing — the SBOM is describing something else. Closing that gap requires extracting the deployed firmware and comparing it against the build inventory, which is a separate exercise from generating the SBOM and should be scheduled as one.
Second, the regulatory specifics are outside what I could verify here. The FDA landing page confirms that the guidance addresses Section 524B recommendations and supersedes the June 27, 2025 final guidance. It does not, in the retrieved text, tell you the required SBOM format or the consequences of omission. Read the guidance body and the statute before you write your submission procedure, and cite them in your procedure rather than citing a blog post.
FAQ
Does my Yocto build generate an SBOM automatically?
It depends on the release. The 6.1-tip documentation says SBOM generation is on by default via create-spdx in INHERIT_DISTRO. The 5.1-tip documentation says it is off by default and requires INHERIT += "create-spdx". Check your release’s documentation and record the inheritance state in your procedure.
Where does the image SBOM land?
As IMAGE-MACHINE.spdx.json under tmp/deploy/images/MACHINE/ in the Build Directory, per the Yocto Development Tasks Manual.
Can I generate an SBOM for a single recipe?
Yes: bitbake <recipe> -c create_recipe_sbom generates it from recipe metadata. The manual notes that recipe SBOMs are included in the image SBOM only for recipes involved in the image build.
Does the SBOM satisfy GPL source obligations by itself?
No. The SBOM identifies licenses and components. Source access is a separate obligation, and the Yocto documentation points to SPDX_ARCHIVE_SOURCES as producing the archives “needed to fulfill ‘source code access’ license requirements.” Whether those archives are complete and retrievable is a reconciliation check, not a build default.
Is SPDX the format FDA requires?
I could not confirm that from the retrieved FDA page, which is a guidance landing page rather than the guidance body. SPDX is an ISO/IEC 5962:2021 standard and is what the OpenEmbedded build system emits, but do not infer FDA acceptance from that. Verify against the current guidance document.
What about components that are not recipes?
They will not appear in the image SBOM. Inventory them separately and document the scope boundary explicitly, so a reviewer can tell the difference between “not present” and “not covered.”