In April 2025, the SLSA steering committee approved version 1.1 of the Supply-chain Levels for Software Artifacts specification. The release closed a year of working group iteration on the Build track, the only track currently considered stable; Source, Dependencies, and Verification tracks remain in earlier draft stages. v1.1 is incremental rather than radical — there are no new levels, and an artifact that meets v1.0 L3 will, in nearly all cases, still meet v1.1 L3 — but the spec tightens language around isolation, hermeticity, and provenance authenticity in ways that have material consequences for downstream verifiers. For defenders, the question is no longer "should we adopt SLSA?" but "are we reading the v1.1 build requirements the same way our auditor reads them?"
What actually changed between SLSA v1.0 and v1.1?
The core level definitions are unchanged. Build L1 still requires automated provenance, L2 still requires a signed authenticated build platform, and L3 still requires non-falsifiable provenance produced by an isolated builder. What changed is the surrounding precision. v1.1 explicitly defines "external parameters" — the inputs a tenant supplies to the builder — and requires that L3 provenance enumerate every external parameter, not merely the ones the platform happens to log. The "isolation strength" requirements now spell out that the builder MUST prevent tenants from injecting code into the signing key environment, not merely "should." Several normative MUSTs replaced earlier SHOULDs, which means a v1.0 attestation that quietly omitted a build-arg can fail a v1.1 verifier. The "About SLSA" page also formalizes the track-based structure, separating future Source-track work from the stabilized Build track.
How do producers verify their builders against v1.1?
Run a four-step audit. First, enumerate every external parameter your build accepts — Dockerfile path, build-args, env-vars, secrets, cache keys — and confirm the resulting in-toto Statement includes them under predicate.buildDefinition.externalParameters. Second, verify your builder's internal parameters (system-controlled values like build VM image) appear under internalParameters. Third, check that resolved dependencies under resolvedDependencies carry digests, not just URIs. Fourth, run a tamper test: try to forge a provenance by submitting a malicious workflow; an L3 builder must refuse to sign because the build identity is bound to the builder, not the tenant.
# SLSA v1.1 Build L3 in-toto Statement excerpt
_type: https://in-toto.io/Statement/v1
predicateType: https://slsa.dev/provenance/v1
subject:
- name: ghcr.io/acme/api
digest:
sha256: 4e9c0d...
predicate:
buildDefinition:
buildType: https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1
externalParameters:
workflow:
ref: refs/heads/main
repository: https://github.com/acme/api
path: .github/workflows/release.yml
vars: {}
internalParameters:
github:
actor_id: "12345"
event_name: push
runner_environment: github-hosted
resolvedDependencies:
- uri: git+https://github.com/acme/api@refs/heads/main
digest:
gitCommit: 9a8b7c...
runDetails:
builder:
id: https://github.com/actions/runner/github-hosted
metadata:
invocationId: "https://github.com/acme/api/actions/runs/123"
startedOn: "2025-05-07T03:11:42Z"
finishedOn: "2025-05-07T03:14:09Z"
What does a v1.1-compliant verifier reject?
Five failure classes that v1.0 verifiers often tolerated. Provenance signed by a key not bound to the declared builder identity. External parameters that do not match the binary's observable behavior (for example, a Dockerfile path declared as ./Dockerfile while the image was actually built from ./Dockerfile.prod). Resolved dependencies missing digests — a URI alone is no longer sufficient at L3. Provenance produced by a builder whose isolation has been documented as broken (look at the GitHub Actions cache-poisoning class of 2025 for the canonical example). And provenance whose runDetails.metadata.invocationId cannot be re-fetched against the builder's public log, because L3 implies independently verifiable audit.
Who is shipping v1.1 attestations today?
Adoption tracks where build platforms decide to upgrade. GitHub's actions/attest-build-provenance action emits SLSA v1 provenance and the SLSA team's reference verifier slsa-verifier understands v1.0 and v1.1 statements interchangeably. Google's Cloud Build, GitLab's release publish, AWS CodeBuild's new build attestation, and the Sigstore community's gitsign/cosign attest chain all produce provenance compatible with v1.1 verification today, though most still self-identify as v1.0 statements until the spec's predicate URI is updated by each implementer. Kubernetes, Curl, Tekton, and Cosign itself sign their own releases at the equivalent of L3, with provenance discoverable via Rekor.
How does v1.1 interact with the rest of the supply-chain stack?
v1.1 is intentionally narrow. It says nothing about source-code controls (Source track, draft), nothing about third-party dependency hygiene (Dependencies track, draft), and nothing about what consumers should do with provenance once they have it (Verification track, draft). Producers that want a more complete program pair v1.1 attestations with: an OpenSSF Scorecard score on the source repo, SBOMs in CycloneDX 1.7 or SPDX 3.x, optional in-toto attestations for unit-test and SAST results, and a policy engine that consumes all of the above. The point of v1.1's narrow scope is to keep the Build track stable while letting the rest of the ecosystem iterate.
What are the most common v1.1 migration mistakes?
We have reviewed roughly forty migrations from v1.0 to v1.1-aligned attestation production over the last six months, and the same four mistakes recur. First, treating external parameters as a flat key-value map when the spec wants typed structure — submitters routinely flatten workflow.ref into a single string instead of preserving the nested object, and downstream verifiers cannot then evaluate ref-specific policies. Second, copying internal parameters into external parameters because both fields look similar; the distinction is who controls the value (platform-controlled goes to internal, tenant-controlled goes to external), and getting it wrong defeats L3's tamper resistance argument. Third, omitting resolvedDependencies digests for native dependencies the build resolved at compile time (Go modules, NPM lockfile entries, Rust crates) — URIs alone fail v1.1. Fourth, signing provenance with a long-lived service-account key rather than a workload-identity-bound short-lived credential; the v1.1 isolation language specifically targets credential reuse as an L3-disqualifying pattern. None of these mistakes is exotic, but each reduces a v1.1 attestation to v1.0 quality, and consumers running strict verifiers will reject the output even though it claims compliance.
What about the draft Source and Verification tracks?
Two tracks remain in draft alongside v1.1's stable Build track. The Source track aims to characterize how source code is managed — code review enforcement, branch protection, signed commits, identity controls on commits, retention guarantees. Draft Source track levels mirror Build track levels in spirit but address a fundamentally different control set; the working group has acknowledged that aligning source-control evidence across GitHub, GitLab, Bitbucket, and Azure DevOps is harder than aligning build-system evidence because the underlying platforms expose different controls under different names. The Verification track is the consumer-side complement: how does a consumer take provenance, attestations, and SBOMs and combine them into a confidence statement about an artifact? Both tracks are months to a year from stability. Producers and consumers should not block their work on either, but should plan attestation production and verification policy in ways that can extend to those tracks when they stabilize. In practice, that means using extensible attestation predicates rather than hard-coded fields, and policy engines that accept multiple predicate types rather than treating SLSA provenance as the only meaningful signal. Organizations that pre-built rigid "is provenance present, yes/no" verification will need to refactor to accommodate Source-track and Verification-track signals; organizations that built more flexible policy engines will absorb the change with configuration updates.
How Safeguard Helps
Safeguard's policy engine consumes SLSA v1.0 and v1.1 provenance, normalizes the in-toto Statement, and runs a configurable rule set across externalParameters, internalParameters, and resolvedDependencies. Griffin AI flags drift between the declared build environment and the binary's observed behavior — for example, a Dockerfile path mismatch — surfacing the exact failure class v1.1 verifiers are supposed to reject. Build-level promotion gates can be configured to require minimum SLSA build level per environment (L2 for staging, L3 for production), and policy can require that the signing identity match an allowlist of approved builders. For producers still on v1.0 attestations, Safeguard's migration report highlights every place where external parameters, dependency digests, or invocation metadata fall short of v1.1's stricter MUSTs, giving security teams a concrete remediation list rather than a generic "upgrade your provenance" recommendation.