Following major supply-chain attacks (SolarWinds, Codecov, 3CX), the community consolidated a standard for evaluating supply-chain robustness: SLSA[1] (Supply-chain Levels for Software Artifacts). SLSA v1.0, published in April 2023, defines four maturity levels. This article focuses on Level 3, which is the realistic and valuable goal for most teams.

Key takeaways

  • SLSA organises maturity into four levels: L1 (basic provenance), L2 (authenticated provenance), L3 (isolated build), and L4 (two independent reviewers).

  • The L2→L3 leap eliminates the most common attack vectors: build contamination, malicious developer machine, and insider threat.

  • GitHub Actions with reusable workflows and OIDC makes L3 achievable without own infrastructure.

  • Signing is useless if nobody verifies: integrating verification in the Kubernetes admission controller is the natural next step.

  • L3 requires build isolation, not byte-for-byte reproducibility. L4 is aspirational for most.

The four levels

SLSA v1.0 structures maturity as follows:

  • L1: basic provenance. The build system generates an attestation indicating what it built and from what.

  • L2: authenticated provenance. The attestation is signed by a trusted build service, not by an individual.

  • L3: isolated and reproducible build. Each build runs in an ephemeral, independent environment, without influence from prior builds or users.

  • L4: two independent reviewers approve every change. Maximum guarantee, aspirational for most.

Progression isn’t linear: L3 is a major qualitative leap from L2.

Why L3 Is the Realistic Goal

The L2→L3 leap eliminates three attack vectors that are especially hard to detect:

  • Build contamination: builds reusing cache or state from prior builds, letting a compromise persist across builds.

  • Malicious developer machine: a developer’s local environment gets compromised and uploads malicious binaries alongside clean source code.

  • Insider threat: an internal engineer with build-system access can modify artefacts without traceability.

With L3, every build runs in a new environment with no prior state. The only input is source code, and any anomaly is traceable to the commit.

How to Reach L3 with GitHub Actions

GitHub Actions makes L3 feasible with reusable workflows[2] and OIDC for secret-less signing[3]. A typical L3 pipeline:

name: Build and Sign
on:
  push:
    tags: ['v*']

permissions:
  id-token: write   # For OIDC → Sigstore
  contents: read
  packages: write   # For publishing to GHCR

jobs:
  build:
    uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0
    with:
      image: ghcr.io/${{ github.repository }}
      registry-username: ${{ github.actor }}
    secrets:
      registry-password: ${{ secrets.GITHUB_TOKEN }}

This reusable workflow performs four actions in sequence:

  • Builds the image on an ephemeral GitHub runner.

  • Generates a provenance attestation per the SLSA schema[4].

  • Signs the attestation with OIDC via Sigstore[5].

  • Pushes image + attestation to the registry.

Consumer-side verification:

cosign verify-attestation 
  --certificate-identity-regexp '^https://github.com/your-org/your-repo/' 
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' 
  ghcr.io/your-org/your-image:v1.0.0

If it verifies, the image was confirmed to have been built by the specific repository, on an ephemeral GitHub runner, from the indicated commit, without human intervention between source and binary.

Digital certificate chain illustrating the verified trust chain concept underlying SLSA Level 3Digital certificate chain illustrating the verified trust chain concept underlying SLSA Level 3 (Image: Wikisosh, CC BY-SA 4.0, via Wikimedia Commons)

Beyond just GitHub Actions

Other CI systems with similar capabilities:

  • GitLab CI[6] with OIDC and cosign.

  • Buildkite[7] with native attestations since 2023.

  • Tekton + Chains[8] for Kubernetes clusters.

  • Jenkins with cosign plugins, though with less fluid integration.

In all cases, the key is the combination of isolated-build + signature-anchored-in-pipeline-identity, not shared keys.

Operational Challenges

Though L3 is achievable, three frictions to anticipate:

  • Verification at the deployment point. Signing is useless if nobody verifies. Integrating verification in the Kubernetes admission controller (Kyverno[9], Gatekeeper[10], sigstore-policy-controller[11]) is the natural next step.

  • Third-party dependencies. Your own chain may be L3, but if you depend on 50 packages without attestations, the real chain is as strong as its weakest link. This is where broad Sigstore adoption matters.

  • Reproducibility. SLSA L4 requires byte-for-byte reproducible builds. L3 requires isolation, not reproducibility, less demanding and sufficient for most threat models.

Action Plan

Four steps for teams starting out:

  • Audit current state. Are builds hermetic? Is there interactive human access to the build? Are artefacts signed?

  • Choose a pilot image. Start with a critical component and migrate its pipeline to L3 before replicating.

  • Adopt reusable workflows. Rather than writing each step, use those from slsa-github-generator[12], which are audited.

  • Add cluster-side verification. Even as warn-only at first, start measuring which images don’t verify.

For context on why SLSA matters now, see supply-chain attacks. Image scanning with Trivy and Grype is complementary: SLSA attests provenance, scanning detects known vulnerabilities. Kubernetes 1.27 integration is completed with admission controllers that verify attestations at runtime.

Conclusion

SLSA L3 is achievable with mature tooling and justifies investment for any team producing commercial or critical software. The technical path exists; what’s missing is the organisational decision to invest in integrity before the next incident makes it urgent.

Frequently asked questions

Do I need byte-for-byte reproducible builds to reach SLSA Level 3?

No. L3 requires build isolation, not reproducibility: every build runs in a new, ephemeral environment with no state from prior builds and no user influence, and the only input is source code. Byte-for-byte reproducibility is an L4 requirement, alongside two independent reviewers per change, and is aspirational for most teams. L3 isolation is enough to eliminate build contamination, malicious developer machine and insider threat.

Can I reach SLSA L3 without running my own signing infrastructure?

Yes, with GitHub Actions: the generator_container_slsa3.yml reusable workflow from slsa-github-generator builds the image on an ephemeral runner and generates a provenance attestation per the SLSA schema. It signs it with OIDC via Sigstore without secrets and pushes image and attestation to the registry. The consumer verifies with cosign verify-attestation, passing the certificate identity and GitHub's OIDC issuer. GitLab CI with OIDC and cosign, Buildkite and Tekton with Chains offer similar capabilities.

What is the point of signing artefacts if nobody verifies them at deployment?

Very little: a signature only means something when it is checked at the deployment point. The natural next step is integrating attestation verification into the Kubernetes admission controller, with Kyverno, Gatekeeper or sigstore-policy-controller, starting in warn-only mode to measure which images fail to verify. Also, your own chain may be L3, but if it depends on 50 packages without attestations, the real chain is only as strong as its weakest link.

Sources

  1. SLSA
  2. reusable workflows
  3. OIDC for secret-less signing
  4. SLSA schema
  5. Sigstore
  6. GitLab CI
  7. Buildkite
  8. Chains
  9. Kyverno
  10. Gatekeeper
  11. sigstore-policy-controller
  12. slsa-github-generator