SBOMs & Provenance
SBOMs & Provenance
A software supply chain attack does not break into your code — it compromises something your code trusts: a dependency, a build tool, a base image, or a CI runner. The SolarWinds breach, the XZ utils backdoor, and the event-stream npm incident all share this pattern. The industry response is a trio of interlocking standards: Software Bill of Materials (SBOM), provenance attestations, and SLSA supply-chain levels. Together they answer three questions every security team must be able to answer at 2 a.m. after a zero-day drops: What is in our software? Where did it come from? Did anything tamper with the build?
SBOMs: CycloneDX vs SPDX
An SBOM is a machine-readable manifest — a complete inventory of every component in a piece of software, including transitive dependencies, with version, license, and vulnerability identifiers. Two formats dominate the ecosystem:
- CycloneDX — designed by OWASP specifically for security use cases. Supports JSON, XML, and Protobuf. First-class support for vulnerabilities, services, formulas (how the software was built), and attestations. The de-facto standard in pipeline tooling: Syft, Trivy, cdxgen, and the GitHub Dependency Submission API all produce CycloneDX.
- SPDX — the ISO/IEC 5962:2021 standard, originally from the Linux Foundation compliance community. Tag-value, JSON, YAML, and RDF formats. Stronger license expression syntax via SPDX license IDs. Mandated by US Executive Order 14028 and the EU Cyber Resilience Act. The NTIA minimum-elements definition is SPDX-aligned.
In practice, large organizations generate CycloneDX for security tooling (feeding into Dependency-Track, Grype, OSV-Scanner) and SPDX for legal and compliance hand-offs. Syft can produce both formats from a single scan.
Generating SBOMs in CI
The best time to generate an SBOM is immediately after a container image is built, before it is pushed to the registry. At that moment the build environment knows exactly what went into the image. Syft is the most widely adopted generator; cdxgen handles polyglot monorepos; Trivy combines SBOM generation with vulnerability scanning in a single pass.
Provenance Attestations
An SBOM tells you what is in an artifact. A provenance attestation tells you how it was built — which source commit, which CI system, which runner, which build commands, and crucially, whether any of those inputs are trusted. Provenance is a signed document that links a build output to its inputs in a tamper-evident way.
The emerging standard is in-toto attestations with the SLSA Provenance predicate. GitHub Actions generates SLSA provenance automatically when you use the actions/attest-build-provenance action. The attestation is stored in the Sigstore transparency log (Rekor) and pinned to the OCI image digest — not a tag, which is mutable, but the immutable content hash.
:latest can be silently replaced. An image referenced as sha256:abc123... cannot. Your SBOM and provenance attestation must reference the digest; otherwise they can be detached and reattached to a different, potentially malicious image.
SLSA Supply-Chain Levels
SLSA (Supply-chain Levels for Software Artifacts, pronounced "salsa") is a Google-originated framework that defines four assurance levels for build integrity. Each level adds requirements that make tampering progressively harder to hide.
Most GitHub Actions workflows running on ubuntu-latest with OIDC-issued tokens meet SLSA L2 today. Reaching L3 requires an isolated, ephemeral build environment where the build service itself — not the developer — generates and signs provenance, and no persistent credentials are injected into the build. Google's Cloud Build with SLSA L3 builder and GitHub's own SLSA Level 3 container builder (slsa-framework/slsa-github-generator) are the practical paths.
End-to-End Pipeline: SBOM + Provenance in GitHub Actions
Continuous Vulnerability Scanning with SBOM
Generating an SBOM at build time is only half the picture. The SBOM must be continuously re-scanned against updated vulnerability databases after the image is deployed — a component that was clean on Monday may have a published CVE by Wednesday. Dependency-Track is the production-grade platform for this: it ingests CycloneDX SBOMs, maintains its own mirrored vulnerability databases (NVD, OSV, GitHub Advisory), and exposes a REST API and webhooks that integrate into your alerting stack. Feed it your SBOM on every deploy; it handles ongoing monitoring.
actions/attest-sbom) so they travel with the image digest and are always retrievable regardless of how old the image is. When a CVE drops, you need to query "which running images contain libssl 3.0.2?" in seconds — not hunt through expired artifacts.
Querying SBOMs Under Incident Conditions
When a zero-day is announced (e.g., a new Log4Shell-class vulnerability), your first question is blast radius: which services are affected? With a well-maintained SBOM pipeline and Dependency-Track, the answer is a single API call. Without it, you are manually grepping thousands of pom.xml and package-lock.json files across hundreds of repositories under time pressure — a notoriously error-prone process that leads to missed instances. At Google and Netflix scale, SBOM-driven blast-radius queries run in under one second across tens of thousands of service versions.
pkg:npm/%40angular/core@17.3.2 or pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1 is ecosystem-agnostic, human-readable, and understood by every major SCA and SBOM tool. Use PURLs in your SBOMs; avoid CPEs for application dependencies (CPEs were designed for OS packages and are ambiguous for application libraries).
Key Takeaways
- SBOMs answer what; provenance attestations answer how and from where; SLSA levels measure how trustworthy the build process is.
- Generate CycloneDX SBOMs from your container images at build time; attach them as signed OCI attestations pinned to the image digest.
- SLSA L2 is achievable today with standard GitHub Actions; L3 requires an isolated build service (slsa-github-generator or Google Cloud Build).
- Store SBOMs in the registry alongside the image and feed them into Dependency-Track for continuous CVE monitoring.
- Under a zero-day incident, a mature SBOM pipeline reduces blast-radius assessment from hours to seconds.