A Software Bill of Materials (SBOM) is a formal, machine-readable inventory of all software components in a product — including open-source libraries, third-party dependencies, and the relationships between them. Think of it as a nutrition label for software: a structured declaration of exactly what's inside.
Until recently, SBOMs were a best practice championed by US federal agencies (particularly after the 2021 Biden Executive Order on Cybersecurity) and security-conscious organisations. From 11 December 2027, they will be a legal requirement for all products subject to the EU Cyber Resilience Act.
This guide walks through everything a development team needs to generate accurate, compliant SBOMs — from choosing a format to integrating generation into your build pipeline.
The Two Major SBOM Standards
Two formats dominate the SBOM landscape. Both are widely accepted for CRA purposes, but they have different strengths:
CycloneDX
CycloneDX was created by OWASP and is optimised for security use cases. It natively supports vulnerability data (VEX — Vulnerability Exploitability eXchange), service dependencies, hardware components, and machine learning models. The current version is 1.6. CycloneDX is typically the better choice for security-focused workflows because it integrates naturally with vulnerability scanners.
SPDX
SPDX (Software Package Data Exchange) is a Linux Foundation standard originally designed for license compliance. Version 2.3 and the newer 3.0 are ISO standards (ISO/IEC 5962:2021). SPDX excels at capturing license information and is the default for many package managers. If your primary concern is license compliance alongside security, SPDX may be the better fit.
Both formats are supported by all major SBOM tooling. For CRA purposes, either is acceptable.
Choosing an SBOM Generation Tool
Several excellent open-source tools can generate SBOMs. The right choice depends on your language ecosystem and workflow:
Generating Your First SBOM with Syft
Syft by Anchore is the most versatile SBOM generator available. It supports over 30 package ecosystems, works on container images, directory trees, and single files, and outputs both CycloneDX and SPDX formats. Here is how to get started:
Installation
# macOS / Linux (one-liner install)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# Verify installation
syft --version
Scan a directory (source code)
# Generate CycloneDX JSON SBOM for a project directory
syft dir:/path/to/your/project -o cyclonedx-json=sbom.cdx.json
# Or SPDX format
syft dir:/path/to/your/project -o spdx-json=sbom.spdx.json
Scan a container image
# Scan a local Docker image
syft myapp:latest -o cyclonedx-json=sbom.cdx.json
# Scan from a registry (no pull required)
syft registry:docker.io/library/nginx:latest -o cyclonedx-json=nginx-sbom.cdx.json
Understanding the Output
A CycloneDX JSON SBOM from Syft looks like this (abbreviated):
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:abc123...",
"version": 1,
"metadata": {
"timestamp": "2025-10-15T09:00:00Z",
"component": {
"name": "my-application",
"version": "2.1.0",
"type": "application"
}
},
"components": [
{
"type": "library",
"name": "express",
"version": "4.18.2",
"purl": "pkg:npm/[email protected]",
"licenses": [{ "license": { "id": "MIT" } }]
}
]
}
CI/CD Integration
For CRA compliance, SBOM generation must happen automatically as part of your build process — not manually on an ad-hoc basis. Here is how to integrate Syft into common CI/CD systems:
GitHub Actions
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
path: .
format: cyclonedx-json
output-file: sbom.cdx.json
upload-artifact: true
GitLab CI
generate-sbom:
stage: build
image: anchore/syft:latest
script:
- syft dir:. -o cyclonedx-json=sbom.cdx.json
artifacts:
paths:
- sbom.cdx.json
expire_in: 90 days
What Makes a Good SBOM?
The CISA SBOM guidance and the NTIA Minimum Elements for an SBOM define quality criteria. For CRA compliance, your SBOMs should meet these standards:
- Complete: Every first-party and third-party component, including transitive dependencies, must be listed. A top-level SBOM without transitive dependencies may not satisfy CRA requirements.
- Accurate PURLs: Each component should have a Package URL (purl) — the standardised identifier used by vulnerability databases to match components to CVEs.
- Versioned: Exact versions, not ranges. "lodash@^4.17.0" is not useful for vulnerability matching; "[email protected]" is.
- Timestamped and signed: The SBOM must be dated (so you know which version of the product it describes) and ideally signed to establish authenticity.
- Machine-readable: JSON or XML format, not PDF. The SBOM must be processable by vulnerability scanners and compliance tools.
From SBOM to Vulnerability Monitoring
Generating an SBOM is only the first step. The real value comes from using it continuously: feeding it into a vulnerability scanner that cross-references your component list against CVE databases like NVD and OSV. When a new vulnerability is published, you need to know — within hours, not weeks — which of your products are affected.
CRATrust automates this entire workflow. Upload your SBOM once, and the platform continuously monitors your component inventory against the latest vulnerability intelligence, alerts you to new findings, and tracks remediation status through to resolution. This is exactly the evidence trail CRA compliance requires.