Build Provenance with SLSA

SecuritySupply ChainSLSADevOps
Share on LinkedIn

After the SolarWinds and Codecov incidents, our security team stopped asking "did we scan for CVEs?" and started asking "can we prove this binary was built from our source code by our CI system?" Vulnerability scanning catches known bad dependencies. Provenance catches the case where someone else's build pipeline — or an attacker who compromised it — produced the artifact you're about to deploy.

SLSA (Supply-chain Levels for Software Artifacts, pronounced "salsa") is a framework from Google and the OpenSSF that defines progressive levels of build pipeline security. At its core is provenance: a signed attestation that links an artifact to its exact source, builder, and build parameters.

SLSA levels at a glance

Level Requirements What it prevents
1 Documented build process Undocumented tampering
2 Hosted build + provenance Ad-hoc local builds sneaking in
3 Non-falsifiable provenance, hermetic builds Builder compromise going undetected
4 Two-person review, reproducible builds Single-actor insider threats

Level 2 is the sweet spot for most engineering teams. You generate provenance automatically in CI, store it with the artifact, and verify it at deployment time.

What provenance contains

A SLSA provenance attestation is a JSON document signed by the build platform:

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [{ "name": "my-app:v1.2.3", "digest": { "sha256": "abc..." } }],
  "predicateType": "https://slsa.dev/provenance/v1",
  "predicate": {
    "buildDefinition": {
      "buildType": "https://github.com/actions/runner",
      "externalParameters": {
        "repository": "https://github.com/org/my-app",
        "ref": "refs/heads/main",
        "workflow": { "path": ".github/workflows/release.yml" }
      }
    },
    "runDetails": {
      "builder": { "id": "https://github.com/actions/runner/v2" },
      "metadata": {
        "invocationId": "https://github.com/org/my-app/actions/runs/12345"
      }
    }
  }
}

This says: artifact my-app:v1.2.3 with SHA256 abc... was built by GitHub Actions runner from commit on main using the release workflow. An attacker can't produce this attestation without access to your CI system.

Generating provenance with GitHub Actions

GitHub Actions has built-in SLSA provenance generation for workflows using slsa-framework/slsa-github-generator:

name: Release
on:
  push:
    tags: ["v*"]

jobs:
  build:
    permissions:
      contents: read
      packages: write
      id-token: write  # Required for OIDC signing
    uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
    with:
      image: ghcr.io/org/my-app
      digest: ${{ needs.build.outputs.digest }}

The generator produces provenance signed via Sigstore's keyless signing (OIDC-based, no long-lived keys to manage). Attestations are stored in the GitHub Container Registry alongside the image or uploaded to a transparency log.

For generic artifacts (JARs, binaries, npm packages):

- uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
  with:
    base64-subjects: "${{ needs.build.outputs.hashes }}"
    upload-assets: true

Verifying provenance at deploy time

Use slsa-verifier to check artifacts before deployment:

slsa-verifier verify-image \
  ghcr.io/org/[email protected] \
  --source-uri github.com/org/my-app \
  --source-tag v1.2.3

In a Kubernetes admission controller or deploy pipeline:

# Fail deploy if provenance doesn't match policy
slsa-verifier verify-artifact my-app.jar \
  --provenance-path provenance.intoto.jsonl \
  --source-uri github.com/org/my-app \
  --builder-id "https://github.com/actions/runner/v2"

Policy-as-code tools (Kyverno, OPA) can enforce that only images with valid SLSA provenance from approved builders enter production clusters.

Hermetic builds (Level 3)

A hermetic build only uses declared inputs — no network access during compilation, no reading undeclared files. This ensures the provenance fully describes how the artifact was produced.

Practical steps toward hermetic builds:

Full hermeticity is hard for ecosystems that fetch dependencies at build time (npm install during Docker build). Mitigate by multi-stage builds that copy pre-resolved node_modules from a locked-deps stage.

Signing artifacts with Sigstore

SLSA provenance uses Sigstore for signing and verification:

cosign sign ghcr.io/org/[email protected]
cosign verify ghcr.io/org/[email protected] \
  --certificate-identity-regexp="https://github.com/org/my-app" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com"

Getting started this week

  1. Add SLSA provenance generation to your release workflow (Level 2).
  2. Commit lockfiles and use frozen installs (foundation for Level 3).
  3. Add slsa-verifier to your deploy pipeline to reject unprovenanced artifacts.
  4. Enable Dependabot/Renovate for controlled dependency updates.
  5. Document your build process in a BUILD.md (Level 1, if nothing else).

Common production mistakes

Teams get supply chain provenance slsa wrong in predictable ways:

Production implementations of supply chain provenance slsa fail when staging mirrors production topology poorly, rollback is untested, and on-call runbooks describe the happy path only.

Debugging and triage workflow

When supply chain provenance slsa misbehaves in production, work top-down instead of guessing:

  1. Confirm scope — one tenant, region, or deployment stage? Narrow blast radius before deep diving.
  2. Check recent changes — deploys, flag flips, config pushes, and schema migrations in the last 24 hours.
  3. Compare golden signals — latency, error rate, saturation, and traffic for the affected surface vs. baseline.
  4. Reproduce minimally — smallest input or scenario that triggers the failure; capture traces/logs with correlation IDs.
  5. Fix forward or rollback — if rollback is faster than root-cause during incident, rollback first, postmortem second.
  6. Add a guard — alert, integration test, or circuit breaker so the same class of failure is caught earlier next time.

Document the timeline during triage. Future you (and on-call) will need timestamps, not just conclusions.

Resources

Frequently asked questions

What SLSA level should my project target?

Most teams should target SLSA Build Level 2 as a practical first milestone — hosted build platform with provenance generation. Level 3 adds non-falsifiable provenance and hermetic builds, requiring more infrastructure investment. Level 4 (two-person review, reproducible builds) is appropriate for critical infrastructure like crypto libraries or OS packages. Start at Level 1 (documented build process) and increment.

How does SLSA provenance differ from an SBOM?

An SBOM lists what went into your artifact — dependencies, versions, licenses. SLSA provenance describes how the artifact was built — which source commit, which builder, which workflow, what inputs. SBOM answers 'what's inside?' Provenance answers 'who built this and from what?' Both are complementary; SLSA provenance often references the SBOM as a build material.

Can I verify SLSA provenance in my deployment pipeline?

Yes — tools like slsa-verifier check that an artifact's provenance attestation matches your policy (expected builder, source repository, branch). Container registries (GitHub Container Registry, Google Artifact Registry) store attestations alongside images. Your deploy pipeline rejects artifacts without valid provenance or with provenance from unexpected sources.

Hiring a senior Android / Flutter engineer?

I architect and ship production mobile software — Kotlin, Jetpack Compose, Flutter — for robotics, EV infrastructure, fintech, and real-time systems. Open to remote roles in Europe and the US.

Get in touch →