Chapter 30Lesson 01~145 minutes

SBOMs, SPDX/CycloneDX, in-toto Attestations, SLSA Provenance, Signatures, and Verification Workflows: Concepts, Architecture, and Mental Model

Attach and verify supply-chain evidence against immutable image digests by separating SBOM inventory, provenance claims, cryptographic signatures, registry referrers, and policy decisions.

SBOMProvenanceSignaturesOCI referrersVerification

Learning objectives

  • Explain the difference between an SBOM, provenance attestation, cryptographic signature, registry referrer, and policy decision.
  • Bind every claim to an immutable image digest and platform rather than a mutable tag.
  • Read BuildKit attestation metadata without assuming that generated evidence is automatically trustworthy.
  • Identify the trust boundary between the builder, registry, signer, verifier, and deployment decision.
  • Recognize current format/version realities: BuildKit SBOMs are SPDX-based, provenance can use SLSA v0.2 or v1, and Engine 29 no longer ships Docker Content Trust commands.

1. The practical problem: “we have an SBOM” is not yet a trust decision

Chapter 29 bound vulnerability results to a digest. Chapter 30 adds the evidence needed to answer different questions: what software is in these bytes, how were these bytes produced, who is asserting something about them, and did a verifier accept those assertions under an explicit policy? Those are separate questions. A package list does not prove build integrity. Provenance does not prove the artifact is vulnerability-free. A signature proves only that a key or identity signed a particular payload; it says nothing useful until the verifier knows what identity was expected and what was signed.

Core rule. The immutable subject digest is the join key. If the SBOM, provenance, signature, scanner result, and deployment record do not resolve to the same digest/platform, the evidence packet is internally inconsistent.

A mutable tag such as demo:release is useful for discovery, not for evidence identity. Resolve it to a digest, record that digest, and verify every downstream object against it.

2. Mental model: subject → evidence → verifier → policy

Causal model: supply-chain evidence is useful only when the subject and verifier are explicit
flowchart TD
  A[Source + build inputs] --> B[Builder identity and build process]
  B --> C[Immutable image digest]
  C --> D[SBOM attestation: what is inside]
  C --> E[Provenance attestation: how it was built]
  C --> F[Signature: who vouches for this subject]
  D --> G[OCI registry/referrer storage]
  E --> G
  F --> G
  G --> H[Verifier checks subject + identity + policy]
  H --> I[Promote / deploy / reject]
            

The build starts with source, Dockerfile, base images, build parameters, and a builder. BuildKit produces an image whose digest identifies the manifest or index. It may also generate attestations. An SBOM describes components. Provenance describes build facts and materials. A signature adds cryptographic evidence from a signing key or workload identity. Registries can store associated artifacts and expose them through OCI-compatible relationships. A verifier then checks subject digest, evidence syntax, cryptographic identity, and organization policy before making a promotion or deployment decision.

Notice the arrows: the verifier does not ask whether “a signature exists.” It asks whether a signature from an expected identity covers the exact subject digest, whether required attestations are attached to that subject, and whether their claims match policy.

3. Define the state before touching it

State Evidence to record Why it matters
Subject image repository + immutable digest + platform All later evidence must name the same subject.
SBOM format, document identity, packages/files, generator Inventory accuracy and format are independent of cryptographic trust.
Provenance predicate type/version, build type, builder ID, materials, parameters Explains how the subject was produced and what the builder claims.
Attestation object attestation/referrer digest and media type Lets you distinguish evidence objects from the application image itself.
Signature signature/bundle, key or certificate identity, algorithm Binds a cryptographic assertion to the subject/payload.
Transparency evidence log/bundle inclusion where used Adds public/auditable evidence in keyless Sigstore flows; not required by the local-key lab.
Policy expected subject, signer, predicate, builder/material constraints Transforms raw evidence into an explicit allow/reject decision.
Verification tool/version, timestamp, result Verification is an action with software and time context, not a permanent property.

4. SBOM: inventory evidence, not authenticity

Docker BuildKit can generate an SBOM attestation during the build with --sbom=true or --attest type=sbom. Docker documents that the generated attestation is JSON-encoded SPDX wrapped as an in-toto predicate. The default scanner plugin is BuildKit’s Syft-based generator. This is valuable because build-time scanning can describe artifacts used in build stages that may not appear in the final filesystem.

SPDX and CycloneDX are both widely used machine-readable BOM standards, but they are not interchangeable labels. The current SPDX specification is 3.0.1; CycloneDX’s current specification is 1.7. BuildKit’s native SBOM attestation path is SPDX-oriented. If your consumer requires CycloneDX, generate or convert it with a tool that explicitly supports that output, and record the generator/version rather than pretending the BuildKit SBOM magically changed format.

Inventory completeness is contextual. A package can be missing because the generator cannot recognize it, because a multi-stage build removed it from the final image, or because the artifact exists outside a supported package ecosystem. “Not listed” is not proof of absence.

5. Provenance: build claims and materials

BuildKit provenance records facts such as build timestamps, parameters, environment, VCS metadata, source details, and materials consumed by the build. Buildx creates minimal provenance by default for build results that can retain attestations. You can request mode=max for richer evidence and explicitly request SLSA provenance v1 with version=v1. As of this chapter baseline, Docker documents v0.2 as the default schema while also supporting v1.

More provenance is not always better. Maximum mode can expose build arguments or source details that you would not publish to an untrusted registry. The design question is not “min or max?” in isolation; it is “which claims does the verifier need, and which details are safe to disclose in this evidence channel?”

# Read-only inspection of a registry image with attestations
# Replace IMAGE with an actual immutable or tagged registry reference.
docker buildx imagetools inspect "$IMAGE" --format '{{json .Provenance}}'
docker buildx imagetools inspect "$IMAGE" --format '{{json .SBOM}}'

6. Signatures: identity plus subject binding

Signing answers a different question. A signer uses a private key, hardware-backed key, KMS key, or keyless workload identity to produce cryptographic evidence. Verification succeeds only when the verifier trusts the corresponding public key or certificate chain and checks the intended identity. For local education we use a throwaway Cosign keypair because it is deterministic, free, and does not require OIDC or a public transparency service.

Cosign itself warns to sign image digests rather than tags. That matters because signing a tag creates a time-of-check race: the tag can move between resolution and signing. The lab therefore resolves localhost:5005/dca30/app:1 to a digest first, forms localhost:5005/dca30/app@sha256:..., and signs that immutable reference.

Generated ≠ authenticated. BuildKit can attach provenance and SBOMs to an image. Their existence alone does not prove an authorized builder produced them. Authentication requires a trusted signature/identity or a trusted transport/platform policy around the evidence.

7. OCI subjects and referrers

OCI Image/Distribution 1.1 standardized a subject relationship and a Referrers API so registries and tools can discover signatures, attestations, and other artifacts associated with a digest. Conceptually, the application image is the subject; an SBOM, provenance statement, or signature is a separate object that refers to that subject. That avoids stuffing every evidence type into the runtime image filesystem.

Registry behavior still matters. A registry may implement OCI 1.1 referrers directly, use a compatibility fallback, impose media-type limits, or garbage-collect unreferenced artifacts differently. Evidence portability therefore includes a registry capability test, not just a tool capability test.

8. Engine 29 compatibility baseline

Component / behavior 2026-09-22 lesson baseline Operational consequence
Docker Engine / CLI 29.8.1 current release Docker Content Trust commands were removed from the CLI in Engine 29. Do not copy old docker trust tutorials into current workflows.
Buildx 0.37.1 current release Supports current BuildKit attestation and imagetools workflows; record the learner’s actual version.
BuildKit 0.33.0 current upstream Current Dockerfile frontend is 1.27.0; builder-packaged versions can differ.
Compose 5.5.1 current release Not required for the attestation mechanics; record it in the checkpoint preflight for environment identity.
containerd / runc 2.3.5 / 1.5.1 current upstream Runtime component versions are evidence context, not attestation identities.
Cosign 3.1.3 pinned lab tool Current release fixes a legacy-bundle verification bypass; use current verification behavior.
OCI Image/Distribution 1.1 artifact/referrer model; image-spec 1.1.1 available Subject/referrer relationships are registry metadata, not files inside the app image.

9. Chapter path

Lesson 2 builds and inspects evidence. Lesson 3 makes format, identity, storage, and policy choices explicit. Lesson 4 deliberately breaks subject/identity assumptions and diagnoses the failure. Lesson 5 produces one auditable packet in which the image digest, SBOM, provenance, signature, and policy verdict all agree.

Next

Build evidence, then verify it

The next lesson uses a disposable localhost registry and a throwaway signing key so the evidence workflow can be exercised without cloud accounts or production credentials.

Knowledge check

Why is an SBOM alone insufficient to prove an image is trustworthy?

What should be the common join key across SBOM, provenance, signature, scan result, and deployment record?

Does provenance prove an image has no vulnerabilities?

Why does Cosign documentation recommend signing a digest rather than a tag?

An attestation was generated by BuildKit and attached to a registry image. Is it automatically trusted?

Official references and version notes

Verified baseline date:

2026-09-22. Docker Engine 29.8.1, Buildx 0.37.1, BuildKit 0.33.0, Compose 5.5.1, containerd 2.3.5, runc 1.5.1, and Cosign 3.1.3 were current upstream references when this lesson was authored. Your installed Docker Desktop/Engine bundle can package different component versions; record actual command output.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.