Concept · Application & cloud security
SBOMs and build provenance
A list of what’s inside an artifact, and a signed record of where and how it was built.
When the next Log4Shell lands, two questions decide how bad your week will be: which of our artifacts contain the vulnerable component? And can we trust that what's running is what we built? SBOMs answer the first and provenance answers the second.
SBOM: what's inside
A software bill of materials lists every component in an artifact, direct and transitive dependencies along with OS packages, with versions and identifiers (package URLs). The two standard formats are SPDX and CycloneDX.
syft ghcr.io/acme/api:1.8.2 -o cyclonedx-json > sbom.json # generate from an image
grype sbom:sbom.json # scan it for known CVEs- Generate it at build time from the actual artifact, and store it alongside the artifact.
- Rescan stored SBOMs whenever new CVEs are published. You can find affected services in minutes without rebuilding anything.
- Know the limits. An SBOM lists components; it doesn't say whether the vulnerable code is reachable. Use dependency scanning with reachability data to prioritise.
Provenance: where it came from
Build provenance is a signed statement, called an attestation, that records which source commit, which build workflow and which builder produced an artifact with a given digest. It defends against tampering between source and production: a compromised build server, a hand-pushed image, a swapped tarball.
SLSA (Supply-chain Levels for Software Artifacts) grades how trustworthy a build's provenance is. The higher levels require builds on a hosted, isolated platform that generates and signs the provenance itself, so the build steps can't forge it.
Signing without managing keys
Sigstore (cosign) signs artifacts and attestations using the CI job's OIDC identity instead of a long-lived private key, and records the signature in a public transparency log.
cosign sign ghcr.io/acme/api@sha256:4c1e… # in CI, keyless
cosign verify ghcr.io/acme/api@sha256:4c1e… \
--certificate-identity-regexp 'https://github.com/acme/api/.github/workflows/release.yml@.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comClosing the loop
None of this helps unless something checks it. Enforce verification at deploy time: an admission controller such as Kyverno or Sigstore's policy controller only admits images that are signed by your release workflow and come with provenance and an SBOM. Deploy by digest, not by mutable tag, so what you verified is what runs.
Pair this with pinned dependencies and least privilege for CI. The supply chain lesson covers the full pipeline.