SLSA Framework: A Practitioner Guide to Software Supply Chain Security Levels and Provenance

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
The SolarWinds compromise was executed by modifying the build process to inject malicious code into signed, legitimate software updates. The XZ Utils backdoor was injected by a contributor who gained maintainer trust over years. Both attacks demonstrate the same principle: the source code repository and the published artifact are two different things, and the gap between them -- the build pipeline -- is an attack surface that traditional application security controls do not cover. SLSA provides a framework for closing this gap by requiring that build pipelines produce verifiable provenance, that builds run in isolated environments, and that source code changes undergo review before being built. This guide covers the SLSA framework requirements, how to implement provenance generation in GitHub Actions, and how to verify provenance in your deployment pipeline.
SLSA Build Levels: What Each Level Requires and Guarantees
SLSA 1.0 defines three build levels with progressively stronger guarantees about build integrity. Each level builds on the previous -- reaching L3 requires meeting all L1 and L2 requirements as well.
Build Level 1: Provenance exists
SLSA Build L1 requires that the build process produces a provenance document containing the builder identity, source repository, and output artifact digest. No requirements are made about the trustworthiness of the build platform or the provenance generation process. An attacker who controls the build environment could produce forged provenance. L1 provides a documented build audit trail and enables tooling to read provenance, but does not provide strong security guarantees. It is the easiest level to achieve and a prerequisite for L2 and L3.
Build Level 2: Hosted, non-forgeable provenance
SLSA Build L2 requires that the build runs on a hosted, managed build platform (GitHub Actions hosted runners, Google Cloud Build, AWS CodeBuild) and that provenance is generated by the platform itself -- not by user-controlled build scripts. This means the provenance cannot be forged by modifying the build script: the platform signs the provenance with its own identity, which the build script cannot access. L2 prevents a compromised build script from producing false provenance claims. GitHub Actions with SLSA GitHub Generator meets L2.
Build Level 3: Hardened, hermetic build environment
SLSA Build L3 adds requirements for build environment isolation and hardening. The build runs in an ephemeral, isolated environment with no shared state between builds. The build cannot access the network during execution (hermetic). The build environment cannot be influenced by user-controlled pipeline code. Source code must have undergone two-party review (branch protection with required reviewers) before being built. L3 provides the strongest supply chain guarantee: even if an attacker compromises a developer account, they cannot get malicious code built without passing two-party review.
Choosing the right SLSA level for your artifacts
For internal applications, SLSA Build L2 is a practical target: it provides non-forgeable provenance from a managed build platform and can be achieved in GitHub Actions today with the SLSA GitHub Generator. SLSA Build L3 is appropriate for artifacts distributed to external consumers (open-source libraries, vendor-distributed software, platform binaries). Start with L1 (provenance generation) to enable tooling, upgrade to L2 when feasible, and plan for L3 on critical artifacts distributed externally.
Generating SLSA Provenance with the SLSA GitHub Generator
The SLSA GitHub Generator provides reusable GitHub Actions workflows that generate SLSA provenance for multiple artifact types (generic binaries, Go binaries, container images, Maven/Gradle artifacts). It is the practical implementation of SLSA provenance generation in GitHub Actions.
Generic binary provenance generation
To generate provenance for any artifact type, call the generic generator workflow: in your release workflow, after building the artifact, add a job that calls slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2 with inputs hash (SHA-256 hash of your artifact) and filename. The generator runs in a separate job, produces a signed .intoto.jsonl provenance file, and uploads it alongside the release artifact. The generator job uses a distinct OIDC identity from your build job, meeting SLSA L3 requirements.
Container image provenance for OCI registries
For container images, use the container image generator: generator_container_slsa3.yml. Pass the image digest (from the docker push output) as input. The generator produces provenance attesting that the image at that digest was built by your GitHub Actions workflow from the specified source repository and commit. The provenance is stored as an OCI artifact in the registry alongside the image, discoverable via the OCI referrers API.
Computing artifact hashes for provenance input
The SLSA generator requires the SHA-256 hash of your artifact as input. In your build job: HASH=$(sha256sum myapp-binary | awk '{print $1}') and pass it to the generator via job output. For multiple artifacts, compute a single JSON hash file: sha256sum artifact1 artifact2 > hashes.txt, base64-encode it, and pass the encoded value as the hash input. The generator will verify each artifact against its expected hash in the provenance.
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
Integrating cosign with SLSA Provenance
SLSA provenance attests to build integrity. cosign (Sigstore) attests to artifact identity by signing the artifact itself. Together they provide a complete chain: provenance proves the build process was legitimate, and the cosign signature proves the artifact has not been modified since the provenance was generated.
Sign artifacts with cosign in GitHub Actions
After building the artifact and generating SLSA provenance, sign the artifact with cosign using keyless signing: cosign sign-blob --yes --output-certificate artifact.pem --output-signature artifact.sig myapp-binary. The OIDC token from the GitHub Actions runner is used to obtain a Fulcio certificate. The signature and certificate are uploaded alongside the binary. The signing event is logged in the Rekor transparency log, providing an immutable audit trail.
Sign OCI images with cosign
For container images: cosign sign --yes myregistry/myapp@sha256:<digest>. The keyless signing process uses the runner's OIDC identity. The signature is stored in the registry as an OCI reference artifact attached to the image digest. Consumers can verify: cosign verify --certificate-identity-regexp 'https://github.com/myorg/myrepo' --certificate-oidc-issuer https://token.actions.githubusercontent.com myregistry/myapp@sha256:<digest>.
Attach provenance attestation to OCI images
cosign attest integrates SLSA provenance with OCI images: cosign attest --yes --predicate provenance.json --type slsaprovenance myregistry/myapp@sha256:<digest>. This stores the SLSA provenance as an OCI attestation attached to the image in the registry. The attestation can be retrieved and verified with cosign verify-attestation, and policy engines like Sigstore Policy Controller or OPA can enforce that images without valid SLSA provenance attestations are not admitted.
Verifying SLSA Provenance in the Deployment Pipeline
Generating provenance is only half of the SLSA model -- the other half is verifying provenance at the point of consumption before an artifact is deployed or used. Without verification, provenance generation is a logging exercise rather than a security control.
Verify with slsa-verifier before deployment
Install slsa-verifier (go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@latest). To verify a binary: slsa-verifier verify-artifact myapp-binary --provenance-path myapp-binary.intoto.jsonl --source-uri github.com/myorg/myrepo. To additionally verify a specific tag: add --source-versioned-tag v1.2.3. Integrate this command into your deployment pipeline as a mandatory step that fails the pipeline if verification does not succeed. A failed verification means the artifact cannot be traced to a trusted build of the specified source.
Enforce SLSA provenance in Kubernetes admission control
For container images, use Sigstore Policy Controller (admission webhook for Kubernetes) to enforce that all images deployed to specific namespaces have valid SLSA provenance attestations and cosign signatures. Create a ClusterImagePolicy resource specifying the expected OIDC issuer and subject pattern for the provenance signer. Images without valid attestations matching the policy are rejected at admission time before the pod is created.
Verify provenance in package manager workflows
For Go modules and npm packages, verification tooling is still maturing but available. npm has experimental provenance support: packages published from GitHub Actions with SLSA provenance show a 'Provenance' badge on the npm registry. Go's vulnerability database integrates with supply chain tooling. For Java artifacts published to Maven Central, slsa-verifier supports JAR verification via the Maven Central provenance API. Check the SLSA tools ecosystem page for the current state of language-specific verification.
SLSA vs SBOM: Complementary Controls for Supply Chain Security
SLSA and SBOMs are frequently mentioned together because both address software supply chain security, but they answer different questions. Understanding their complementary relationship helps organizations deploy both effectively.
SLSA proves how an artifact was built
SLSA provenance answers: was this binary built from the source code I can inspect? Was it built by a trusted, isolated build platform? Did the source code undergo required review? It does not tell you what is in the artifact -- only that the artifact came from a specific, verifiable build process. An artifact can have perfect SLSA L3 provenance and still contain a vulnerable dependency that needs patching.
SBOM lists what is in an artifact
An SBOM (in CycloneDX or SPDX format) enumerates the components, libraries, and their versions included in an artifact, along with their licenses and known vulnerability identifiers. It answers: does this artifact contain Log4j 2.14.1? Is this dependency licensed under a GPL license that requires source disclosure? SBOMs enable vulnerability management -- you can query an SBOM against a CVE database to find vulnerable components. They do not prove how the artifact was built.
Use both: SLSA for build integrity, SBOM for component risk
The complete supply chain security posture requires both. Generate SLSA provenance in the build pipeline to prove build integrity. Generate an SBOM using syft, Trivy, or your build tool's SBOM plugin at build time to document components. Attach both to the release artifact. Verification at deployment time checks the SLSA provenance (was it built from the right source?) and scans the SBOM against a vulnerability database (does it contain known-vulnerable dependencies?). EO 14028 and NIST SP 800-218 (SSDF) both require SBOM generation; SLSA provides the build integrity complement that SBOMs do not cover.
The bottom line
SLSA implementation is a maturity journey: start with Build L1 by integrating the SLSA GitHub Generator into your release workflows to generate provenance for your most critical artifacts -- the overhead is a single reusable workflow call. Upgrade to L2 by ensuring builds run on hosted GitHub Actions runners rather than self-hosted ones. Plan for L3 on externally distributed artifacts by enabling branch protection with required reviewers and hermetic dependency management. Pair SLSA provenance with cosign signing and integrate slsa-verifier into deployment pipelines as a mandatory gate. Add SBOM generation alongside SLSA to cover the component risk surface that provenance does not address. Together, these controls implement the supply chain security requirements of EO 14028 and NIST SSDF and provide verifiable defense against build process compromise attacks.
Frequently asked questions
What does SLSA provenance contain and who signs it?
A SLSA provenance attestation is a JSON document in the in-toto attestation format that contains: the builder identity (e.g., the GitHub Actions runner with its OIDC identity), the source repository URL and commit SHA, the build trigger (the workflow file that initiated the build), build parameters (any inputs that affected the build), the invocation ID (a unique build run identifier), and the output artifact digest (SHA-256 hash of the built artifact). The provenance is signed by the build platform -- in GitHub Actions with SLSA GitHub Generator, it is signed using Sigstore's keyless signing with the runner's OIDC identity. The signature is stored in the Rekor transparency log.
What is the difference between SLSA Build L1, L2, and L3?
Build L1 requires provenance to exist and be available, but makes no requirements about the trustworthiness of the build platform. An attacker who controls the build platform could produce fake provenance. Build L2 requires that the build platform is a hosted, managed service (not a self-managed runner) and that the provenance is generated by the platform itself rather than by user-controlled code in the build. This means the provenance cannot be forged by the build script. Build L3 additionally requires that the build runs in an isolated, ephemeral environment that cannot be influenced by previous builds or external input during the build, that the build environment is hardened against tampering, and that the source code underwent two-party review before being built.
What is a hermetic build and why does SLSA require it?
A hermetic build has no network access during the build execution and resolves all dependencies from a locked, pre-fetched set of inputs. Non-hermetic builds fetch dependencies at build time from the internet, which means the artifact is influenced by whatever version of the dependency was available at that moment -- an attacker who controls a package registry can inject a malicious version into a non-hermetic build even without modifying the source code. Hermetic builds prevent this: all inputs are fixed before the build starts, the build runs without network access, and the output is fully determined by the fixed inputs.
How is SLSA related to in-toto?
SLSA provenance attestations use the in-toto attestation framework as their underlying specification. in-toto is a framework for defining supply chain policies and producing link metadata that documents steps in the supply chain. SLSA uses the in-toto Attestation Framework's envelope format (predicateType and predicate fields) for provenance documents, specifically with predicateType 'https://slsa.dev/provenance/v1'. You can think of in-toto as providing the vocabulary and format and SLSA as providing the specific requirements and trust levels for build provenance.
What is the SLSA GitHub Generator and how does it work?
The SLSA GitHub Generator is a reusable GitHub Actions workflow maintained by the SLSA team that generates SLSA provenance for build artifacts. Your workflow calls the generator as a reusable workflow, passing the artifact and its hash. The generator runs in a separate workflow job with its own OIDC identity (distinct from the build job's identity), produces a signed SLSA provenance attestation, and uploads it as a release asset alongside the artifact. Because provenance generation runs in a separate job controlled by the generator (not your build script), the provenance meets SLSA Build L3 requirements when using GitHub's hosted runners.
How does SLSA differ from an SBOM and do I need both?
SLSA provenance answers 'How was this artifact built and by whom?' -- it proves build integrity and chain of custody. An SBOM (Software Bill of Materials) answers 'What components are in this artifact?' -- it lists all dependencies, their versions, and their licenses. They are complementary, not alternatives. SLSA provenance tells you the artifact was built from a specific commit by a verified build platform. The SBOM tells you what libraries are included so you can check for known CVEs. Supply chain security requires both: provenance to verify build integrity and SBOM to assess component risk.
How do I verify SLSA provenance before deploying an artifact?
Use the slsa-verifier CLI tool. For a binary artifact: slsa-verifier verify-artifact myapp-binary --provenance-path provenance.intoto.jsonl --source-uri github.com/myorg/myrepo --source-versioned-tag v1.2.3. This verifies that the provenance signature is valid (checking the Rekor transparency log), the artifact digest in the provenance matches the artifact you have, the source repository matches what you expect, and the build platform meets the claimed SLSA level. Integrate this verification step into your deployment pipeline as a mandatory gate before any artifact is deployed.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
