CycloneDX SBOM and VEX Export¶
Automatic generation of Software Bill of Materials (SBOM) and Vulnerability Exploitability eXchange (VEX) documents during image builds.
Table of Contents¶
- CycloneDX SBOM and VEX Export
- Table of Contents
- Quick Start
- What is an SBOM?
- Architecture Overview
- Kernel CVE Enrichment
- Setting Up Your Company Supplier Information
- Troubleshooting
Quick Start¶
After building an image, SBOM, VEX, and summary files are automatically generated under the build directory:
build/tmp/deploy/cyclonedx-export/<machine>/<image>
├── bom.json # Software Bill of Materials (SBOM)
├── vex.json # Vulnerability Exploitability eXchange (VEX)
└── summary.json # Human-readable statistics and per-recipe breakdown
View the SBOM:
The bom.json file is generated in CycloneDX 1.6 format and can be uploaded to ToloMEO or shared with customers.
Note: Packages with DAVE as supplier can receive updates because they are maintained by DAVE. If you require pinned versions, contact DAVE.
What is an SBOM?¶
A Software Bill of Materials (SBOM) is a complete inventory of all software components in your image, including:
- Package names and versions
- Licenses
- Known vulnerabilities (CVEs)
- Component suppliers/manufacturers
This is useful for:
- Security audits and compliance
- License tracking
- Vulnerability management
- Supply chain transparency
Architecture Overview¶
The CycloneDX export is implemented as three cooperating bbclasses, all activated by a single require in the distro configuration:
| Class | Scope | What it does |
|---|---|---|
cyclonedx_collect |
Every recipe | Runs after do_cve_check; writes a per-recipe JSON blob containing metadata, CPE IDs, dependency lists, and all Patched/Ignored CVEs |
cyclonedx_assemble |
Image recipes | Runs after do_rootfs; reads all per-recipe blobs, propagates suppliers, and writes bom.json, vex.json, and summary.json |
Kernel CVE Enrichment¶
When meta-vulnscout is available, kernel CVE analysis is performed at three levels:
kernel_generate_cve_exclusions— generates acve-extra-exclusions.incfile listing kernel CVEs that are architecturally not applicable.kernel_filter_nonbuilt_cves— cross-references CVEs with the compiled source file list (SPDX_INCLUDE_COMPILED_SOURCES) to mark CVEs for source files not built into this kernel image asIgnored.improve_kernel_cve_report— image-level post-rootfs scout that re-classifies kernel CVEs using thevulns.gitdataset and produces a.scouted.jsonfile.
cyclonedx_collect automatically detects when kernel_filter_nonbuilt_cves is inherited and
sequences itself after it, so the modified _cve.json is ready before CVE collection runs.
The assemble class automatically picks up the .scouted.json from step 3 when
CYCLONEDX_KERNEL_SCOUTED_FILE is set. No extra class is needed beyond the meta-vulnscout
classes themselves.
To enable kernel CVE enrichment, add to the kernel recipe .bbappend:
And in the distro configuration:
INHERIT += "improve_kernel_cve_report"
SPDX_INCLUDE_COMPILED_SOURCES:pn-linux-yocto = "1"
CYCLONEDX_KERNEL_SCOUTED_FILE = "${IMGDEPLOYDIR}/${IMAGE_NAME}.scouted.json"
Setting Up Your Company Supplier Information¶
The meta-tolomeo layer includes DAVE Embedded Systems as a pre-configured supplier. If you use this layer in your own build, add your company supplier information so that your custom packages are correctly attributed in the SBOM.
Step 1: Define Your Company as a Supplier¶
Create or edit your distro configuration file (e.g., conf/distro/my-distro.conf):
# Define your company supplier information
CDX_SUPPLIER_MAP[mycompany.name] = "My Company Name"
CDX_SUPPLIER_MAP[mycompany.urls] = "https://www.mycompany.com https://gitlab.com/mycompany"
Step 2: Assign Your Supplier to Your Packages¶
For each recipe you create or customize, add the supplier assignment:
There is no need to set the supplier for all dependencies; it is automatically propagated.
Step 3: Set a Default Supplier (Recommended)¶
To ensure all components in your SBOM have a supplier assigned, set a default supplier in your distro configuration:
# Set default supplier for components without explicit assignment
CDX_DEFAULT_COMPONENT_SUPPLIER = "mycompany"
This will automatically assign your company as the supplier for any components that don't have a supplier after the automatic propagation process. This is particularly useful for:
- Third-party open-source components that you integrate
- Components that aren't part of DAVE's managed packages
- Ensuring complete supplier coverage in your SBOM
When to use this:
- Recommended for production builds: Ensures every component has a supplier, which is often required for compliance and security audits
- Skip during development: Leave it unset if you want to see which components lack explicit supplier assignments
Example output when set:
Assigned default supplier 'mycompany' to 47 recipes without explicit supplier:
- busybox
- glibc
- openssl
...
Step 4: Assign Your Supplier to Specific Packages¶
If you want to override suppliers for specific packages in your distro configuration without the need to directly append to an already existing recipe:
# In your distro config
CDX_COMPONENT_SUPPLIER:pn-my-custom-app = "mycompany"
CDX_COMPONENT_SUPPLIER:pn-my-custom-lib = "mycompany"
Automatic Supplier Propagation¶
The supplier assignment system works in a hierarchical manner:
- Explicit assignments (highest priority): Suppliers set directly on recipes via
CDX_COMPONENT_SUPPLIER - Propagated suppliers: Suppliers automatically propagated from dependencies
- Default supplier (lowest priority): Applied to remaining components via
CDX_DEFAULT_COMPONENT_SUPPLIER
Propagation rules:
- When you assign a supplier to a package, it automatically propagates to all its dependencies
- DAVE-assigned packages have the highest priority and override other assignments
- Your custom suppliers propagate to dependencies unless they already have a supplier assigned
Example:
If your custom packagegroup-myapp has supplier mycompany, all packages it depends on will also
be marked as mycompany (unless they already have a different supplier assigned, such as DAVE
packages).
This means you only need to assign suppliers to your top-level packages—the system handles the rest.
Troubleshooting¶
SBOM file is missing¶
Make sure the build completed successfully. The SBOM is generated at the end of the build process.
My packages don't show my company as the supplier¶
Check that:
- You've defined your supplier in
CDX_SUPPLIER_MAPwith bothnameandurls - You've assigned
CDX_COMPONENT_SUPPLIER = "mycompany"to your recipes - Your distro configuration includes the supplier definition file
- The package you are trying to include is not already under DAVE's dependencies (DAVE suppliers have highest priority)
Some packages don't have a supplier assigned¶
If you see warnings about packages without suppliers during the build:
WARNING: The following 47 recipes in the SBOM do not have a supplier assigned:
- busybox
- glibc
...
TIP: You can set CDX_DEFAULT_COMPONENT_SUPPLIER to automatically assign a default supplier to these components.
Solution:
Add a default supplier to your distro configuration:
This will automatically assign your company as the supplier for all components that don't have one after the propagation process.
Alternative approach:
If you prefer to explicitly control which packages get your supplier, you can:
- Review the warning list
- Assign
CDX_COMPONENT_SUPPLIERto specific top-level packages - Let propagation handle their dependencies
I want to use a different SBOM format¶
By default, CycloneDX 1.6 format is used. To use the older 1.4 format for compatibility with older tools, add to your distro configuration: