A release artifact can have the expected filename, version, and download location without being the artifact your release process was supposed to produce. A compromised publishing account, an unexpected build path, or a mistake in release automation can put different bytes in front of users while everything around those bytes still looks familiar.
Checking an artifact’s hash helps answer whether the bytes changed relative to a known hash. It does not, by itself, answer where that hash came from or whether those bytes were built from the intended source by an approved build process.
Build provenance addresses that missing link. It is verifiable information describing where, when, and how a software artifact was produced. Used correctly, it lets a consumer evaluate a statement such as: “this exact artifact was produced by this trusted builder from this expected source revision under these build conditions.”
This article develops a practical mental model for build provenance. You will learn what a provenance attestation needs to bind together, what a verifier should check, which supply-chain failures this reduces, and why a valid attestation is evidence rather than a universal guarantee that software is trustworthy.
The security question is about origin, not just bytes
Suppose a deployment system receives payments-service.tar.gz. It calculates a digest and gets:
artifact digest: 8f3c...91a2A cryptographic digest is useful because a different artifact will, under the assumptions of a suitable hash function, almost certainly have a different digest. If a trusted release record already says that 8f3c...91a2 is the expected digest, the deployment system can detect accidental or malicious substitution after that record was created.
But consider a weaker workflow:
1. Build or obtain an artifact.
2. Publish the artifact.
3. Calculate its digest.
4. Publish that digest beside it.If the same compromised release path can replace both the artifact and the published digest, the digest still matches. The verifier has confirmed consistency between two attacker-controlled values, not the artifact’s intended origin.
The missing question is:
Who is making the claim that these bytes came from the build we intended, and what evidence supports that claim?
Build provenance gives that claim a structured form that can be authenticated and checked against policy.
Think in terms of four bindings
A useful provenance mental model connects four things:
artifact <-> source <-> build process <-> builder identityEach connection matters.
The artifact must be identified by content, normally with a cryptographic digest. A filename is not enough because names can be reused or replaced.
The source identifies the input revision that the build used, such as a particular version-control commit rather than a movable branch name.
The build process describes the relevant build definition and parameters. This helps distinguish an approved release workflow from some other process that happens to consume the same source.
The builder identity identifies the build platform or trusted build environment that is claiming to have performed the build.
If one binding is missing, a verifier can answer fewer security questions. Knowing the source without binding the output digest does not prove which artifact came from it. Knowing the output digest without the source does not tell you what was built. Knowing both without authenticating the builder may leave the claim open to fabrication.
See the smallest useful verification
Imagine an organization permits production deployments only when an artifact was built from its release repository by an approved hosted builder.
A simplified provenance record might communicate these facts:
subject digest: sha256:8f3c...91a2
source repository: example.org/team/payments
source revision: 4b91...e220
builder identity: trusted-build.example/release
build type: payments-release-v3The exact schema and identity format depend on the provenance system. The security logic is more important than the field names.
Before deployment, the verifier can compare the artifact’s actual digest with the provenance subject and then evaluate policy:
artifact digest matches provenance subject
AND provenance authenticity is valid
AND builder identity is approved
AND source repository is approved
AND source revision is the revision selected for release
AND build type is approvedOnly if all required conditions hold does the deployment continue.
This changes the trust decision. The system no longer accepts an artifact merely because it exists in a release location. It accepts the artifact because authenticated evidence ties those exact bytes to an expected production path.
Authenticity makes provenance evidence rather than metadata
A JSON document saying “trusted builder produced this” is not useful security evidence if anyone who can upload an artifact can write the same document.
The provenance therefore needs an authenticity mechanism that the consumer can verify. A common design uses a digital signature or another authenticated attestation mechanism. The verifier establishes the identity authorized to make the attestation and checks that the attestation has not been altered after authentication.
The important trust relationship is:
verifier trusts identity X to speak for builder Ynot merely:
the signature is mathematically validA valid signature from an unknown or unauthorized identity should not satisfy the policy. Cryptographic verification establishes who authenticated the statement under the credential model; policy decides whether that identity is trusted for this build.
This distinction also matters when one signing service can represent several builders. The verifier should check the builder identity and the signer relationship required by the provenance system, rather than treating any valid signature from the broader service as sufficient.
Generate provenance inside the build trust boundary
Provenance is only as reliable as the process that records it.
Consider a build script that runs with ordinary project-controlled permissions and finishes by writing:
builder = "trusted-build"
source = current_commit
artifact = hash(output)Signing that file later does not automatically make every field trustworthy. If untrusted build steps can choose or alter security-relevant provenance fields, a malicious build may be able to make false claims about its own execution.
Stronger designs generate or verify provenance information in a part of the build platform that the build workload cannot freely control. In other words, the mechanism recording the builder identity, source inputs, and relevant build parameters should be inside the trust boundary that the verifier intends to trust.
This is an important cause-and-effect relationship:
workload writes its own security claims
-> compromise may falsify the claims
trusted build control plane records claims
-> workload has less ability to lie about its originThe exact architecture varies by build platform. When evaluating a provenance feature, ask which fields come from the trusted control plane, which can be influenced by project code, and which identities protect the final attestation.
Verify policy, not just the attestation format
A common implementation mistake is to stop after confirming that an attestation parses and its authentication is valid.
That proves too little. A perfectly authentic attestation can truthfully describe an artifact produced from the wrong repository, an unreviewed revision, an unexpected build definition, or parameters that production policy does not permit.
A useful verifier therefore has two stages:
1. Is this attestation authentic and bound to this artifact?
2. Does the authenticated statement satisfy our release policy?The second stage should be explicit. Depending on the threat model, policy may constrain:
- the expected source repository;
- the exact source revision or an independently approved release reference;
- the builder identity;
- the permitted build type or workflow;
- security-relevant external build parameters;
- required dependencies or other recorded inputs when the provenance model supports them.
Do not blindly copy every provenance field into policy. Constrain fields that distinguish an approved build from a build an attacker could legitimately request but that you would not want to deploy.
Keep the artifact identity content-based
Release names are convenient for humans but weak as security identities.
If provenance says only that it applies to service-v2.tar.gz, a different file can later receive the same name. A digest binds the statement to the artifact’s content instead.
Verification should therefore calculate the digest of the bytes being consumed and compare that value with the artifact identity recorded in the authenticated provenance. Do this on the actual artifact that will be installed or deployed, not on a nearby manifest unless the manifest is itself securely bound to the artifact through a verified scheme.
This also avoids a subtle operational mistake: verifying one object and deploying another. If a pipeline downloads an artifact, verifies it, transforms or repackages it, and then deploys the transformed result, the original provenance no longer directly identifies the final bytes. The transformation is another supply-chain step and may need its own provenance or another explicit integrity relationship.
Treat source references as immutable inputs
A branch name such as main describes a moving reference. It can point to one commit when a build runs and another commit when a verifier investigates later.
For provenance decisions, prefer source identities that resolve to immutable revisions, such as a specific commit digest. Human-friendly tags or release names can still participate in the release process, but the evidence should preserve the exact revision that was actually used.
The verifier also needs an independent rule for deciding which revision is acceptable. Provenance saying “artifact A came from commit C” does not prove that commit C was reviewed, approved, or intended for production. Those are source-control and release-policy questions.
This separation is useful:
provenance: what produced these bytes?
release policy: was that source and process authorized?Both are needed when the threat model includes unauthorized but technically valid builds.
Understand what provenance reduces and what it does not
Build provenance is especially useful against substitution and path-confusion problems in a software supply chain. It can help a consumer reject artifacts that lack evidence of an approved build origin, were produced by an unexpected builder, came from an unexpected source revision, or do not match the digest named by the attestation.
It does not prove that the source code is free of vulnerabilities or malicious logic. An approved builder can faithfully build harmful source.
It does not make a compromised trusted builder trustworthy. If an attacker controls the part of the build platform that the verifier deliberately trusts, the attacker may be able to produce artifacts and provenance that satisfy policy. Hardening the builder and limiting its authority remain necessary.
It also does not guarantee that every dependency was benign. Provenance can record dependencies and improve traceability, but the security value depends on what is captured and what the verifier checks. Dependency review, integrity controls, and vulnerability management address related but different risks.
Finally, provenance does not remove the need to protect the verifier. A deployment system that ignores verification failures, accepts arbitrary identities, or permits an easy bypass can defeat an otherwise strong attestation design.
Design failure behavior before production needs it
Verification will eventually fail for legitimate operational reasons: a builder identity changes, a release workflow is upgraded, an attestation is unavailable, or a policy is stricter than a new build path expects.
Do not respond by adding a permanent “skip provenance verification” switch to the normal deployment path.
For high-impact production artifacts, a failed required provenance check should normally stop the deployment until the evidence or policy problem is resolved. If emergency operation requires an exception path, make it explicit, narrowly authorized, auditable, and temporary. The exception should identify what requirement is being bypassed and why.
For lower-risk environments, a team may initially use provenance in observation mode to learn what valid builds look like before enforcing policy. That can be a reasonable rollout strategy, provided everyone understands that logging a mismatch does not provide the same protection as rejecting it.
Test the verifier with deliberately wrong evidence
A successful happy-path deployment proves little about policy enforcement. Add negative tests that change one security-relevant fact at a time.
Useful cases include:
correct attestation + wrong artifact digest -> reject
valid attestation + unapproved builder -> reject
valid attestation + wrong source repository -> reject
valid attestation + unapproved source revision -> reject
valid attestation + disallowed build parameters -> reject
missing required provenance -> reject when enforcement is enabledAlso test identity and policy rotation. If a builder credential or build definition must change, verify that the new identity can be introduced without temporarily accepting every identity. Controlled overlap between old and new trusted identities is safer than replacing a narrow policy with a wildcard during migration.
Operational monitoring should record why verification failed without copying secrets or unnecessary sensitive build data into logs.
Use a standard model when interoperability matters
You do not need to invent a private provenance vocabulary. The Supply-chain Levels for Software Artifacts project, commonly called SLSA, defines build provenance as verifiable information that tracks an artifact back through the build process to where it came from. Its provenance model includes artifact subjects, build definitions, resolved dependencies, and builder information.
The in-toto attestation framework provides a general structure for making authenticated statements about software supply-chain artifacts. Standards such as these are useful because producers and consumers can agree on what evidence means without designing a new format for every pipeline.
A standard schema is not the security control by itself. The important properties remain the same: authenticate the statement, bind it to the exact artifact, generate trustworthy fields inside the intended build trust boundary, and verify those fields against an explicit consumer policy.
Conclusion
Artifact integrity and artifact provenance answer different questions. A digest can tell you whether bytes match an expected value. Build provenance can provide authenticated evidence about how those bytes came to exist.
For a meaningful control, bind the provenance to the exact artifact digest, record immutable source and relevant build information, authenticate the statement through an identity your consumer deliberately trusts, and enforce a policy that describes an approved build path. Generate security-relevant provenance data where ordinary build workloads cannot simply rewrite their own history.
The practical review question is: If an attacker can publish a different artifact, what independent evidence would make our deployment system reject it? Build provenance is valuable when it turns that answer from “the filename and hash look right” into a verifiable chain from the bytes back to an authorized build.