Skip to content

The Drift Log · Provenance, licensing and the paper trail

Lock Dependency Versions to Preserve License Provenance

22 October 2026 · 3 min read · 666 words · inference

A wax seal resting on a page of hash digests

Pinning dependencies creates an immutable link between code and its license provenance, enabling reliable audits.

The hidden risk in unpinned vendored code

A repository that pulls third‑party packages without exact version pins lives on a moving target. Today the code may be covered by MIT, tomorrow the same package name resolves to a version that adds GPL clauses. The licence metadata attached to the build changes without any trace. That is the failure mode: a line you did not write becomes a liability because you cannot prove which licence applied at the time of compilation.

Pinning dependencies creates a stable licence surface

When a package manager records a full lock file, every transitive dependency is bound to a specific commit or tarball hash. The lock file is a deterministic snapshot of the code that will be compiled. Because the snapshot is immutable, the licence text that ships with each package is also immutable.

{
  "dependencies": {
    "lodash": "4.17.21",
    "axios": "1.4.0"
  },
  "lockfileVersion": 2,
  "packages": {
    "node_modules/lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-..."
    },
    "node_modules/axios": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
      "integrity": "sha512-..."
    }
  }
}

The resolved URL and the integrity hash together guarantee that the exact bytes used for the build can be retrieved later. If the upstream maintainer later changes the licence file, the hash will no longer match the recorded value, flagging a provenance break. By committing the lock file to source control, you create a single source of truth for both code and licence provenance.

Capture the lock in a Build‑Intent proposal

The Build‑Intent gate is the first checkpoint before any artefact is written. It records the intent, validates licensing invariants, and stores the proposal as an immutable artefact. Adding the lock file to the proposal binds the exact dependency graph to the licence metadata that the harness will later certify.

The workflow looks like this:

  1. Generate a lock file with your package manager (npm ci, yarn install --frozen-lockfile, pip freeze > requirements.txt, etc.).
  2. Submit a Build‑Intent that includes the lock file alongside the source tree.
  3. The gate checks that every entry in the lock has a recognised licence. If a licence is missing or conflicts with policy, the proposal is rejected before any code is written.

Because the proposal is stored unchanged, the same lock file can be replayed in future builds, guaranteeing that the SBOM produced later matches the exact licences that were approved. The link between the SBOM and the Build‑Intent proposal is the same technique described in the post on automated SBOM generation from Build‑Intent proposals.

Auditing becomes a matter of replay, not guesswork

When the certification harness runs, it consumes the artefact recorded by the Build‑Intent gate. It can verify that the lock file’s hashes still resolve to the same bytes, and it can emit an SBOM that lists each package, its version, its source URL, and its licence. The SBOM entries are therefore immutable records of licence provenance.

If a downstream audit asks “which licence covered axios in version 1.4.0?”, the answer is in the SBOM and can be traced back to the lock file stored in the Build‑Intent. No manual digging through vendored folders is required. The audit outcome will be one of the certification harness verdicts: CERTIFIED if the licence matches policy, PROVISIONAL if the artefact is reproducible but the licence has not yet been asserted, INCONCLUSIVE if the harness cannot exercise the contract, or FAILED if a licence conflict is detected.

This approach directly addresses the problem outlined in the pillar post /blog/vendoring-code-without-a-paper-trail-is-unsecured-debt. Instead of a “folder of hope”, you have a verifiable chain from source to licence.

What you can do on Monday

  1. Enforce a repository policy that rejects merges without a lock file.
  2. Extend your CI pipeline to submit a Build‑Intent that includes the lock file.
  3. Run the SBOM generation step from the Build‑Intent and store the result alongside the lock.

These three steps give you an immutable link between every line of vendored code and its licence metadata. The link survives future upgrades, audits, and even accidental deletions of the original vendored folder. By pinning dependencies and recording the lock at the intent stage, you turn a compliance risk into a reproducible, auditable asset.

Keep reading

Next in the log

The Strategic Master Library · written and reviewed under the house's own epistemic rules: nothing claimed that we cannot show.