Dependency Lockfile and Allowlist¶
Dependency policy — instantiates Transitive Trust Boundary Hardening
Pins every dependency to an exact, pre-approved version and digest and refuses anything else, so a build can only pull what was reviewed — not whatever the registry serves today.
A build that trusts its registry inherits every future change that registry makes — including a maintainer takeover or a poisoned update. Dependency Lockfile and Allowlist severs that open-ended trust by freezing the dependency set to specific versions and content digests (the lockfile) and constraining what a build is permitted to pull at all (the allowlist). Its defining move is default-deny against a reviewed snapshot: trust is scoped to an exact, hash-checked set that a human approved, so a newly-published malicious version is simply never eligible, and a tampered copy of an approved version fails its digest. It governs which exact artifacts enter — not who published the name, and not whether the bytes are signed.
Example¶
A JavaScript application depends on a library declared as ^1.2.0. Without a lockfile, each install resolves that range to whatever the registry currently offers — so a maintainer whose account is hijacked can publish 1.2.9 with malware, and the next CI build pulls it automatically. With a lockfile pinning exact versions and integrity digests, and an allowlist routing installs only through an approved internal proxy, the build fetches solely the exact, hash-verified artifacts that were reviewed. The hijacker's 1.2.9 is never selected because nothing asked for it; a tampered 1.2.5 fails its recorded digest. The upstream is free to change — the build is not.
How it works¶
Record the exact version and content digest of every direct and transitive dependency (the lockfile), and enforce an allowlist of permitted packages and sources; any install that does not match both the lock and the allowlist fails. The effect is to convert a live, mutable supply — "whatever the registry serves now" — into a frozen, reviewable set. It scopes and inventories what may enter; it leaves naming, signing, and build-lineage checks to other mechanisms.
Tuning parameters¶
- Pin granularity — version only versus version plus content digest. Digest pinning is what actually stops substitution; version-only pinning still trusts the registry to serve honest bytes.
- Allowlist scope — per-package, per-registry, or per-org. Narrow allowlists cut the attack surface but need more maintenance as real needs change.
- Update-review gate — how hard it is to change the lock. A required review on every bump is the safeguard; auto-updating the lock quietly re-opens the door.
- Transitive depth — pin direct dependencies only, or the full resolved tree. Full-tree pinning closes the transitive holes attackers actually use.
- Source restriction — public registry versus an internal mirror only, controlling where approved artifacts may even be fetched from.
When it helps, and when it misleads¶
Its strength is stopping silent change: an upstream update or a tampered artifact cannot enter without failing the lock, and the trusted set becomes explicit, diffable, and reviewable rather than implicit in a version range.
Its failure mode is that a lockfile freezes known-good and known-bad alike.[1] Pinning to a version with a later-discovered vulnerability keeps you on the vulnerable one until someone deliberately updates; and a dependency that was already malicious at review time gets pinned and blessed by the very mechanism meant to protect you. The classic misuse is auto-bumping the lock with no review — which restores exactly the live-registry trust the lock was supposed to remove — or writing an allowlist so broad it permits anything. The discipline: pair pinning with active vulnerability monitoring, and treat every change to the lock as a reviewed event, not a routine one.
How it implements the components¶
trust_scope_contract— the lockfile-plus-allowlist is a scope contract: the build is trusted to pull only these exact, approved artifacts from these approved sources, and nothing else.dependency_and_substitution_inventory— the lockfile is a complete inventory of the exact dependency versions and digests, and the digest match is what forecloses silent substitution of an approved version.
It does not bind package names to their legitimate publishers (intermediary_role_registry, Package Namespace Confusion Guard); it does not produce the human-readable component report used for audit (Software Bill of Materials Review); and it does not verify signatures or build provenance (Artifact Signature Verification, Provenance Attestation Check).
Related¶
- Instantiates: Transitive Trust Boundary Hardening — scopes registry trust down to an exact, reviewed set instead of the live feed.
- Sibling mechanisms: Package Namespace Confusion Guard · Software Bill of Materials Review · Artifact Signature Verification · Provenance Attestation Check · Trusted Update Channel Pin
Notes¶
A lockfile enforces (it blocks an install that does not match), where a Software Bill of Materials reports (it makes the component set visible for audit); the two are complementary, not substitutes. And it controls which version, where Package Namespace Confusion Guard controls whose package — a lock can faithfully pin the wrong package if the name resolved to an attacker before the pin existed, which is why name-binding is its companion, not its duplicate.
References¶
[1] The lockfile embodies allowlisting — a default-deny stance in which only explicitly-approved items pass. Its known cost is staleness: an allowlist is only as safe as its last review, so it must be paired with a process that re-examines what has been approved. ↩