Hitchhiker's Guide — Operating a Supply-Chain Assurance Pipeline

The operator's manual for Phase 14 WARMUP. The WARMUP derives the mechanisms; this is how you actually sign keyless, generate and verify SLSA provenance, query a transparency log, enforce binary authorization, and pin/reconcile dependencies — with concrete commands and expected behavior.

Table of Contents


Keyless Signing and Verification (Cosign)

# Keyless sign (Fulcio issues a short-lived cert bound to your OIDC identity; Rekor logs it)
COSIGN_EXPERIMENTAL=1 cosign sign ghcr.io/acme/orders@sha256:<digest>

# Verify by DIGEST, pinning the expected identity + issuer (NOT a mutable tag)
cosign verify \
  --certificate-identity-regexp '^https://github.com/acme/orders' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/acme/orders@sha256:<digest>

No long-lived key to steal; the signature is publicly recorded. Always verify by digest and pin the signer identity + issuer — a verify that accepts any identity proves nothing.

Generating and Verifying SLSA Provenance

# A trusted, isolated builder (e.g. the SLSA GitHub generator) emits non-falsifiable provenance.
cosign verify-attestation --type slsaprovenance \
  --certificate-identity-regexp '^https://github.com/slsa-framework/slsa-github-generator' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/acme/orders@sha256:<digest>

Then enforce policy (Lab 01): the provenance's subject must equal the deploying digest; the builder must be allowed; the source repo+commit must match; the materials must reconcile with the lockfile; and the achieved SLSA level must meet the bar. Field-matching is not enough — reconcile the materials.

Querying the Transparency Log (Rekor)

rekor-cli search --sha sha256:<artifact-digest>        # is this artifact's signature logged?
rekor-cli get --uuid <entry-uuid>                       # the entry + inclusion proof

Monitoring discipline: subscribe to Rekor for your identities/artifacts so an unexpected signature (someone signing as you) is detected — the audit property that makes a transparency log valuable. Lab 02 implements the inclusion-proof verification (recompute the Merkle root from the audit path, check it against the signed tree head).

Binary Authorization at Admission

# Sigstore policy-controller / Kyverno: only run images that pass policy, by digest.
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
spec:
  images: [{glob: "ghcr.io/acme/**"}]
  authorities:
    - keyless:
        identities: [{issuer: "https://token.actions.githubusercontent.com",
                      subjectRegExp: "^https://github.com/acme/.*"}]
      attestations:
        - name: must-have-slsa-provenance
          predicateType: slsaprovenance

Fail closed: an image without a valid signature and the required provenance is refused admission. This is the enforcement point — without it, provenance is decoration.

Hermetic and Reproducible Builds

# Hermetic: Bazel/Nix declare all inputs and run with no network -> no smuggled build-time fetches.
bazel build //service:image     # inputs pinned; sandboxed; no undeclared network
# Reproducible: strip non-determinism so an independent rebuild is bit-for-bit identical.
export SOURCE_DATE_EPOCH=$(git log -1 --format=%ct)    # deterministic timestamps
# then: an independent rebuilder produces the SAME digest -> the binary provably matches the source

A reproducible build means a third party can confirm the artifact corresponds to the source — the strongest defeat of a compromised builder.

Dependency Pinning and Reconciliation

  • Pin by digest, not just version (a re-published version or a lying mirror can't substitute).
  • Refuse public resolution of internal names (dependency confusion); scope/namespace internal packages and pin per-package registries.
  • Disable install scripts by default; review them when needed.
  • Reconcile what the build consumed against the lockfile (Lab 01 materials check) — fail on any extra, missing, or digest-mismatched material.
  • Monitor maintainer changes and unusual release artifacts (the xz lesson — the backdoor was in release tarballs, not the git tree).

SBOM and VEX in Practice

syft ghcr.io/acme/orders@sha256:<digest> -o cyclonedx-json > sbom.json   # inventory
grype sbom:sbom.json                                                      # known CVEs
# Attach an SBOM + VEX attestation so consumers know what's PRESENT and what's EXPLOITABLE.
cosign attest --type cyclonedx --predicate sbom.json ghcr.io/acme/orders@sha256:<digest>

When the next critical CVE drops, query SBOMs across the fleet for "are we affected and where," then publish VEX (not_affected with justification where the path is unreachable) to cut noise.

Failure Drills

  • Injected dependency → materials reconciliation flags unlocked-material → build rejected.
  • Swapped artifact → digest mismatch / subject mismatch → admission refused.
  • Forged signature for your identity → appears in Rekor → monitoring alerts.
  • Below-SLSA-level build → policy refuses.
  • Tampered inclusion proof → recomputed root ≠ signed tree head → not-included.

Evidence Packet

The threat model with per-link controls; a verified keyless signature + SLSA provenance (with materials reconciliation output); a Rekor inclusion-proof verification; a fail-closed binary-authorization policy and a blocked-deploy demo; a reproducible-build verification; an SBOM+VEX attestation; and a dependency-policy with a blocked confusion/typosquat case.

References

  • Sigstore Cosign/Fulcio/Rekor docs; SLSA GitHub generator; Sigstore policy-controller; Kyverno.
  • RFC 6962; Reproducible Builds project; Bazel/Nix; Syft/Grype; OpenSSF Scorecard.
  • Phase 03 and Phase 07 cross-references.