Skip to content

lockwarden drift

Lockfile & version-anomaly detection vs a base ref.

Terminal window
lockwarden drift [--base <ref>]
Usage: lockwarden drift [options]
lockfile & version-anomaly detection vs a base ref
Options:
--base <ref> git ref to compare the lockfile against (default: "main")
-h, --help display help for command

drift answers: did my lockfile change in ways my manifest doesn’t explain? It compares the working lockfile against the one committed at --base and flags anomalies — the tampering patterns that never show up in a normal dependency bump.

FlagTypeDefaultMeaning
--base <ref>stringmainGit ref to compare the lockfile against

All global flags apply.

Finding kindSeverityWhat it means
integrity-swapcriticalThe integrity hash changed for an unchanged version — the same name@version now points at different bytes
unexplained-versionhighA resolved version changed with no corresponding package.json change to explain it — lockfile-only tampering
resolved-url-movehigh (host move) / medThe tarball URL for an unchanged version moved — high when the host changed
patch-introduced-dephighA new package entered the tree alongside patch/minor bumps of existing dependencies
Terminal window
npx lockwarden drift --base main
drift vs 'main' — critical 1 · high 1
lockfile: package-lock.json
[critical] integrity-swap nested-lib@3.0.1
integrity hash changed for unchanged version nested-lib@3.0.1
baseIntegrity: sha512-N1yzAAA0aaaBBBbbbCCCcccDDDdddEEEeeeFFFfffGGGgggHHHhhhIIIiiiJJJjjjKKKkkkLLLlllMMAA==
currentIntegrity: sha512-TAMPEREDaaaBBBbbbCCCcccDDDdddEEEeeeFFFfffGGGgggHHHhhhIIIiiiJJJjjjKKKkkkLLLlllMMAA==
[high] resolved-url-move other-lib@2.0.0
other-lib@2.0.0 tarball host moved registry.npmjs.org → registry.evil-mirror.example for an unchanged version
baseResolved: https://registry.npmjs.org/other-lib/-/other-lib-2.0.0.tgz
currentResolved: https://registry.evil-mirror.example/other-lib/-/other-lib-2.0.0.tgz
note: provenance is informational only — valid provenance has shipped from compromised pipelines

Exit 1. Neither of these happens in a legitimate bump: same version + different hash means different bytes; same version + different host means a different source of truth.

Example 2 — a dependency PR that smuggles a package in

Section titled “Example 2 — a dependency PR that smuggles a package in”
Terminal window
npx lockwarden drift --base main
drift vs 'main' — high 1
lockfile: package-lock.json
[high] patch-introduced-dep dep-b@1.0.0
new package dep-b@1.0.0 entered the tree alongside patch/minor bump(s): dep-a 1.0.0 → 1.0.1
bumps: dep-a 1.0.0 → 1.0.1
note: provenance is informational only — valid provenance has shipped from compromised pipelines

A patch release that brings a new dependency with it is the axios/plain-crypto-js delivery shape. audit --diff scores the same event from the execution-surface side (LW006D-PATCH-DEP-INTRODUCED, Critical) — run both on dependency PRs; see dependency review.

Terminal window
npx lockwarden drift --base origin/main
drift vs 'origin/main' — no findings
lockfile: package-lock.json
clean no lockfile drift vs 'origin/main'
note: provenance is informational only — valid provenance has shipped from compromised pipelines

Exit 0. Other useful refs:

Terminal window
npx lockwarden drift --base v1.4.0 --json # since the last release, machine-readable
npx lockwarden drift --base HEAD~5 # the last five commits
{
"command": "drift",
"base": "main",
"lockfile": { "path": "/work/app/package-lock.json", "type": "npm" },
"findings": [
{
"kind": "integrity-swap",
"severity": "critical",
"package": "nested-lib@3.0.1",
"detail": "integrity hash changed for unchanged version nested-lib@3.0.1",
"evidence": {
"baseIntegrity": "sha512-N1yz…",
"currentIntegrity": "sha512-TAMP…"
}
}
],
"warnings": [],
"exitCode": 1
}

Field tables: JSON output → drift.

CodeMeaning
0No anomalies at or above --threshold
1Anomalies at or above --threshold
2Execution error — unknown ref, lockfile missing at the base ref, unparseable lockfile

drift deliberately does not treat SLSA provenance as a pass signal — every run prints the reminder. The June 2026 Miasma compromise published trojanized packages with valid provenance from the victim’s own hijacked pipeline. Provenance presence is informational context, never a green light — version-to-version anomaly is the honest signal. More: trust model.

  • drift reads git locally; it makes no network calls. --offline is always satisfied.
  • Requires the lockfile to exist at the base ref (exit 2 otherwise).