Git, CI/CD & GitOpsLXVIII · SBOMDistribution
SBOM distribution and attestation — SBOM as an in-toto attestation
What you'll learn
- Attach an SBOM to an artifact digest as a signed cosign attestation
- Describe the in-toto attestation envelope and the predicate types SPDX and CycloneDX use
- Explain the OCI referrer model and how a verifier fetches the SBOM by digest
- Recognise the difference between a SBOM as a CI artifact and an SBOM as a registry attestation
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
A SBOM that lives in CI artifact storage is a SBOM that disappears with the retention window. The production-graded distribution is to attach the SBOM to the artifact digest as a signed attestation in the registry. The attached SBOM lives as long as the image digest lives; the signature proves the attestation was produced by the build pipeline; the in-toto envelope makes the SBOM a structured claim that any verifier can read.
Why the SBOM must move with the artifact
The SBOM is an inventory of the artifact bytes; the bytes are identified by their digest. A SBOM stored anywhere else must be re-anchored to the digest at every query. The registry-native distribution is the OCI referrer model: a SBOM attached to an image is stored as a separate OCI artifact that refers to the image digest, and the registry indexes the referrer.
flowchart LR
A["Image (digest)"] --> B["Registry"]
B --> C["SBOM (referrer)"]
B --> D["Signature"]
B --> E["Provenance (referrer)"]
C --> F["in-toto envelope"]
F --> G["Signed payload"]
The in-toto envelope and cosign attach sbom
The SBOM is wrapped in an in-toto attestation before it is
attached. The envelope is a JSON document with two layers: the
statement (the predicate type, the subject, and the
predicate — the SBOM) and the signature (the signed payload
plus the certificate and the Rekor entry). The in-toto project
defines https://spdx.dev/Document for SPDX documents and
https://cyclonedx.org/bom for CycloneDX documents.
The cosign commands:
cosign attach sbom --sbom sbom.spdx.json \
ghcr.io/org/app:$COMMIT_SHA
cosign sign --keyless ghcr.io/org/app:$COMMIT_SHA
The first command uploads the SBOM as an OCI referrer; the
second signs the image and the referrer. The verifier runs
cosign verify-attestation --keyless --certificate-identity-regexp ... — the OIDC subject proves
the attestation was produced by this workflow.
Production discipline
- Attach the SBOM to the artifact digest as a signed attestation. The CI artifact is a backstop.
- Pin the OIDC subject in the verifier (a wildcard is too permissive) and verify in the admission controller.
- Monitor Rekor inclusion. A signature without a Rekor entry has lost the tamper-evidence property.
Cross-course references
- Git, CI/CD & GitOps — Part LIII-06 (Image Signing in CI) is the cosign and Sigstore foundation that the SBOM attestation reuses.
Quiz
Knowledge check · 4 questions
Q1. Why is attaching the SBOM to the artifact digest as a signed attestation more durable than storing the SBOM as a CI artifact?
Q2. A wildcard `--certificate-identity-regexp 'https://github.com/org/.*'` is the production pattern for the verifier's OIDC subject pin.
Q3. Name the two layers of the in-toto attestation envelope and what each layer contains.
Q4. Diagnose why the SBOM is not load-bearing at audit time and recommend the fix.
Team T's CI generates an SBOM with syft, uploads it as a CI artifact, and references the SBOM path in a deployment manifest. Six months later the audit team asks for the SBOM. The CI artifact retention has expired; the SBOM is gone.
Passing score: 75%. Answers are checked in this browser.