A Software Bill of Materials (SBOM) is a complete inventory of all components, libraries, and dependencies in software. This comprehensive guide covers everything you need to know about SBOMs.
What is an SBOM?
An SBOM is a formal record of the software components and their dependencies.
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-Package",
"name": "my-application",
"documentNamespace": "https://example.com/my-app",
"creationInfo": {
"created": "2026-02-27T00:00:00Z",
"creators": ["Tool: spdx-sbom-generator"]
},
"packages": [
{
"SPDXID": "SPDXRef-Package-npm-react-18.2.0",
"name": "react",
"version": "18.2.0",
"supplier": "Organization: Meta",
"downloadLocation": "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
}
]
}
Why SBOM?
- Security - Identify vulnerabilities quickly
-
- Compliance - Track licenses
-
- Transparency - Know your dependencies
-
- Supply Chain - Provenance tracking
-
- Regulation - Executive Order compliance
SBOM Formats
SPDX (Software Package Data Exchange)
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "my-application",
"documentNamespace": "https://example.com/spdx",
"creationInfo": {
"created": "2026-02-27T10:00:00Z",
"creators": [
"Tool: spdx-sbom-generator v1.0.0",
"Organization: Acme Corp"
]
},
"packages": [
{
"SPDXID": "SPDXRef-Package-npm-react-18.2.0",
"name": "react",
"versionInfo": "18.2.0",
"packageFileName": "react-18.2.0.tgz",
"supplier": "Organization: Meta Platforms, Inc.",
"downloadLocation": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
"filesAnalyzed": false,
"externalRefs": [
{
"referenceCategory": "SECURITY",
"referenceType": "cpe22Type",
"referenceLocator": "cpe:2.3:a:meta:react:18.2.0:*:*:*:*:*:*:*:*"
}
]
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relationshipType": "DESCRIBES",
"relatedSpdxElement": "SPDXRef-Package-myapp"
},
{
"spdxElementId": "SPDXRef-Package-myapp",
"relationshipType": "DEPENDENCY_OF",
"relatedSpdxElement": "SPDXRef-Package-npm-react-18.2.0"
}
]
}
CycloneDX
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.5" serialNumber="bom-123">
<metadata>
<timestamp>2026-02-27T10:00:00Z</timestamp>
<tools>
<tool>
<name>syft</name>
<version>1.0.0</version>
</tool>
</tools>
<component type="application">
<name>my-application</name>
<version>1.0.0</version>
</component>
</metadata>
<components>
<component type="library">
<name>react</name>
<version>18.2.0</version>
<purl>pkg:npm/[email protected]</purl>
<supplier>
<name>Meta Platforms, Inc.</name>
</supplier>
</component>
</components>
<dependencies>
<dependency ref="pkg:npm/[email protected]">
<dependency ref="pkg:npm/scheduler"/>
</dependency>
</dependencies>
</bom>
Package URL (purl)
{
"purl": "pkg:npm/[email protected]"
}
{
// Components of purl
"type": "npm", // Package type
"namespace": null, // Optional namespace
"name": "react", // Package name
"version": "18.2.0", // Version
"subpath": null, // Optional subpath
"qualifiers": {}, // Optional qualifiers
"comment": null // Optional comment
}
Generation Tools
Syft
# Install Syft
brew install syft
# Scan directory (auto-detects package manager)
syft my-project/
# Generate SPDX
syft my-project/ -o spdx
# Generate CycloneDX
syft my-project/ -o cyclonedx-json
# Scan container image
syft docker:myimage:latest
# Scan from container archive
syft docker-archive:myimage.tar
# Scan with SBOM input (for chaining)
syft my-project/ -o syft-json | grype sbom:
SPDX SBOM Generator
# Install
npm install -g @spdx/spdx-sbom-generator
# Generate
spdx-sbom-generator -o output.spdx.json
npm / Yarn / pnpm
# npm
npm install -g @aspect/sbom
sbom npm
# Yarn
sbom yarn
# pnpm
sbom pnpm
Integration Examples
GitHub Actions
name: SBOM Generation
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
sbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
format: spdx-json
output-file: sbom.spdx.json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.spdx.json
GitLab CI
stages:
- sbom
sbom:
stage: sbom
image: docker:latest
services:
- docker:dind
script:
- |
# Install Syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh
# Generate SBOM
syft . -o cyclonedx-json > sbom.json
# Upload as artifact
curl --header "JOB-TOKEN: $CI_JOB_TOKEN" \
--upload-file sbom.json \
"$CI_API_V4_URL/projects/$CI_PROJECT_ID/jobs/artifacts/main/file?sbom.json"
Vulnerability Scanning
Grype
# Install Grype
brew install grype
# Scan from SBOM
grype sbom:sbom.spdx.json
# Scan directory
grype directory:my-project/
# Scan container image
grype docker:myimage:latest
# Filter by severity
grype my-project/ --severity Critical,High
# Update vulnerability database
grype db update
Trivy
# Install Trivy
brew install trivy
# Scan with SBOM
trivy sbom --format spdx-json sbom.spdx.json
# Scan container image
trivy image myimage:latest
# Scan filesystem
trivy fs .
Example Workflow
name: Security Scan
on:
push:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
format: spdx-json
output-file: sbom.spdx.json
- name: Scan vulnerabilities
uses: anchore/scan-action@v3
with:
sbom: sbom.spdx.json
severity: Critical,High
Best Practices
Generate SBOM Automatically
# Always generate SBOM on every build
on:
push:
branches: [main]
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: npm ci && npm run build
- name: Generate SBOM
run: syft . -o cyclonedx-json > sbom.json
- name: Upload SBOM
run: |
# Upload to release or registry
# Store for security scanning
Store SBOMs
# Store alongside artifacts
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.spdx.json
# Or in registry
- name: Publish SBOM
run: |
# Publish to SBOM registry
# e.g., GitHub Advisory Database, Dependency Track
Monitor Dependencies
# Check for outdated dependencies
npm outdated
# Audit for vulnerabilities
npm audit
# Check license compliance
npx license-checker --summary
SBOM Management
Dependency Track
# docker-compose.yml
version: '3'
services:
postgres:
image: postgres:15
environment:
POSTGRES_DB: dtrack
POSTGRES_PASSWORD: admin
POSTGRES_USER: admin
dtrack:
image: owasp/dependency-track
ports:
- "8080:8080"
depends_on:
- postgres
environment:
- DATABASE_URL=postgres://admin:admin@postgres:5432/dtrack
# Upload SBOM via API
curl -X POST \
-H "Authorization: ApiKey YOUR_API_KEY" \
-F "[email protected]" \
https://dtrack.example.com/api/v1/bom
External Resources
Conclusion
SBOMs are essential for software supply chain security. Key points:
- Generate SBOMs automatically in CI/CD
- Use standard formats (SPDX, CycloneDX)
- Scan for vulnerabilities regularly
- Store SBOMs alongside releases
- Track license compliance
With increasing regulation, SBOMs are becoming required for many software products.
Comments