Skip to main content
โšก Calmops

SBOM: Software Bill of Materials Guide

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