---
name: "build_provenance"
description: "Make software releases provable: signed builds, reproducible builds, SLSA attestations, Sigstore signing, and admission-time verification. Use when setting up release signing, adding provenance to a CI pipeline, verifying an artifact's origin, or choosing between GPG, cosign, GitHub attestations, and SLSA levels."
---

# Build Provenance

## Purpose
Turn "trust me, I built this" into a checkable claim. A release gets a signed statement of exactly what source, workflow, and builder produced each artifact, built so independent rebuilds can reproduce the same bytes, and verified at the point of consumption (by a person with a CLI, or by a cluster at admission).

## Workflow

1. **Pick the provenance model first.** For container images: cosign keyless signing + SLSA provenance. For release binaries: GitHub Artifact Attestations (`actions/attest-build-provenance@v1`) or `slsa-github-generator` for Build L3. For Debian-style packages: reproducibility with `.buildinfo`. See `references/provenance-stack.md` for the SLSA level ladder (L1/L2/L3) and what each tool actually guarantees.

2. **Make the build reproducible before you sign anything.** Pin the toolchain and lockfiles, set `SOURCE_DATE_EPOCH` from the commit timestamp, strip absolute paths (`-ffile-prefix-map`), sort inputs, and compare two builds byte-for-byte in CI. Signing a nondeterministic build proves origin but leaves tampering in the build window unverifiable.

3. **Sign keyless, log publicly.** Use Sigstore Fulcio + Rekor (via cosign or GitHub OIDC), never long-lived GPG keys you have to store, rotate, and pray nobody leaks. Sign by content digest (`@sha256:...`), never by tag.

4. **Publish the provenance beside the artifact.** Provenance files live with the release (`.intoto.jsonl`), SBOMs are signed too. Write the consumer's verification recipe into your release docs, not just "possible in theory."

5. **Verify at the consuming end.** Users check with `slsa-verifier` or `gh attestation verify`; clusters enforce with Kyverno `verifyImages`. Roll out enforcement in `Audit` mode first, then flip to `Enforce`.

## Output Contract
Delivering a provenance setup means producing:
- Signed artifacts + provenance statements attached to each release, verifiable by an outsider with the documented commands.
- A double-build CI job proving reproducibility (or a documented gap).
- A written verification recipe a consumer can run in under 5 minutes.
- Optionally: an admission policy enforcing signature checks, landed in Audit before Enforce.

## Operating Rules
- Keyless Sigstore first; long-lived signing keys only when a compliance regime forces them.
- Never sign by tag. Always by digest.
- State the SLSA level AND the spec version (levels differ between v1.0/v1.2; GitHub docs still reference v1.0). A level claim without a version is half a claim.
- When verifying, pin the source ref (`--source-ref refs/tags/vX.Y.Z`), not just the repo. An attestation names the workflow; without the tag, a borrowed attestation from another release passes.
- Provenance covers binaries and images. It does not cover the build environment being clean. Pair with reproducible builds or honest SLSA-level scoping.
- Validate provenance files locally with `bin/check-provenance.py` before publishing. It checks the in-toto envelope, SLSA predicate type, subject digests, and builder identity presence.
- Skip anything you cannot verify: unverified numbers, invented tool flags, and copied configs with untested pins get cut.
