Hash Pinning as an Audit Chain of Custody Mechanism
Cryptographic hashes replace mutable tags to prevent supply chain attacks.

Hash pinning turns a software supply chain from a string of mutable, take-it-on-faith links into something a cryptographic record can actually prove, and that shift is the subject of this piece. Every dependency, every artifact, every environment state can be traced, attested, and checked at any point in the development lifecycle, provided the right anchors get set early enough.
Most delivery pipelines trust third-party updates by default. A signed package from a publisher everyone recognizes clears nearly every automated gate a team has built, and that's precisely the hole attackers walk through. Per ReversingLabs' fourth annual Software Supply Chain Security Report, open-source malware detections rose 73% in 2025 against the year before, and exposed development secrets across major repositories climbed 11% over the same stretch ReversingLabs Software Supply Chain Security Report 2026. Those aren't rounding errors. They describe an ecosystem where the gate is checking the wrong thing.
Neither attack tripped an alarm at the door, because the name and the publisher were both legitimate. The content was the problem, not the identity attached to it bastion.tech.
The Trivy compromise shows how fast that kind of breach spreads once it's inside. Stolen CI/CD credentials moved across multiple pipelines and cascaded into Checkmarx and LiteLLM in turn, one compromised credential becoming many downstream victims. The attacker never had to force a door. They just had to ride along inside an update everyone already trusted.
The scale of the exposure is no longer a niche concern. OX Security's breach response guide found that 91% of organizations had experienced at least one software supply chain security incident ox.security. These are the kinds of numbers that move a technical debate into a boardroom one.
One structural flaw produces all of it: version tags move. A tag can be silently repointed at a new commit, and nothing downstream gets told. An assumption baked into how the ecosystem was built has gone unpatched for years, left standing because fixing it would mean rethinking how versioning works at its root. It's an assumption baked into how the ecosystem was built, and it's exactly the assumption hash pinning exists to replace. Supply chain attacks are estimated to cost the global economy $80.6 billion in 2026 (a 76% increase compared with 2023), while the Jaguar Land Rover attack alone, beginning 31 late August/early September 2025, caused £1.9 billion in damage and halted production for five weeks (dev.to).
Hash pinning: from mutable references to cryptographic identity
A version tag is a pointer. A cryptographic hash is a fingerprint. The pointer can be moved to point somewhere else entirely; the fingerprint cannot, because changing what it describes changes the fingerprint itself. SHA-256 pinning works on that principle: it checks the exact cryptographic fingerprint of an artifact before anything uses it, and if even one byte has changed, the hash no longer matches and the fetch fails. Per OX Security, pinning packages to immutable SHA-256 hashes stops automated systems from pulling in a hijacked release, even one published under a familiar name.
The technique applies across the whole stack, not just to package installs. Package dependencies, whether npm, PyPI, or Go modules, get pinned to exact versions with integrity hashes recorded in lockfiles. CI/CD actions get pinned to a commit SHA instead of a mutable tag like @v4. Container base images get pinned to an image digest rather than a floating tag such as node:24-alpine. Each of these is the same move applied to a different layer: replace a name that can be reassigned with an identity that can't.
Checksums and provenance are not the same thing, and treating them as interchangeable is where a lot of otherwise careful teams go wrong. A checksum confirms a file arrived unchanged. It says nothing about who built it or how. Per the qrcli security audit filed as GitHub issue #23, releases that ship checksums without signing satisfy integrity but not provenance, and those are two separate audit properties. Most projects today only satisfy one of them.
There's a gap even careful pinning doesn't close on its own. Pinning a direct dependency doesn't automatically pin what that dependency quietly pulls in underneath it, the transitive layer of sub-packages a developer never explicitly named. Per Google's supply chain security documentation, that hidden layer is where a lot of real attacks actually land. Functional package managers handle this differently: rather than dropping every package into one shared global folder, each package lives in its own directory, named by a cryptographic hash of its full input and dependency graph, not just the top-level version a developer typed into a manifest. That hash captures the whole tree, so a change three layers down appears as a different identity at the top.
A hash-pinned artifact as the anchor of an audit chain of custody
Physical forensics has a working model for this problem already. Chain of custody logs every hand evidence passes through, with a timestamp and a signature at each step, and breaking that chain is enough to get evidence thrown out of court. Software has a direct equivalent. Per Oligo Security's supply chain security guide, every input, meaning source code, libraries, and build scripts, along with the exact build process, its tools, environment, and parameters, and the resulting output, its checksums, binary names, and deployment targets, all need to be documented and linked together.
Build logs tied to artifacts through build IDs and hashes let a team trace any binary back to its complete build history. Trace is the operative word here, not simply verify. Verification tells you an artifact matches what it claims to be right now. Tracing tells you where it came from and every step it passed through to get there, which is the difference between confirming a fact and being able to defend it later.
Attestation tools such as in-toto, Tekton Chains, and Sigstore do the linking cryptographically, tying an artifact to its build metadata at the exact moment it's produced. If someone alters the binary afterward, the attestation no longer matches, and the tampering becomes visible rather than silent. The Affinidi supply chain provenance model, described in 2026, lays out how this plays out in practice across three steps: a developer signs a commit with a decentralized identifier, CI then issues a verifiable credential for the build artifact carrying the commit hash, a timestamp, and the builder's identity, and a verifier checks both before anything moves forward. An unsigned commit gets rejected at that first check, which means a SolarWinds-style backdoor insertion never makes it past the first link in the chain.
For an auditor, what this buys is concrete and specific. Any artifact sitting in production can be traced back to a specific build run. Any build run can be traced back to a specific, pinned set of inputs. And any change to those inputs produces a new hash, which means a new, distinct, traceable identity, rather than a silent overwrite of the old one. The chain breaks the moment a mutable reference sneaks back in: a floating tag, an unpinned base image, or a commit nobody signed. Each of those is a gap an auditor can't close and an attacker can walk straight through.
SHA pinning in CI/CD pipelines: from developer habit to organizational policy
The tj-actions and trivy-action attacks both worked the same way: an existing tag got repointed at a malicious commit, and every downstream workflow still referencing that tag pulled the malicious code on its next run, with no warning at all. That's the exact failure mode SHA pinning is built to close, since a commit SHA can't be silently reassigned the way a tag can.
GitHub responded structurally rather than leaving it to individual teams to catch on. In August 2025, the platform rolled out an update letting organizations block known-bad actions and enforce SHA pinning as policy, aimed squarely at the workflow-level risk where a single compromised action can quietly alter pipeline behavior across every repository using it, per ReversingLabs' report. Turning this into policy, rather than leaving it as a habit some engineers remember and others don't, is what actually changes outcomes at scale.
The pattern itself is simple enough to write on a whiteboard. The SHA is what binds the reference; the trailing comment keeps it readable for a human skimming the file; and tools like Dependabot understand the format well enough to keep proposing version bumps against it. Nobody loses the convenience of automated update suggestions by adopting this.
A handful of complementary controls extend the same logic from source code through to the running artifact. Setting persist-credentials: false on checkout steps that don't need to push removes the default token from disk, which narrows what an attacker gets if that step is compromised. Scheduled vulnerability scanning, run weekly rather than only on demand, matters because the dependency tree barely moves between scans, but the vulnerability database behind it changes daily. Short-lived, dynamically injected credentials beat static repository secrets, which sit there fully harvestable the moment a runner is compromised.
What unmanaged drift actually looks like has a specific shape. One 2026 GitHub project issue described three different Supabase CLI versions running at once inside the same organization: version 2.77.0 in CI, 2.110.0 in the cloud sandbox, and no pin at all on developer laptops, with the project's node:24-alpine base image carrying no digest either. Each of those mismatches is a separate gap in the audit chain, a place where the question "which version actually ran" has three different answers depending on who's asking. Once pinning is in place, every build run can attest to exactly which version of every action and dependency it used. Without it, the audit log just names a tag, and that tag may have pointed at entirely different code from one day to the next.
SBOMs as the inventory layer of the audit chain, and their limits without signing
An SBOM gives a security team an exact inventory of what's inside its software, and that inventory earns its keep during an incident. When something like Log4j breaks, or a coordinated npm attack starts spreading, a team with an SBOM can check exposure in minutes rather than manually crawling through builds and containers looking for a match. That speed difference is not incremental. It's the difference between an incident response measured in hours and one measured in days.
An SBOM lists components but does not verify build integrity or detect tampering. Per Cloudsmith's guide, most SBOMs generated today are compliance snapshots, produced at the end of a build, filed somewhere, and never looked at again. An SBOM tells a team what's in its software. It does not tell them that the software was actually built from the code they think it was, or that the build process itself got tampered with along the way, per Aquilax's analysis of artifact signing.
Transitive dependencies are one gap: version pinning and SBOM generation typically apply to declared dependencies, and the hidden sub-packages those packages pull in are often omitted or inaccurate. Provenance is the second: a checksums file confirms an artifact arrived intact, but proves nothing about who built it or whether the build process itself was sound.
Government agencies have run into this same wall from the compliance side. The July 2025 S3C2 Secure Software Supply Chain Government Summit brought together 12 participants across 6 US agencies, and what came out of it was a documented sense of frustration: nobody was quite sure how to drive real change without a compliance mandate forcing the issue, and some vendors were still refusing to hand over full SBOM files arxiv.org. That's not a technology gap. It's an incentive gap, and it's arguably the harder one to close.
One response to the fact that an SBOM captures only a single static snapshot is to stop treating the SBOM as a snapshot at all. OX Security's Pipeline Bill of Materials, or PBOM, tracks component, dependency, and configuration changes continuously across the whole pipeline instead of capturing one static picture at build time, so the inventory stays current across every build and every release rather than going stale the moment it's filed. There are two distinct gaps SBOMs alone cannot close. On provenance, a checksums file verifies the artifact arrived intact but does not prove builder identity or build process integrity (the qrcli audit, GitHub issue #23, 2026-09-04, describes this as "integrity, not provenance"). The SBOM layer directly enables certain compliance hooks. SOC 2 CC9.2 requires documented vendor/third-party risk management. ISO 27001 A.5.21 addresses ICT supply chain security. Under the EU Cyber Resilience Act, SBOMs and verifiable build integrity are upcoming regulatory requirements for many organizations, with SBOM obligations applying from December 11, 2027, per bastion.tech's guide.
SLSA levels and Sigstore: adding provenance attestation on top of the hash
SLSA gives the industry a shared ladder for build integrity, defined across four levels, each one tightening the chain a notch further. Level 1 asks only that the build process be documented and not run by hand. Level 2 requires the build to run on a hosted build service, with provenance recorded as a signed attestation rather than taken on trust. Level 3 raises the bar again: builds have to be isolated, and provenance has to be non-falsifiable, though reproducible builds are recommended rather than strictly required at this level. Level 3 requires builds to be isolated and provenance to be non-falsifiable, which makes the audit chain tamper-evident rather than merely documented.
Trying to jump from no provenance at all straight to Level 3 rarely works. Per secure-pipelines.com's analysis, teams that attempt the leap in one move tend to abandon it partway through, and a phased approach, Level 1 first, then Level 2, then Level 3 reserved for the pipelines that carry the most risk, holds up far better in practice. Ambition without sequencing burns teams out here as reliably as it does anywhere else in engineering.
Sigstore, an open-source project from the Linux Foundation, removes a big chunk of the friction that used to keep smaller teams out of this work entirely: it enables cryptographic signing without requiring anyone to run their own GPG key management or stand up PKI infrastructure. GitHub's native artifact attestations, built on actions/attest-build-provenance, offer a simpler on-ramp than the full SLSA generator toolchain, producing Sigstore-signed attestations stored directly in GitHub's attestation API, which makes it a reasonable place for a team starting at Level 2 to begin. The in-toto Attestation Framework, known as ITE-6, defines the shared envelope format that Sigstore, SLSA, and other tools all use to describe provenance claims, which means attestations produced by different tools inside the same pipeline can be combined into one coherent, verifiable record rather than sitting as disconnected files.
Put Sigstore or Cosign together with SLSA and a Kubernetes admission controller, and the three form a working enforcement triad. Per saaro.net's 2026 analysis, that combination can block unsigned or unattested artifacts from ever reaching production, rather than just flagging them after the fact. That's the meaningful line between an SBOM and a real chain of custody: tools that add signing, attestation, and registry integration can demonstrate custody for a specific build, which matters enormously in a procurement review or a regulator's inquiry, while an SBOM without attestation is still just an inventory, however accurate. Cloudsmith's 2026 guide frames the underlying engineering principle well: build toward a "system of evidence," where every pipeline decision gets logged in a way that's immutable and queryable, so that compliance falls out of the engineering process as a side-effect rather than existing as a separate project bolted on afterward.
Reproducible environments as the foundation that makes hash pinning complete
Even a pipeline with every dependency, action, and image carefully pinned has a weak link if the build environment underneath it isn't pinned too. A floating node:24-alpine image, or an unpinned system-level tool sitting below the package manager, means two builds run from the identical source can still produce different outputs, and neither the SBOM nor the attestation will catch that drift, because both are looking at layers above it.
Functional package managers close this gap at the root. Per activestate.com's analysis, each package lives in its own distinct directory, identified by a cryptographic hash of its full inputs and dependency graph, so when one developer hands a project configuration to another, the package manager reconstructs the exact same environment on the recipient's machine, not an approximation of it. Nix's flake.lock file works the same way: it records the exact commit hash for every input, and committing that file to Git means every developer, every CI runner, and every production build resolves to identical versions permanently, per devopsboys.com's guide.
The comparison with Docker is instructive rather than dismissive. Docker pinning is a manual discipline: transitive dependencies and the system-level tools beneath the package manager will still drift unless a complete lockfile locks every single layer by hand, per a 2026 KTH DevOps course contribution. A Nix build, by contrast, produces identical output every time, because changing any declared input changes the resulting build hash automatically, with no manual layer-by-layer discipline required to keep it that way.
This is the piece that makes the rest of the audit chain mean something. When the environment itself is hash-addressed, the SBOM and the attestation stop being statements only about the artifact and become statements about a fully reproducible, independently verifiable system. An auditor doesn't have to take the build's word for it; they can re-derive the same hash on their own and check it against what was claimed. Hash pinning, at that point, functions like chain of custody has always functioned in forensics: a record strong enough to stand on its own, whether or not anyone trusts the people who made it.
Sources
- Ultimate Guide to Software Supply Chain Security in 2025
- audit: supply-chain hardening — SHA-pin actions, scheduled govulncheck, provenance/SBOM · Issue #23 · CaporalDead/qrcli
- Software Supply Chain Security: 2026 Guide
- Software Supply Chain Security Report 2026: A guidance timeline | RL Blog
- Responding to a Supply Chain Breach: A Guide to Key Rotation, Version Pinning, and Scoping the Blast Radius
- 12 Best Practices to Prevent Software Supply Chain Attacks (2026) | Bastion
- Supply Chain Provenance | Affinidi Solutions
- arxiv.org


