In 2020, attackers compromised the SolarWinds build system and injected malicious code into signed, official software updates that went out to 18,000 organizations. The artifacts looked legitimate. The signatures were valid. The problem was nobody had any way to prove how those artifacts were built, by what system, from what source commit, under what conditions. The signature told you SolarWinds touched it. It told you nothing about whether a malicious build step had been injected in between.
That gap is exactly what SLSA fixes.
SLSA (Supply-chain Levels for Software Artifacts, pronounced “salsa”) is a framework originated at Google and now maintained under the OpenSSF that defines progressively stronger guarantees about build integrity. It gives you cryptographic, machine-verifiable proof that a given artifact was produced by a specific build system from a specific source commit, with no opportunity for tampering in between. And with the EU Cyber Resilience Act requiring vulnerability reporting and traceability starting September 2026, and the US CISA SSDF mandating similar discipline for federal software suppliers, this is no longer a nice-to-have.
In twenty years of building production infrastructure, I have seen organizations do a good job signing artifacts and a terrible job of knowing what they were signing. SLSA closes that gap.
The Problem: Your Build System Is an Attack Surface
Before getting into SLSA specifics, it is worth understanding exactly what threat model we are talking about. Supply chain attacks come in several flavors, and not all of them involve compromising source code.
The SolarWinds attack targeted the build pipeline itself. The XZ Utils attack in 2024 targeted a maintainer account to inject a backdoor into a compression library that ships in most Linux distributions. The 3CX attack in 2023 compromised a signed desktop application through a dependency that had itself been compromised. In each case, the artifact reached end users looking legitimate because the signing step happened after the compromise.
Traditional artifact signing (signing a binary with a GPG key or a container image with cosign) answers the question “did this specific organization release this artifact?” It does not answer “was this artifact built in a controlled environment from the exact source code that lives in your repository?” That distinction matters enormously.
SLSA answers the second question by defining what a build system must prove and how it must prove it. The proof takes the form of a provenance attestation: a signed document that records the builder identity, the source repository and commit hash, the build parameters, the entry point, and the digest of every output artifact. Critically, this attestation is signed by the build platform itself (GitHub Actions, Google Cloud Build, GitLab CI, etc.), not just by the developer who kicked off the build. That separation of duties is what makes it meaningful.
SLSA Levels: What Each One Actually Requires
SLSA v1.0 defines three levels for the Build Track. Each one adds a stronger guarantee.
SLSA Build Level 1 requires that the build process be fully scripted and that provenance be generated. The provenance does not need to be signed or verified, but it must exist. This alone eliminates the “we have no idea how this was built” scenario. It is a low bar, but it creates the artifact that everything else depends on.
SLSA Build Level 2 requires that the provenance be signed by an authenticated build service and that it be non-falsifiable by the developer who initiated the build. This is the critical step. At Level 2, your provenance can no longer be produced by a developer’s laptop or a shared CI machine where someone could inject a step. The provenance must come from a trusted build platform (GitHub Actions, Cloud Build, etc.) running in an environment the developer cannot directly modify. Most mature teams should be targeting Level 2 as their baseline.
SLSA Build Level 3 adds the requirement that the build environment be hardened against tampering even by a compromised build service. This means ephemeral, single-use build environments, isolation between builds, and the build process itself being verifiably based on the input source with no persistent state that could be modified between runs. This is the level that would have stopped the SolarWinds attack: even if the build server had been compromised, an attacker could not have injected code without it being detectable in the provenance.

A Level 3 build is a significant engineering investment. Most organizations I work with target Level 2 across the board and Level 3 for their highest-risk artifacts: the internal build tooling itself, shared libraries used across many services, and anything that runs with elevated privileges in production.
What Provenance Actually Contains
The provenance attestation is a JSON document formatted using the in-toto Attestation Framework and serialized as a DSSE (Dead Simple Signing Envelope). Here is what matters in it:
Builder identity: Who ran this build. For GitHub Actions, this is the GitHub Actions OIDC identity, which is cryptographically tied to the specific workflow, repository, and branch. Not a developer’s personal key. Not a shared CI credential. The platform identity.
Source repository and commit: The exact repository URL and commit SHA that was checked out. Combined with the builder identity, this means you can verify that a given artifact came from a specific commit in a specific repository.
Build entry point: Which workflow file triggered this build. Knowing the source commit is not enough if an attacker can run a different workflow file. The provenance includes the workflow path so you can verify the expected build process was actually used.
Output artifact digest: The SHA-256 hash of every artifact produced. This links the provenance document to the actual artifact.
Build parameters and environment: Relevant environment variables and parameters that could affect the build output.
When you ship this provenance document alongside your artifact (as an OCI referrer for container images, or as a separate attestation file for binaries), any downstream consumer can verify the entire chain: “this artifact has this digest, this provenance says it was produced from this commit in this repository using this workflow, and this signature from GitHub Actions’ OIDC key proves that provenance is authentic.”
Implementing SLSA with GitHub Actions
The easiest path to SLSA Build Level 2 for most teams is the slsa-framework/slsa-github-generator. This is a set of reusable GitHub Actions workflows that generate provenance automatically, with the signing happening in a separate isolated job that the developer cannot influence.
For a Go binary, the workflow looks like this:
jobs:
build:
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: |
go build -o my-binary .
- name: Generate artifact hashes
id: hash
run: |
sha256sum my-binary > checksums.txt
echo "hashes=$(cat checksums.txt | base64 -w0)" >> "$GITHUB_OUTPUT"
provenance:
needs: [build]
permissions:
actions: read
id-token: write
contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
with:
base64-subjects: "${{ needs.build.outputs.hashes }}"
The key point is that the provenance job uses the slsa-github-generator workflow, which runs in a separate GitHub Actions context controlled by the SLSA framework, not by your repository. It fetches the OIDC token from GitHub Actions, creates the provenance, and signs it using Sigstore’s Fulcio CA (part of the Sigstore transparency log ecosystem). Your repository code cannot tamper with that process.
For container images, there is a dedicated generator_container_slsa3.yml reusable workflow that integrates with Docker’s build provenance and signs the attestation as an OCI referrer attached to the image manifest.

I have rolled this out across several platform teams now, and the engineering lift is lower than most people expect. Two to three days of work to add the reusable workflow, another day or two to update release pipelines to surface the provenance artifact alongside releases, and then the ongoing cost is approximately zero. The complexity lives in the slsa-github-generator framework, not in your repository.
One thing that trips people up: the reusable workflow must be referenced by a specific version tag or commit SHA, not @main. The SLSA framework itself requires that the build definition (including the workflow that generates provenance) be pinned and auditable. Using @main would introduce exactly the kind of mutable reference that SLSA is designed to eliminate.
Verifying Provenance at Deploy Time
Generating provenance is only half the work. The other half is actually verifying it before you deploy.
The slsa-verifier CLI is the standard tool for this. For a binary:
slsa-verifier verify-artifact my-binary \
--provenance-path my-binary.intoto.jsonl \
--source-uri github.com/myorg/myrepo \
--source-tag v1.2.3
This performs several checks: verifies the signature on the provenance using Sigstore’s transparency log, checks that the builder identity matches GitHub Actions, confirms the source repository and tag match what you expect, and verifies that the artifact digest in the provenance matches the artifact you have in hand. If any of these checks fail, the command returns a non-zero exit code.
For container images, both cosign and slsa-verifier can verify OCI attestations:
slsa-verifier verify-image myregistry/myimage:v1.2.3 \
--source-uri github.com/myorg/myrepo
Where you integrate this matters. The right place is in your deployment pipeline, before the artifact touches production. In a Kubernetes deployment workflow using ArgoCD or Flux, this fits naturally as a pre-sync hook. In an OPA/Gatekeeper or Kyverno policy, you can enforce that every admitted image has a verified SLSA attestation as a cluster-wide admission control rule. That is my preferred pattern for mature setups: enforce verification at the admission layer so developers cannot accidentally bypass it by running kubectl apply directly. Our article on policy-as-code enforcement with OPA and Kyverno covers exactly how to wire this kind of check into your admission controller.

SLSA vs. SBOM: Complementary, Not Competing
I get this question constantly, so let me settle it directly. SLSA and SBOMs solve different problems and you need both.
An SBOM (Software Bill of Materials) answers “what components does this artifact contain?” It tells you about dependencies, licenses, and known vulnerabilities in those dependencies. When a new CVE drops for a library, an SBOM lets you quickly identify which of your artifacts are affected.
SLSA answers “how was this artifact built, and can I verify it?” It tells you about the build provenance and integrity of the artifact itself, regardless of what components it contains.
You can have an artifact with a perfect SBOM and no SLSA provenance (you know what’s in it but cannot verify how it was built). You can have an artifact with perfect SLSA provenance and no SBOM (you know it was built correctly but have no dependency inventory). Neither alone is sufficient.
Our article on software supply chain security, SBOMs, and Sigstore covers the SBOM side in depth. Think of SLSA as the provenance layer that sits on top of SBOM: once you know what is in your artifact, SLSA lets you prove it was assembled correctly from those components.
OpenSSF Scorecard and the Broader Ecosystem
SLSA does not exist in isolation. The OpenSSF (Open Source Security Foundation, the same organization that maintains SLSA) also maintains the OpenSSF Scorecard, a tool that evaluates open source projects on a set of security best practices and gives them a score from 0 to 10.
SLSA adoption is one of the Scorecard checks, but Scorecard also covers dependency pinning, branch protection, code review requirements, fuzzing, and vulnerability disclosure policies. For open source projects that your organization depends on, running Scorecard against your dependencies gives you a quick risk assessment. For projects your organization maintains, a high Scorecard score signals to downstream consumers that you take supply chain security seriously.
The SLSA specification also has a Source Track (currently in development as of 2025) that will extend provenance guarantees upstream into the source repository itself: verifying that code review happened, that branch protection was enforced, and that the commit was not pushed directly by a single individual. The Build Track (the current v1.0 spec) covers the build process; the Source Track will cover the entire SDLC chain from commit to artifact.
Regulatory Pressure Is Real: EU CRA and CISA SSDF
I want to be clear about the timeline here because I have seen teams dismissing SLSA as a future concern. It is not.
The EU Cyber Resilience Act requires that manufacturers of products with digital elements report actively exploited vulnerabilities within 24 hours starting September 11, 2026. Meeting that requirement without build provenance is difficult: if you cannot trace which artifact versions contain a given component, you cannot quickly determine which of your shipped products are affected. SLSA provenance, combined with an SBOM, gives you that traceability.
The US CISA Secure Software Development Framework (SSDF, based on NIST SP 800-218) mandates that federal software suppliers demonstrate build integrity controls. SLSA Level 2 or higher maps directly to the SSDF’s “PW.1” and “PS.1” control families. If you sell software to the US federal government or work in a regulated industry under similar mandates, SLSA is effectively required.
The combination of EU CRA, CISA SSDF, and growing enterprise vendor assessment questionnaires asking about build integrity means that the question is not whether you will implement SLSA but when. Starting now puts you ahead of the compliance scramble; starting in response to an audit or an incident is painful.
In my experience, organizations that treat compliance requirements as the primary driver end up building the minimum viable checkbox. The ones that treat supply chain integrity as a genuine engineering problem end up with SLSA as one piece of a broader defense-in-depth posture. That broader posture also includes secrets detection to keep credentials out of repositories, container image hardening to reduce runtime attack surface, and workload identity federation to eliminate static credentials from CI/CD systems.
Practical Implementation Path
If you are starting from zero, here is the sequence I recommend:
Week 1-2: Inventory and baseline. Run the OpenSSF Scorecard against your most critical repositories. Identify which of your artifacts are currently produced with no provenance and which already have some form of build record. The goal is to understand your current state before defining a target state.
Week 3-4: SLSA Level 1 across all critical repositories. This is lower-lift than most teams expect. For GitHub Actions shops, adding a step to generate and upload a provenance stub is a few hours of work per repository. This establishes the habit of treating provenance as a first-class artifact.
Month 2: SLSA Level 2 for your top 10 most critical artifacts. Add the slsa-github-generator reusable workflow to your release pipelines for these artifacts. Wire up slsa-verifier checks in your deployment pipelines for the same artifacts. Validate the end-to-end chain.
Month 3+: Admission control enforcement. Once you have provenance flowing for your critical artifacts, add admission control policies (via Kyverno or OPA/Gatekeeper, as covered in our policy-as-code guide) that require verified SLSA provenance for any image that wants to run in your production cluster. This is the step that turns SLSA from a passive record into an active enforcement mechanism.
Ongoing: Expand coverage and raise levels. Move from Level 2 to Level 3 for your highest-risk artifacts. Extend SLSA coverage to internal libraries, build tooling, and infrastructure automation scripts.
War Story: The Build Server Nobody Knew About
A few years ago, I was called in to help a financial services firm after a security audit flagged anomalous code in one of their internal libraries. The library was signed with the organization’s code signing certificate, the certificate was valid, and the library had been shipping in production for about eight months.
What the audit eventually turned up was that a developer had set up an unofficial Jenkins instance on a server in the company’s internal network, used it to build a patched version of the library, and signed it with a certificate from a developer machine. Nobody had noticed because the downstream services just checked that the certificate was valid, not where the build had come from.
With SLSA Level 2 in place, this attack would have been stopped at the verification step. A properly configured slsa-verifier check would have flagged immediately that the provenance for this library either did not exist or was not signed by the organization’s official CI platform. The signature on the artifact was genuine; the provenance was missing. That distinction is the entire point.
This is why I argue for treating provenance verification as an admission-control gate rather than an optional check. Developers can and do work around optional checks, not always maliciously but sometimes just to move faster. Making provenance verification mandatory at the cluster admission layer means there is no path to production for an artifact that cannot prove its lineage.
The Bottom Line
SLSA is not complicated to implement at Level 2, the level that matters most. The slsa-github-generator reusable workflows handle the hard parts. The slsa-verifier CLI makes verification straightforward. The policy integration with Kyverno and OPA/Gatekeeper is well-documented.
What is complicated is changing how your organization thinks about build artifacts. Right now, most teams treat a signed artifact as trusted. SLSA asks you to treat only an artifact with verified build provenance as trusted. That mental shift is bigger than the tooling change.
Start with your most critical artifacts. Get the provenance flowing, get the verification wired into your deployment pipeline, and then expand from there. The regulatory mandates are not going away, and the attack surface has never been larger. Cryptographic proof of how your software was built is quickly becoming table stakes for any serious production environment.
Get Cloud Architecture Insights
Practical deep dives on infrastructure, security, and scaling. No spam, no fluff.
By subscribing, you agree to receive emails. Unsubscribe anytime.
