Introduction to Software Bills of Materials (SBOMs)
Learn what SBOMs are, why they matter for container security, and how to generate them in your Docker workflows.
Software Bills of Materials (SBOMs) have become a critical component of modern software supply chain security. In this post, we'll explore what SBOMs are, why they're essential for container security, and how you can start generating them today.
What is an SBOM?
A Software Bill of Materials (SBOM) is a comprehensive inventory of all software components, libraries, and dependencies used in building a software application. Think of it as an ingredients list for your software - it tells you exactly what went into creating your application.
For containers, an SBOM becomes even more crucial because:
- Containers bundle not just your application code, but entire runtime environments
- Base images contain hundreds of packages and libraries
- Dependencies can be nested multiple layers deep
- Vulnerabilities can exist at any layer of your container stack
Why SBOMs Matter
Vulnerability Management
Without an SBOM, you're flying blind when it comes to vulnerabilities. When a new CVE is announced, you need to know:
- Do any of my containers contain the vulnerable component?
- Which specific versions are affected?
- How quickly can I identify and patch affected systems?
Compliance Requirements
Many industries and government contracts now require SBOMs:
- US Executive Order 14028 mandates SBOMs for federal software
- NTIA minimum elements define what must be included
- Financial services increasingly require supply chain transparency
License Compliance
SBOMs help you track software licenses across your entire stack:
# Example: Finding GPL licenses in your container
syft docker:myapp:latest -o json | jq '.artifacts[] | select(.licenses[]?.value | contains("GPL"))'
Generating SBOMs for Containers
Let's look at practical examples of generating SBOMs using popular tools.
Using Syft
Syft is a popular open-source tool for generating SBOMs:
# Install syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# Generate SBOM for a container image
syft docker:nginx:latest -o spdx-json > nginx-sbom.json
# Generate SBOM for local directory
syft dir:. -o cyclonedx-json > app-sbom.json
Docker Scout Integration
Docker Scout provides built-in SBOM generation:
# Enable Docker Scout
docker scout quickview
# Generate and view SBOM
docker scout sbom nginx:latest
In CI/CD Pipelines
Here's how to integrate SBOM generation into your CI/CD:
# GitHub Actions example
name: Build and Generate SBOM
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build container
run: docker build -t myapp:${{ github.sha }} .
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: myapp:${{ github.sha }}
format: spdx-json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.spdx.json
SBOM Formats
There are several standardized SBOM formats:
SPDX (Software Package Data Exchange)
{
"spdxVersion": "SPDX-2.3",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "myapp-container",
"packages": [
{
"SPDXID": "SPDXRef-Package-nginx",
"name": "nginx",
"versionInfo": "1.21.6",
"downloadLocation": "NOASSERTION"
}
]
}
CycloneDX
{
"bomFormat": "CycloneDX",
"specVersion": "1.4",
"version": 1,
"metadata": {
"component": {
"type": "container",
"name": "myapp"
}
},
"components": [
{
"type": "library",
"name": "openssl",
"version": "1.1.1f"
}
]
}
Best Practices
1. Generate SBOMs at Build Time
Don't wait until deployment - generate SBOMs as part of your build process:
# Multi-stage Dockerfile with SBOM generation
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
# Generate SBOM for dependencies
RUN npx @cyclonedx/cyclonedx-npm --output-file sbom.json
FROM node:18-slim AS runtime
WORKDIR /app
COPY --from=builder /app/sbom.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY . .
CMD ["npm", "start"]
2. Store SBOMs with Images
Use OCI annotations to attach SBOMs to container images:
# Using buildx to attach SBOM
docker buildx build \
--annotation "org.opencontainers.image.sbom=sbom.spdx.json" \
-t myapp:latest .
3. Automate SBOM Analysis
Set up automated scanning of your SBOMs:
#!/bin/bash
# Script to check for known vulnerabilities in SBOM
SBOM_FILE="$1"
VULNERABILITY_DB="path/to/vuln/db"
# Extract packages from SBOM
jq -r '.packages[] | "\(.name):\(.versionInfo)"' "$SBOM_FILE" | \
while read package; do
# Check against vulnerability database
if grep -q "$package" "$VULNERABILITY_DB"; then
echo "VULNERABILITY FOUND: $package"
fi
done
Integration with Container Registries
Modern container registries support SBOM storage and analysis:
Harbor
# Harbor automatically generates SBOMs for pushed images
docker push harbor.example.com/myproject/myapp:latest
# View SBOM in Harbor UI or via API
curl -u admin:password \
"https://harbor.example.com/api/v2.0/projects/myproject/repositories/myapp/artifacts/latest/additions/vulnerabilities"
AWS ECR
# ECR supports SBOM uploads
aws ecr put-image-sbom \
--repository-name myapp \
--image-id imageTag=latest \
--sbom file://sbom.spdx.json
Next Steps
SBOMs are just the beginning of supply chain security. In upcoming posts, we'll cover:
- Attestations: Signing and verifying build metadata
- Policy Enforcement: Using SBOMs for admission control
- Vulnerability Remediation: Automated patching workflows
Start experimenting with SBOM generation in your projects today. The investment in supply chain transparency will pay dividends in security and compliance.
Resources
Want to dive deeper into container security? Check out my book "Docker & Kubernetes Security" for comprehensive coverage of SBOMs, attestations, and supply chain protection.