Join our Newsletter — 33% off our NHI Course
Home› Guides› SLSA and Build Provenance Guide
Guide Software & AI Supply Chain

SLSA and Build Provenance Guide

← All guides
By Lalit Choda, NHI Mgmt Group Updated 16 October 2026 17 min read
On this page

A signed release proves that someone with a key signed it, not that it was built from the source you reviewed on a build system nobody tampered with. SLSA (Supply-chain Levels for Software Artifacts) and in-toto attestations close that gap by recording, in a signed, tamper-evident and machine-checkable form, which builder produced an artefact, from which source revision, with which parameters. This guide covers the SLSA v1.2 Build and Source tracks, the anatomy of a provenance attestation, keyless signing with Sigstore and the workload identities behind it, producing provenance on GitHub, npm and PyPI, hermetic and reproducible builds, and verifying provenance at deploy time with policy engines. It is for platform engineers, release engineers and application security teams. Dependency selection, SBOMs and malicious packages are outside its scope; pipeline credentials are covered in the CI/CD Pipeline Identity Security Guide.

Key takeaways

  • SLSA v1.2 is the current approved specification and has two tracks: Build (L0 to L3) and the new Source track (L1 to L4).
  • Provenance is only useful if someone verifies it against expectations: the builder identity, the source repository, the build type and the external parameters, with unknown parameters causing failure.
  • Build L3 is mostly about identity and secrets: isolated runs, and provenance signing material that user-defined build steps cannot reach.
  • Keyless signing moves trust to the builder's workload identity, so the OIDC trust configuration and the identity you pin at verification become the controls.
  • Verify where it is enforceable: at registry upload, at install, or in a Kubernetes admission controller, starting in audit mode and moving to enforce once the false positives are gone.

What SLSA covers in v1.2

SLSA is an OpenSSF specification. The specification index lists v1.2 with status "Approved", alongside v1.1 and a working draft. The change log for v1.2 says the Source track was added, the threat model was updated to cover the threats it mitigates, and the specification was reorganised to support multiple tracks. No Build track changes are listed, so Build levels mean the same in v1.0, v1.1 and v1.2. Older material citing "SLSA 4" refers to the earlier v0.1 specification, which used a single track numbered 1 to 4.

Build track

LevelNameCore requirementThreat it addresses
Build L0No guaranteesNone: the absence of SLSANone
Build L1Provenance existsThe build platform automatically generates provenance recording "what entity built the package, what build process they used, and what the top-level input to the build were""Mistakes, documentation": release errors, missing inventory, inability to rebuild
Build L2Hosted build platformBuilds run on a hosted platform that must "Generate and sign the provenance itself""Tampering after the build": altering the artefact in storage or a registry
Build L3Hardened buildsThe platform must "prevent runs from influencing one another, even within the same project" and keep provenance signing secrets away from user-defined build steps"Tampering during the build": insiders, stolen credentials, other tenants, cache poisoning between runs

L1 provenance is unauthenticated, so its value is documentation. L2 is the first level that resists an attacker; L3 is the realistic target for anything shipped to customers or deployed to production.

Source track

LevelNameWhat the source control system must do
Source L1Version controlledStore and manage source in a modern version control system
Source L2History and ProvenanceKeep branch history "continuous, immutable, and retained", and issue a source provenance attestation for each new revision
Source L3Continuous technical controlsContinuously enforce the organisation's technical controls (for example required checks) on named branches and tags
Source L4Two-party review"Changes in protected branches MUST be agreed to by two or more trusted persons prior to submission"

The source control system communicates the level it has verified through a Source Verification Summary Attestation (VSA), which tells consumers "what high level security properties a given source revision meets". Two-party review may grant trusted robots, such as Dependabot, a standing exception, which makes those bot identities high-value targets in their own right. Note that the VSA verifiedLevels field enumerates Source levels 0 to 3 in v1.2, even though L4 is defined.

Anatomy of a provenance attestation

SLSA provenance is a predicate inside an in-toto attestation. The in-toto Attestation Framework has four layers: the Predicate "Contains arbitrary metadata about a subject artifact"; the Statement "Binds the attestation to a particular subject and unambiguously identifies the types of the predicate"; the Envelope "Handles authentication and serialization" (in practice usually a DSSE envelope); and the Bundle groups several attestations. The Statement type is https://in-toto.io/Statement/v1 and the SLSA predicate type is the exact string https://slsa.dev/provenance/v1, which verifiers should match as a string rather than resolve.

FieldMeaningWhat a verifier does with it
subject[].digestArtefacts the build produced, by name and hashMust match the digest of the artefact being installed or deployed
runDetails.builder.id"URI indicating the transitive closure of the trusted build platform"Looked up in the verifier's roots of trust to decide the maximum Build level
buildDefinition.buildTypeTemplate that says how to interpret parameters and dependenciesMust equal the expected build type
buildDefinition.externalParametersParameters "under external control, such as those set by a user or tenant"Untrusted: compare with expectations (repository, ref, workflow path); fail on anything unrecognised
buildDefinition.internalParametersParameters set by the build platform itselfOptional; useful in incident response
buildDefinition.resolvedDependenciesArtefacts needed at build time, as URIs with digestsOptional recursive verification; evidence for a hermeticity review
runDetails.metadatainvocationId, startedOn, finishedOnLinks the artefact to a specific run and its logs
runDetails.byproductsOther outputs such as logs, not the build outputDebugging and forensics

The same framework carries other predicates, such as SBOMs and test results. Provenance answers "where and how was this built", not "is it safe".

Where identity fits: keyless signing and builder identity

Every provenance signature is made by a non-human identity. Traditionally that was a long-lived private key stored as a CI secret, readable by any compromised build step. Sigstore replaces it with keyless signing:

  1. The build job generates an ephemeral key pair and requests an OIDC token from its CI platform. The token's claims describe the workload: repository, workflow, ref and trigger.
  2. Fulcio, the Sigstore certificate authority, verifies the token and "issues a short-lived certificate bound to the provided identity and public key". Fulcio certificates are "valid for 10 minutes".
  3. The job signs the attestation, discards the private key, and the signing event is recorded in Rekor, "an immutable, append-only ledger".
  4. Verifiers check the signature, that the certificate identity matches an expected identity, that the certificate chains to the Sigstore root, and the Rekor inclusion proof, which shows the certificate was valid when the signature was made.
  • Pin the identity, not just the issuer: accepting any certificate from https://token.actions.githubusercontent.com accepts anything any GitHub repository built. Pin the repository and, for L3, the reusable workflow path. With Cosign that means --certificate-identity (or a tightly anchored --certificate-identity-regexp) plus --certificate-oidc-issuer.
  • Treat the OIDC trust configuration as privileged: the same job token that obtains a signing certificate can usually be exchanged for cloud credentials. Scope federation trust to repository, branch and environment. See the Cloud Workload Identity Guide.
  • Keep signing material out of user-defined steps: the L3 requirement that signing secrets be inaccessible to build steps is the same principle as not exposing deployment secrets to pull request builds. Where you still sign with stored keys (air-gapped or private registries), hold them in a KMS or HSM and grant the signer a sign-only permission. See the Cryptographic Key Management Guide.
  • Remove publish tokens once trusted publishing works: npm and PyPI trusted publishing exchange the CI job's OIDC identity for publication, so long-lived registry tokens can be revoked. See the Secrets Management Guide.
  • Monitor the transparency log: an unexpected Rekor entry under your repository identity is a strong compromise signal.

Producing provenance on common platforms

PlatformMechanismKey requirements and limits
GitHub ActionsArtifact attestations with actions/attest; signed with SigstorePermissions id-token: write, contents: read, attestations: write (plus packages: write for images). Public repositories on all current plans; private and internal repositories need GitHub Enterprise Cloud
GitHub Actions, L3 patternBuild in a reusable workflow that also generates the attestationGitHub documents this as helping "achieve SLSA v1.0 Build Level 3"; verify with --signer-workflow pinned to the reusable workflow. The OpenSSF slsa-github-generator uses the same pattern
npmnpm publish --provenance, or automatic with trusted publishingGitHub Actions or GitLab CI/CD on "a supported cloud CI/CD provider using a cloud-hosted runner"; npm CLI 9.5.0 or later; the repository field must match the source; consumers run npm audit signatures
PyPIPEP 740 attestations via Trusted PublishingPublishers: GitHub Actions, GitLab CI/CD, Google Cloud, ActiveState. Two predicate types, PyPI Publish and SLSA Provenance; at most two attestations per file
Google Cloud BuildBuild provenance and attestations consumed by Binary AuthorizationBinary Authorization enforces policy at deploy time for GKE, Cloud Run and other runtimes, and offers an SLSA check in continuous validation
Self-hosted CICosign or in-toto tooling called from the pipelineReaching L2 or L3 depends on the platform's own isolation and on keeping signing out of user steps; a self-hosted runner shared across projects will not meet L3

npm states the limit plainly: provenance does not guarantee a package is free of malicious code; it gives a verifiable link to source and build instructions.

Hermetic, isolated and reproducible builds

SLSA L3 requires isolation between runs. Two stronger properties sit beyond the current Build levels and are worth pursuing for your most critical artefacts:

  • Ephemeral and isolated: each run starts in a fresh VM or container, with no cache or workspace shared with other runs or with untrusted pull request builds. Shared caches are a common way one run influences another.
  • Hermetic: every input is declared in advance and pinned by digest, and the build has no network access once inputs are fetched. Hermeticity makes resolvedDependencies complete rather than best effort, and stops a build from silently pulling a newly poisoned dependency or a retagged action.
  • Reproducible: "A build is reproducible if given the same source code, build environment and build instructions, any party can recreate bit-by-bit identical copies of all specified artifacts." Relevant environment attributes include dependency versions, build flags and environment variables such as locale. Common fixes are normalising timestamps (the SOURCE_DATE_EPOCH convention), file ordering and build paths.
  • Independent rebuild: reproducibility only pays off when a second, separately administered builder rebuilds and compares hashes. That is the one control that detects a compromised build platform signing valid provenance for a tampered artefact.

Hermetic builds are achievable for most services with lockfiles and digest-pinned base images; full reproducibility is costly and usually justified only for widely distributed software, security agents and firmware.

Verifying provenance before use

The SLSA verification procedure has three steps. First, check the envelope signature against your roots of trust, confirm the subject digest matches the artefact, confirm the predicate type, and look up the builder's level. Second, "You SHOULD compare the provenance against expected values" for at least the builder identity, the canonical source repository, the build type and the external parameters, and "Any unrecognized externalParameters SHOULD cause verification to fail." Third, optionally verify dependencies recursively, using VSAs to record earlier results.

Forming expectations

  • Defined in source: the repository declares its expected builder and workflow, and the package name is bound to that repository. Best for internal software.
  • Defined by producer: the producer publishes expectations through an authenticated channel that resists unilateral change. Useful for suppliers.
  • Trust on first use: accept the first observed values and alert on change. The pragmatic option for third-party open source packages.

Where to enforce

Enforcement pointExample toolingStrengthWeakness
Registry at uploadPackage ecosystem checks; internal artefact repository policySLSA calls this "RECOMMENDED whenever possible"; one check protects every consumerNeeds control of the registry
CI before promotiongh attestation verify, cosign verify-attestation, npm audit signaturesEasy to add; blocks bad artefacts before they reach production registriesBypassed by anyone who deploys outside the pipeline
Kubernetes admissionKyverno verifyImages with keyless attestors and SLSA attestation conditions; Sigstore policy-controllerEnforced at the last moment; covers manual deploymentsOnly covers what the cluster runs; webhook availability becomes a dependency
Managed cloud deploy policyGoogle Binary Authorization attestors, dry-run mode and continuous validationBlocked deployments logged to Cloud Audit Logs; continuous checks on running PodsProvider-specific
MonitorService that continuously verifies and publishes resultsCatches drift and retroactive findingsDetects rather than prevents

A Kyverno rule pins a keyless attestor with subject, issuer and rekor.url, can require an attestation of type https://slsa.dev/provenance/v1 with conditions on predicate fields such as buildDefinition.buildType, and by default rewrites image tags to digests (mutateDigest). Deploy by digest regardless: a tag can be moved after verification.

Choosing a target level

  • Small teams on hosted CI: turn on GitHub artifact attestations or registry trusted publishing for everything you release. That reaches Build L2 at almost no cost; move release builds into a reusable workflow for L3.
  • Large organisations with many pipelines: standardise on a few central build templates that produce L3 provenance, and make "built by an approved template" the deploy-time rule, so expectations live in one place.
  • Software vendors: publish provenance with every release, plus the builder identity and verification command customers need to form expectations.
  • Consumers of open source: verify where the ecosystem supports it (npm, PyPI, signed container images), use trust on first use, and alert when a package that had provenance publishes a release without it.
  • L3 versus reproducible: L3 gives breadth across all services; independent reproducible rebuilds give depth on a few critical artefacts and are the only one of the two that protects against the build platform itself.

Implementing build provenance

  1. Inventory release paths: every pipeline that produces something deployed or distributed, its runner type, and where signing keys or publish tokens live.
  2. Generate provenance (L1 to L2): enable artifact attestations or trusted publishing on hosted runners and deploy by digest. Nothing is enforced yet.
  3. Replace stored keys: move to keyless signing, remove signing keys and registry tokens from CI secrets, and tighten OIDC trust policies to repository, branch and environment.
  4. Harden for L3: move release builds into reusable workflows or central templates, use ephemeral runners, and stop sharing caches between trusted and untrusted runs.
  5. Verify in audit mode: add verification in CI and an admission policy with failureAction: Audit (Kyverno) or dry-run (Binary Authorization). Review every failure for two to four weeks; most will be images from unattested pipelines or third parties.
  6. Enforce in rings: enforce first on a non-production cluster, then production namespaces owned by teams already compliant, then everything. Define an exemption list with owners and expiry dates.
  7. Plan rollback and break-glass: rollback is switching the policy back to audit, a logged platform team action. Break-glass deployments must alert and be reviewed.
  8. Add hermetic and reproducible builds for the highest-risk artefacts once enforcement is stable.

Detection and measurement

  • Admission and policy logs: denied and audited deployments, by namespace and image source.
  • Transparency log monitoring: signing events in Rekor for your repository identities that do not correspond to a known pipeline run.
  • CI audit logs: changes to release workflows, runner groups and OIDC trust policies.
  • Registry events: publications made with tokens rather than trusted publishing, and releases that lack provenance when earlier ones had it.

Metrics that show it is working:

  1. Percentage of production deployments whose image digest has verified L3 provenance.
  2. Number of long-lived signing keys and registry publish tokens remaining in CI secrets (target zero).
  3. Admission policy mode coverage: share of clusters and namespaces in enforce rather than audit.
  4. Count and age of active exemptions and break-glass deployments.
  5. Percentage of third-party packages and base images in use that publish verifiable provenance.
  6. For critical artefacts, the share of releases independently rebuilt with matching hashes.

Common failure patterns

  • Signing without verifying: provenance is produced and stored, but nothing checks it before deployment.
  • Verifying the issuer but not the identity: a policy that accepts any GitHub Actions certificate, or a loose regular expression, lets an attacker's own repository produce "valid" provenance.
  • Treating valid provenance as safe code: provenance shows where an artefact was built. If attacker code runs inside the legitimate workflow, the output carries genuine provenance. The Ultralytics PyPI compromise combined a GitHub Actions injection with a leftover PyPI token; workflow hardening and token removal are both needed.
  • Compromised build platform: SLSA L3 trusts the builder. In the SolarWinds compromise malicious code entered during the build and shipped with a legitimate signature, the case independent reproducible rebuilds are designed to catch.
  • Unverified downloads in pipelines: scripts piped from the internet into a shell bypass every attestation. The Codecov breach altered a widely used CI script to harvest secrets, and the exposure of the HashiCorp release signing key through it shows why signing material must not be reachable from build steps.
  • Mutable inputs: builds that reference tags rather than digests for actions, base images and dependencies are not hermetic. The tj-actions/changed-files compromise repointed existing tags at malicious code.

Framework mapping

FrameworkReferenceHow provenance contributes
NIST SSDF (SP 800-218)PO.5, PS.2.1, PS.3.1, PS.3.2Secure build environments; integrity verification information for releases; archive releases; collect and share provenance data
NIST SP 800-53 Rev. 5SR-4, SR-11, SI-7, SI-7(15), CM-14, SA-10Provenance, component authenticity, software integrity, code authentication, signed components, developer configuration management
NIST CSF 2.0GV.SC, PR.PS-06Supply chain risk management; secure software development practices
ISO/IEC 27001:2022 Annex AA.5.21, A.8.4, A.8.25, A.8.32ICT supply chain security, access to source code, secure development life cycle, change management
CIS Controls v8.1Control 16Application software security, including third-party component management
MITRE ATT&CK v20T1195.002 Compromise Software Supply ChainProvenance verification and independent rebuilds detect manipulated software before it reaches the consumer

Practitioner checklist

  • Record the SLSA Build level of every release pipeline and set L3 as the target for production and customer-facing artefacts.
  • Generate signed provenance for all release artefacts and deploy by digest, never by tag.
  • Replace stored signing keys and registry publish tokens with keyless signing and trusted publishing, then revoke the old credentials.
  • Scope OIDC federation and signing identities to specific repositories, branches, environments and reusable workflows.
  • Verify provenance against expectations (builder, repository, build type, external parameters) and fail on unknown parameters.
  • Run admission policies in audit mode first, then enforce in rings with owned, expiring exemptions.
  • Monitor the transparency log, CI audit logs and registry events for signing or publishing outside known pipelines.
  • Pin actions, base images and dependencies by digest, and isolate release builds from untrusted runs and shared caches.
  • Pilot reproducible builds with an independent rebuilder for your most widely distributed artefacts.

Standards and references

Related NHI Mgmt Group resources: CI/CD Pipeline Identity Security Guide · Cloud Workload Identity Guide · Secrets Management Guide · AI Supply Chain and AI-BOM Guide · Machine Identity, PKI and Certificate Lifecycle Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Written and reviewed by Lalit Choda, NHI Mgmt Group. Last updated 16 October 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org