Dependency Provenance Verification in Local Development

Provenance, in the context of software dependencies, means the origin and history of a component — who authored it, where it was built, and whether it's been modified since publication. Verification means confirming cryptographically that what was installed is what the publisher signed, and that the distribution path between publisher and machine wasn't tampered with.
That definition excludes quite a lot of what teams treat as equivalent. A vulnerability scan isn't provenance verification. CVE presence is independent of authenticity; a perfectly clean CVE record says nothing about whether the artifact on disk is the one the maintainer intended to ship. A license audit isn't provenance verification either. A package can carry an accurate SPDX identifier and still be compromised. An SBOM answers "what is in this artifact?" It doesn't answer "which registry distributed this artifact?", and it provides no cryptographic proof of the distribution path.
Teams that run dependency scanners and generate SBOMs often believe they've covered provenance. They haven't. Provenance requires a cryptographic chain linking the artifact on disk back to its build origin. Without that chain, the other controls are useful but incomplete, and conflating them with provenance leaves a hole that attackers understand better than defenders do.
How a Compromised Package Moves from a Single Maintainer Account into Millions of Production Systems
The xz Utils compromise is the canonical reference point. xz is a dependency for nearly 30,000 Debian and Ubuntu packages, a blast radius that 2025 LNCS research describes as comparable to glibc. The attack didn't break any signature check. It made signatures irrelevant.
A trusted maintainer account was socially engineered over an extended period. Malicious code was introduced into what appeared to be a clean release. The package passed automated integrity checks because the signature was valid; the attacker controlled the signing key. The provenance of the build process itself was never verified. The binary propagated through CI/CD pipelines and registries downstream, activation deferred, detection delayed by months.
The local development environment is where this package first landed on a developer's machine, before any organizational gate. Without provenance verification at that moment, the poisoned artifact became a build input. It got locked into lockfiles. It reproduced across teammates' machines. By the time it entered CI, it looked exactly like a trusted dependency because everyone upstream had already treated it as one. That normalization is the attack's most durable feature.
The attack's success depended structurally on provenance verification not happening at the earliest possible point. Every subsequent stage in the pipeline inherited the compromised input and had no reason to question it.
What the Major Package Registries Actually Provide for Provenance Today
The registries aren't standing still, but coverage is uneven in ways that matter operationally.
npm is furthest ahead. The --provenance flag reached general availability in October 2023. Trusted Publishing reached GA in July 2025. As of npm CLI v11.5.1, provenance is attached by default unless explicitly opted out. The default now favors attestation, which is exactly where defaults need to be.
PyPI is accelerating but far from universal. Only 32.7% of Poetry's dependencies carry provenance attestations as of available data. Trusted Publishing for GitHub Actions reached GA in July 2025, which should increase coverage over time. A developer pulling a PyPI package today has a better-than-even chance of receiving an artifact with no attestation whatsoever, and the default tooling won't flag that absence. That silence is the problem.
Cargo provides strong integrity guarantees via SHA-256 checksums in Cargo.lock and OIDC-based authentication that eliminates long-lived API tokens. What Cargo doesn't provide is cryptographic provenance infrastructure. Its checksums confirm file integrity, not build origin. Knowing the bits weren't corrupted in transit is different from knowing where and by whom those bits were produced.
Research published in 2026 proposed a six-level verification chain for AI package ecosystems. Levels one through three cover file integrity, artifact identity, and publisher authenticity, designed to function offline and run on every install. Levels four and five cover envelope integrity and registry attestation, verified in strict mode. The argument embedded in that framework is correct: levels one through three should be default behavior in local development, not an opt-in available only to developers who already know to look for them.
AI model weights from registries like Hugging Face represent the outer edge of this problem. Many are distributed in pickle format, which permits remote code execution on load, with no registry-level provenance infrastructure to verify origin. The same category of risk, at greater scale, with less tooling.
Why SLSA Is Designed for CI/CD Pipelines and What That Leaves Unaddressed Locally
SLSA, the Supply Chain Levels for Software Artifacts framework maintained by the OpenSSF, is serious infrastructure. Its current specification is v1.2, approved in November 2025, graduating the Source track from experimental status and making source-level verification summary attestations first-class components of the framework. GitHub Artifact Attestations provide SLSA Build Level 2 by default for any Actions workflow; Level 3 is achievable via reusable workflows. For organizations invested in GitHub Actions, CI/CD provenance is increasingly available without significant additional configuration.
SLSA provenance is based on the in-toto attestation framework, a signed document associating metadata with an artifact. The slsa-verifier tool checks cryptographic signatures and expected builder IDs at verification time.
What SLSA doesn't address is the moment a developer runs npm install or pip install on their laptop. It doesn't address the dependencies entering a project before a CI pipeline ever runs. Local builds that produce artifacts never submitted to a CI builder fall outside its scope entirely. Ongoing research has documented that modern pipelines often lack clear boundaries of identity and reliable artifact origin information even within CI; the problem is considerably more acute locally, where no equivalent framework has achieved equivalent adoption.
SLSA gives organizations a strong story for what leaves their CI. It doesn't give them a story for what enters their developers' environments. Confusing scope with coverage is how the gap persists.
What SBOMs Contribute to Local Provenance Workflows and Where They Stop Short
An SBOM is a nested inventory of software components. Its operational value during incidents is real. During Log4Shell, an accurate SBOM could identify exposure in minutes rather than hours of manual build inspection.
Regulatory pressure has made SBOM adoption effectively mandatory for large segments of the market. U.S. Executive Order 14028, the SSDF, and the EU Cyber Resilience Act have moved SBOMs from best practice to compliance requirement for organizations selling software to the U.S. federal government or into certain regulated markets.
The provenance case is more complicated, and it hinges on when and how the SBOM is generated. An SBOM produced at the end of a build reflects the environment at build time, not at the moment each dependency was first added. New SBOMs should be generated with every build; for active development, daily generation is recommended practice. An SBOM generated in CI that reflects a dependency added locally three days earlier doesn't capture what was installed or from where. That timing gap silently degrades the SBOM's accuracy as a security control, and most teams don't account for it.
NTIA minimum elements require that when a tool can't enumerate the full transitive dependency graph, it must flag those gaps as known unknowns. Most local workflows don't enforce this requirement. The gaps accumulate without acknowledgment.
The ML-BOM problem is emerging and underappreciated. AI model weights are now dependencies in the same functional sense as npm packages, but traditional SBOM scanners can't read them. A model in pickle format can execute arbitrary code on load, with no standardized inventory format that adequately captures it and no provenance infrastructure to verify its origin.
SBOMs become a provenance control only when generated early, generated continuously, and paired with attestation. Produced as a compliance artifact at the end of the pipeline, they're an inventory. A valuable one, but not a verification.
How Environment Reproducibility and Provenance Verification Depend on Each Other
A study of 5,298 Docker builds, conducted by Malka et al. in January 2026, found that only 6.4% of rebuilt images matched the original set of installed package versions exactly. Bitwise identity was virtually never achieved. That figure has direct consequences for any provenance claim.
If a rebuild pulls different package versions than the original, provenance attestations from the first build don't apply to the second. Environment drift silently invalidates previously verified dependency graphs. A developer whose environment has drifted from the team baseline may be running unverified versions of dependencies even if the project's canonical lockfile is fully attested. The attestation is accurate; it just no longer describes what's actually running. Most teams have no mechanism to detect when this happens.
The relationship between reproducibility and provenance isn't obvious, but it's fundamental. Reproducibility without provenance gives you a consistent environment whose contents may have been tampered with. Provenance without reproducibility gives you attested artifacts that may not match what is running. Neither property is sufficient without the other.
Container image tags are mutable. A base image pinned by tag may resolve to a different underlying image on a subsequent pull. Digest-pinning is a prerequisite for provenance claims to hold across rebuilds, not an aspirational practice. Most teams use tag-pinning. Lockfiles like Cargo.lock and package-lock.json provide version pinning but not build origin attestation. They narrow the problem without solving it, and the gap between the two is where attacks live.
Provenance verification at the local stage must be built into the environment definition. Applying it as a post-hoc check after the environment is already running is too late.
What Local Provenance Verification Looks Like in a Reproducible Environment Toolchain
Three reproducible environment tools dominate this space: Devbox, Dev Containers, and the Nix-derived ecosystem more broadly. Each represents a different point on the spectrum between approachability and determinism, and each carries different implications for provenance.
The Nix model is most directly relevant. Every package is built from a derivation specifying all inputs. The store path is a cryptographic hash of those inputs, making the build reproducible and the provenance of every installed package traceable back to its derivation. The package set contains over 80,000 packages, and a package cache can reduce install time by up to 90% compared to building from source. Devbox surfaces this model for teams that want those guarantees without writing derivations directly.
Dev Containers provide strong environment consistency within containers, but their provenance claims depend entirely on image discipline. Digest-pinned base images are required for provenance claims to hold; tagged images reintroduce the drift problem Malka et al. documented.
A local provenance workflow integrating these tools has identifiable, concrete components. The environment definition lives in version control, making the spec the source of truth rather than the developer's current machine state. Package installs resolve to cryptographically identified artifacts, not floating version ranges. SBOM generation triggers at environment activation or on dependency change, not deferred to CI. Attestation verification runs at install time for packages carrying attestations, which now includes npm packages published with Trusted Publishing and PyPI packages that carry attestations. When a dependency carries no provenance attestation, the tooling surfaces that absence as a visible gap rather than silently accepting it.
When the environment definition encodes provenance controls, every developer who activates the environment inherits those controls automatically. A new contributor on day one operates with the same verification posture as the senior engineer who configured the environment months earlier. Security posture stops being a function of individual knowledge and becomes a property of the infrastructure itself.
Where Provenance Verification in Local Dev Fits into the Broader Supply Chain Security Posture
The propagation model is direct. A dependency first enters the software lifecycle on a developer's machine. From there it enters the lockfile, the lockfile enters version control, CI consumes the lockfile, and the artifact enters production. Verification at any later stage is catching something that has already crossed multiple trust boundaries, each of which normalized it further. The cost of detection scales with propagation distance.
Local verification prevents specific, traceable downstream failures — poisoned packages entering lockfiles and accumulating the appearance of trusted inputs; SBOM debt building up because dependencies were never inventoried at the point of addition; CI provenance checks failing on artifacts whose local provenance was never established, triggering expensive remediation mid-pipeline.
CI-level and production-level controls still carry distinct responsibilities, and they're not redundant with local verification. CI needs SLSA Build Level 2 or higher attestations for pipeline-produced artifacts, and Verification Summary Attestations for downstream consumers. Production needs runtime verification that the deployed artifact matches its attested build. Each stage assumes the one before it has done its job. Local verification is the stage that currently assumes nothing, because nothing checks it.
Wiz's 2025 State of Code Security Report found that 61% of organizations have secrets exposed in public repositories. That's a symptom of the same underlying condition as unverified local dependencies — security controls applied after sensitive material has already propagated.
This is an infrastructure decision, not a literacy campaign. Platform and security engineering teams make this decision once, embed it into the environment definition, and every developer who activates that environment inherits the posture. The alternative is coverage that tracks whoever happened to be paying close attention that week, which is no coverage policy at all.


