Skip to content
$cd ..

// post

Software Supply Chain Security and SBOMs

The software supply chain attacks of recent years — SolarWinds, Codecov, Log4Shell — shifted supply chain security from a theoretical concern to an operational one. SBOMs (Software Bills of Materials) became one of the central responses to this shift. But there’s still significant confusion about what an SBOM actually is, what it can and can’t do, and how to make one useful rather than just compliant.

What is an SBOM?

An SBOM is a formal, machine-readable inventory of the components that make up a piece of software. Think of it as the ingredient list for your application: every library, dependency, framework, and tool that went into building it, along with version numbers and licensing information.

Two formats dominate:

For most security use cases, CycloneDX is the more capable format.

Why SBOMs Matter

The value of an SBOM is realized in two scenarios:

1. Vulnerability response

When a critical vulnerability is disclosed (another Log4Shell, another OpenSSL), the first question is: do we use this component? Without an SBOM, answering that question requires manually searching codebases, dependency files, and Docker images across every service. With an SBOM, it’s a query.

2. Supply chain integrity

SBOMs, when combined with attestations and signing, let you verify that what you built is what you shipped — and that no component was tampered with between build and deployment.

Generating SBOMs

For application dependencies

Syft by Anchore is the most capable open-source SBOM generator. It scans container images, directories, and archives.

# Generate SBOM for a container image
syft nginx:latest -o cyclonedx-json > sbom.json

# Generate for a local project directory
syft dir:. -o spdx-json > sbom.spdx.json

For container images

# Include OS packages + application dependencies
syft alpine:latest -o cyclonedx-json

# Or with Docker Scout (built into Docker CLI)
docker scout sbom nginx:latest

In CI/CD

# GitHub Actions — generate and attest SBOM on every build
- name: Generate SBOM
  uses: anchore/sbom-action@v0
  with:
    image: ${{ env.IMAGE }}
    format: cyclonedx-json
    output-file: sbom.cyclonedx.json

- name: Attest SBOM
  uses: actions/attest-sbom@v1
  with:
    subject-name: ${{ env.IMAGE }}
    sbom-path: sbom.cyclonedx.json

Scanning SBOMs for Vulnerabilities

Generating an SBOM is step one. Scanning it against known vulnerability databases is where the security value is realized.

Grype pairs naturally with Syft and scans SBOMs against NVD, OSV, GitHub Advisories, and more:

# Scan a container image directly
grype nginx:latest

# Scan a previously generated SBOM
grype sbom:sbom.cyclonedx.json

# Output as table, JSON, or SARIF for CI integration
grype nginx:latest -o sarif > results.sarif

OSV-Scanner from Google scans dependency files and SBOMs against the OSV database:

osv-scanner --sbom sbom.cyclonedx.json

Supply Chain Integrity: Beyond the SBOM

An SBOM tells you what’s in your software. To verify how it was built and that it hasn’t been tampered with, you need:

Sigstore / Cosign

Cosign signs container images and other artifacts using keyless signing via OIDC identity (no long-lived keys to manage):

# Sign an image after pushing
cosign sign --yes ghcr.io/myorg/myapp:v1.0.0

# Verify before deployment
cosign verify ghcr.io/myorg/myapp:v1.0.0 \
  --certificate-identity=https://github.com/myorg/myapp/.github/workflows/release.yml@refs/heads/main \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com

SLSA (Supply-chain Levels for Software Artifacts)

SLSA is a framework for supply chain integrity with four levels of assurance. At SLSA Level 3, builds are:

Practical Starting Point

If you’re starting from zero:

  1. Add Syft to your CI build — generate an SBOM for every container image you publish
  2. Run Grype on the SBOM — fail the build on critical/high vulnerabilities (with a reasonable policy)
  3. Publish the SBOM as a build artifact — attached to your release or stored in your registry
  4. Sign images with Cosign — keyless signing via GitHub Actions OIDC is straightforward

This gives you a solid foundation: you know what’s in your software, you’re scanning it continuously, and you can prove it was built from the source it claims.

Previous
Hardening GitHub Actions Workflows
Next
Secrets Management in CI/CD Pipelines