Skip to main content
RunBook Academy

Git, CI/CD & GitOpsLXVIII · SBOMDistribution

SBOM distribution and attestation — SBOM as an in-toto attestation

Intermediate⏱ ~22 mingitdocker

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

Not yet marked complete on this device.

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

  1. Attach the SBOM to the artifact digest as a signed attestation. The CI artifact is a backstop.
  2. Pin the OIDC subject in the verifier (a wildcard is too permissive) and verify in the admission controller.
  3. 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

  1. Q1. Why is attaching the SBOM to the artifact digest as a signed attestation more durable than storing the SBOM as a CI artifact?

  2. Q2. A wildcard `--certificate-identity-regexp 'https://github.com/org/.*'` is the production pattern for the verifier's OIDC subject pin.

  3. Q3. Name the two layers of the in-toto attestation envelope and what each layer contains.

  4. 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.