How to Generate a CRA-Compliant SBOM: Tools, Formats, and CI/CD Integration
A hands-on guide to generating Software Bills of Materials for CRA compliance. Covers open-source tools, format selection, and automated pipeline integration.
In this article
The CRA requires a Software Bill of Materials. Every competitor article tells you this. None show you how to generate one.
This guide covers open-source tools, format selection, and CI/CD integration with no vendor lock-in required.
Tip: Start with Syft or Trivy for SBOM generation — both support CycloneDX and SPDX output and integrate easily into CI/CD pipelines.
Summary
- CRA requires machine-readable SBOMs covering "at least top-level dependencies"
- Recommended formats: CycloneDX 1.4+ or SPDX 2.3+ (per BSI TR-03183)
- Open-source tools: Syft (images/filesystems), Trivy (containers), cdxgen (source code)
- Integrate SBOM generation into CI/CD for automatic updates
- Quality matters: minimum fields include package name, version, supplier, hash, license
Important: The CRA requires machine-readable SBOMs covering all transitive dependencies. A simple package.json or requirements.txt is NOT sufficient.
What the CRA Actually Requires
Let's start with what the regulation says. Annex I, Part II of the CRA requires manufacturers to:
"identify and document vulnerabilities and components contained in the product, including by drawing up a software bill of materials in a commonly used and machine-readable format"
Key points:
- Machine-readable format: Not a PDF, not a spreadsheet, but structured data
- At least top-level dependencies: The minimum scope, though more is better
- Not required to be public: Provided to authorities on request
- Must be updated: With each release, patch, or component change
The CRA doesn't mandate a specific format, but standardization efforts point clearly to CycloneDX and SPDX.
Format Selection: CycloneDX vs SPDX
Two formats dominate the SBOM landscape. Both are acceptable for CRA compliance.
CycloneDX
Origin: OWASP project, security-focused Current version: 1.6 (1.4+ recommended for CRA) Best for: Security and vulnerability management
Strengths:
- Native VEX (Vulnerability Exploitability eXchange) support
- Designed for security use cases
- Lighter specification, easier to implement
- Strong tooling ecosystem
- Direct CVE/vulnerability linking
JSON example:
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "lodash",
"version": "4.17.21",
"purl": "pkg:npm/lodash@4.17.21",
"hashes": [
{
"alg": "SHA-256",
"content": "cc6d..."
}
],
"licenses": [
{
"license": {
"id": "MIT"
}
}
]
}
]
}
SPDX
Origin: Linux Foundation, license compliance-focused Current version: 2.3 (ISO/IEC 5962:2021 standard) Best for: License compliance and legal review
Strengths:
- ISO international standard
- Comprehensive license expression syntax
- Strong in open source compliance contexts
- Longer track record
- Better for complex licensing scenarios
JSON example:
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "my-application",
"packages": [
{
"SPDXID": "SPDXRef-Package-lodash",
"name": "lodash",
"versionInfo": "4.17.21",
"downloadLocation": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"licenseConcluded": "MIT",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "cc6d..."
}
]
}
]
}
Which to Choose?
| Use Case | Recommendation |
|---|---|
| Primary focus is security/vulnerabilities | CycloneDX |
| Primary focus is license compliance | SPDX |
| Need VEX integration | CycloneDX |
| Enterprise with existing SPDX tooling | SPDX |
| German market (BSI TR-03183) | Either (both recommended) |
| Starting fresh, no preference | CycloneDX (simpler, security-focused) |
For CRA compliance, either format works. Pick one and be consistent.
Open-Source SBOM Generation Tools
No vendor lock-in required. These tools are free, open-source, and production-ready.
Syft (Anchore)
Best for: Container images, filesystems, archives License: Apache 2.0 Output formats: CycloneDX, SPDX, Syft JSON
Installation:
# Linux/macOS
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# Homebrew
brew install syft
# Docker
docker pull anchore/syft
Usage examples:
# Scan a container image
syft alpine:latest -o cyclonedx-json > sbom.cdx.json
# Scan a directory
syft dir:/path/to/project -o cyclonedx-json > sbom.cdx.json
# Scan an archive
syft /path/to/archive.tar.gz -o spdx-json > sbom.spdx.json
# Scan with specific catalogers (e.g., only Python)
syft dir:. -o cyclonedx-json --select-catalogers python
Supported ecosystems: Python, Node.js, Ruby, Java, Go, Rust, PHP, .NET, and more.
Trivy (Aqua Security)
Best for: Container images with built-in vulnerability context License: Apache 2.0 Output formats: CycloneDX, SPDX, plus vulnerability reports
Installation:
# Linux (Debian/Ubuntu)
sudo apt-get install trivy
# macOS
brew install trivy
# Docker
docker pull aquasec/trivy
Usage examples:
# Generate SBOM from container image
trivy image --format cyclonedx --output sbom.cdx.json alpine:latest
# Generate SBOM from filesystem
trivy fs --format cyclonedx --output sbom.cdx.json /path/to/project
# Generate SBOM with vulnerability info
trivy image --format cyclonedx --output sbom.cdx.json \
--scanners vuln nginx:latest
Advantage: Trivy can generate SBOMs and scan for vulnerabilities in one pass.
cdxgen (CycloneDX)
Best for: Source code analysis across many languages License: Apache 2.0 Output format: CycloneDX
Installation:
# npm (requires Node.js)
npm install -g @cyclonedx/cdxgen
# Docker
docker pull ghcr.io/cyclonedx/cdxgen
Usage examples:
# Scan current directory
cdxgen -o sbom.json
# Scan specific project type
cdxgen -t python -o sbom.json
# Scan with deep dependency resolution
cdxgen --deep -o sbom.json
# Scan a specific directory
cdxgen -o sbom.json /path/to/project
Supported languages: JavaScript, Python, Java, Go, Rust, PHP, Ruby, .NET, C/C++, and more.
Tool Comparison
| Feature | Syft | Trivy | cdxgen |
|---|---|---|---|
| Container images | Excellent | Excellent | Good |
| Source code | Good | Good | Excellent |
| Filesystem scan | Excellent | Good | Good |
| Vulnerability scanning | No (use Grype) | Yes | No |
| CycloneDX output | Yes | Yes | Yes |
| SPDX output | Yes | Yes | No |
| Speed | Fast | Medium | Medium |
| Language coverage | Very broad | Broad | Very broad |
Recommendation: Start with Syft for most use cases. Add Trivy if you need integrated vulnerability scanning. Use cdxgen for complex source code projects.
CI/CD Integration
Manual SBOM generation doesn't scale. Integrate it into your build pipeline.
GitHub Actions
name: SBOM Generation
on:
push:
branches: [main]
release:
types: [published]
jobs:
sbom:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Syft
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
- name: Generate SBOM
run: |
syft dir:. -o cyclonedx-json > sbom.cdx.json
- name: Upload SBOM as artifact
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.cdx.json
retention-days: 90
# Optional: Upload to CRA Evidence
- name: Upload to CRA Evidence
if: github.event_name == 'release'
env:
CRA_EVIDENCE_TOKEN: ${{ secrets.CRA_EVIDENCE_TOKEN }}
run: |
curl -X POST https://app.craevidence.com/api/v1/ci/sbom \
-H "Authorization: Bearer $CRA_EVIDENCE_TOKEN" \
-F "file=@sbom.cdx.json" \
-F "product_id=${{ vars.PRODUCT_ID }}" \
-F "version=${{ github.ref_name }}"
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
rules:
- if: $CI_COMMIT_BRANCH == "main"
- if: $CI_COMMIT_TAG
Jenkins
pipeline {
agent any
stages {
stage('Generate SBOM') {
steps {
sh '''
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b .
./syft dir:. -o cyclonedx-json > sbom.cdx.json
'''
}
}
stage('Archive SBOM') {
steps {
archiveArtifacts artifacts: 'sbom.cdx.json', fingerprint: true
}
}
}
}
Docker Build Integration
Generate SBOM during Docker build:
# Multi-stage build with SBOM generation
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Generate SBOM in build stage
FROM anchore/syft:latest AS sbom
COPY --from=builder /app /app
RUN syft dir:/app -o cyclonedx-json > /sbom.cdx.json
# Final image
FROM node:20-slim
COPY --from=builder /app/dist /app
COPY --from=sbom /sbom.cdx.json /app/sbom.cdx.json
CMD ["node", "/app/index.js"]
SBOM Quality: Meeting TR-03183
The German BSI Technical Guideline TR-03183 extends the NTIA minimum elements. While not legally required across the EU, following TR-03183 ensures high-quality SBOMs.
Required Fields
| Field | Required By | Notes |
|---|---|---|
| Component name | NTIA + TR-03183 | Package identifier |
| Version | NTIA + TR-03183 | Exact version string |
| Supplier | NTIA + TR-03183 | Vendor or maintainer |
| Unique identifier | NTIA + TR-03183 | PURL recommended |
| Dependency relationship | NTIA + TR-03183 | Direct vs transitive |
| Author of SBOM | NTIA + TR-03183 | Who created the SBOM |
| Timestamp | NTIA + TR-03183 | When SBOM was created |
| Hash values | TR-03183 | SHA-256 minimum |
| License | TR-03183 | SPDX license ID |
| Source repository | TR-03183 | VCS URL if available |
Validating SBOM Quality
Use these tools to check your SBOM:
# Validate CycloneDX format
npm install -g @cyclonedx/cyclonedx-cli
cyclonedx validate --input-file sbom.cdx.json
# Check for minimum fields with jq
jq '.components[] | select(.version == null or .purl == null)' sbom.cdx.json
# Count components with hashes
jq '[.components[] | select(.hashes != null)] | length' sbom.cdx.json
Improving SBOM Quality
If your SBOM is missing data:
- Use lock files:
package-lock.json,Pipfile.lock,go.sumcontain more metadata - Scan built artifacts: More complete than source-only scans
- Combine tools: Different tools find different components
- Add manual entries: For commercial or internal components
Keeping SBOMs Current
An SBOM is a snapshot. It must be updated to remain useful.
When to Regenerate
- Every release (major, minor, patch)
- After dependency updates
- After security patches
- When build configuration changes
Versioning Strategy
product-v1.0.0-sbom.cdx.json
product-v1.0.1-sbom.cdx.json
product-v1.1.0-sbom.cdx.json
Or use timestamps:
product-sbom-2026-01-15T10-30-00Z.cdx.json
Retention
The CRA requires 10-year retention. Store historical SBOMs:
- In your artifact repository
- In S3/cloud storage with lifecycle policies
- In CRA Evidence for integrated compliance tracking
Common Pitfalls
One-time SBOM generation
Problem: Creating an SBOM once and never updating it.
Solution: Automate SBOM generation in CI/CD. Every build should produce a fresh SBOM.
Missing transitive dependencies
Problem: SBOM only lists direct dependencies, missing nested packages.
Solution: Use lock files, scan built artifacts, enable deep scanning options.
Wrong format version
Problem: Using CycloneDX 1.3 when TR-03183 recommends 1.4+.
Solution: Check your tool's output version. Update tools regularly.
No hash values
Problem: Components without cryptographic hashes can't be verified.
Solution: Ensure your tool includes hashes. Scan built artifacts rather than just source.
Manual creation
Problem: Hand-crafting SBOMs is error-prone and unsustainable.
Solution: Always automate. Manual entries only for components tools can't detect.
Ignoring internal components
Problem: Only documenting open-source dependencies, not proprietary code.
Solution: Internal components need documentation too. Add them manually or configure tools appropriately.
SBOM Implementation Checklist
SBOM IMPLEMENTATION CHECKLIST
FORMAT SELECTION:
[ ] CycloneDX 1.4+ or SPDX 2.3+ chosen
[ ] JSON format (machine-readable)
[ ] Decision documented
TOOLING:
[ ] Primary tool selected (Syft/Trivy/cdxgen)
[ ] Tool installed and tested locally
[ ] Output validated against schema
CI/CD INTEGRATION:
[ ] SBOM generation added to build pipeline
[ ] Artifacts stored with appropriate retention
[ ] Generation triggered on releases
QUALITY ASSURANCE:
[ ] All components have: name, version, supplier
[ ] Hash values present (SHA-256+)
[ ] License information included
[ ] Transitive dependencies captured
[ ] PURL identifiers used
OPERATIONS:
[ ] SBOM versioned alongside product releases
[ ] Historical SBOMs archived (10-year retention)
[ ] Process documented for team
OPTIONAL - CRA EVIDENCE INTEGRATION:
[ ] API token configured
[ ] Upload automated on release
[ ] Quality scoring enabled
Next Steps
With SBOM generation automated, you're ready for:
- Vulnerability scanning: Connect SBOMs to vulnerability databases
- License compliance: Analyze license obligations
- Technical file integration: Include SBOMs in CRA documentation
- ENISA reporting preparation: SBOMs enable rapid vulnerability identification
CRA Evidence automates this entire workflow:
- Upload SBOMs via CLI or CI/CD
- Automatic vulnerability scanning with Trivy
- TR-03183 quality scoring
- Technical file export with integrated SBOMs
Start generating compliant SBOMs at app.craevidence.com.
Requirements: Understand what the CRA requires for SBOMs in our SBOM requirements guide.
Quality: Validate your SBOM against the BSI TR-03183 standard.
VEX: Add vulnerability context to your SBOM with VEX documents.
This article is for informational purposes only and does not constitute legal advice. For specific compliance guidance, consult with qualified legal counsel familiar with EU product regulations.
Related Articles
Are Smart Cameras Important Products Under the EU Cyber...
Smart security cameras are classified as Important Products (Class I) under...
9 minEU Cybersecurity Act 2: Supply Chain Bans, Certification...
On January 20, 2026, the EU proposed replacing the Cybersecurity Act...
10 minCRA Product Classification: Is Your Product Default,...
A practical guide to determining your product's CRA category. Includes...
11 minDoes the CRA apply to your product?
Answer 6 simple questions to find out if your product falls under the EU Cyber Resilience Act scope. Get your result in under 2 minutes.
Ready to achieve CRA compliance?
Start managing your SBOMs and compliance documentation with CRA Evidence.