Install-script detection
New or changed preinstall / install / postinstall scripts, plus optional allowScripts enforcement in the style of @lavamoat/allow-scripts.
npm package · MIT · Node ≥ 18
Fail CI when dependency changes look suspicious.
Diffs your lockfile against a git ref or a saved baseline, looks up every new or changed package in the npm registry, and fails the build when something looks like a supply-chain attack: new install scripts, typosquats, publisher changes, lost provenance, bad signatures and more. Supports npm, pnpm and yarn (classic and Berry) lockfiles. Zero runtime dependencies.
npm i -D package-tripwire
$ npx package-tripwire --base origin/mainpackage-tripwire — 2 → 6 packages (4 added, 1 updated, 0 removed) ERROR [install-script] esbuild@0.24.0 runs install scripts → postinstall: node install.js ERROR [typosquat] expresss looks like a typosquat: edit distance 1 from "express" WARN [maintainer-change] debug@4.4.3 maintainers changed -thebigredgeek,-tjholowaychuk WARN [unknown-package] expresss@0.0.1 not found in registry WARN [deprecated] request@2.88.2 is deprecated NOTE [new-dependency] esbuild@0.24.0 added 2 error(s), 4 warning(s), 4 note(s).✖ Failing (fail-on: error).
Supply-chain attacks arrive as a one-line lockfile change: a typosquatted name, a fresh postinstall script, a version published an hour ago by a new maintainer. In a big PR diff, nobody reads pnpm-lock.yaml.
package-tripwire reads it for you. It only queries the registry for added or changed packages, so it stays fast, and it fails the PR with a clear reason.
New or changed preinstall / install / postinstall scripts, plus optional allowScripts enforcement in the style of @lavamoat/allow-scripts.
Edit distance, -/_/. confusion, homoglyphs, scoped copies and -js / node- affixes against popular package names.
Flags versions published by a different npm user, and maintainer list changes.
Fail on versions younger than --min-age (default 72h).
Verifies registry tarball signatures and flags lost provenance attestations.
Same name@version with a different hash or tarball source, plus opt-in lockfile-lint style URL policy.
package-lock / shrinkwrap v1–v3, pnpm-lock v5–v9, yarn.lock classic and Berry.
JSON, SARIF and Markdown; CLI, library and GitHub Action.
# Compare against HEAD
npx package-tripwire# Compare against the PR base
npx package-tripwire --base origin/main# Snapshot a baseline
npx package-tripwire --save-baseline .tripwire/baseline.json# Stricter gate with reports
npx package-tripwire --min-age 7d --fail-on warn --sarif tripwire.sarif --json tripwire.jsonname: Dependency tripwire
on: pull_request
permissions:
contents: read
security-events: write # only needed for SARIF upload
jobs:
tripwire:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: MrLouisWright/package-tripwire@v1
with:
min-age: 72h
fail-on: error
sarif: tripwire.sarif
- if: always()
uses: github/codeql-action/upload-sarif@v3
with: { sarif_file: tripwire.sarif }
| Flag | Description |
|---|---|
--base <ref> | Git ref to compare against (default HEAD) |
--baseline <file> | Compare against a saved baseline (or any lockfile) instead of git |
--save-baseline <file> | Write a baseline snapshot of the current lockfile and exit |
--lockfile <path> | Lockfile to check (auto-detected by default) |
--min-age <dur> | Minimum publish age: 90m, 72h, 3d, 1w, 0 |
--offline | No registry lookups |
--registry <url> | Registry URL (default https://registry.npmjs.org) |
--no-dev | Ignore dev dependencies |
--no-signatures | Skip registry tarball signature verification |
--require-provenance | Treat missing provenance attestations as findings |
--enforce-allow-scripts | Fail when install scripts run outside allowScripts |
--write-allow-scripts <file> | Write the configured allowScripts list to a JSON policy file |
--config <file> | Config file path |
--fail-on <level> | error (default), warn, note or none |
--json [file] | JSON report to a file, or stdout |
--sarif <file> | SARIF 2.1.0 report for GitHub code scanning |
--markdown <file> | Markdown report for PR comments and job summaries |
--quiet, --no-color | Output tweaks |
Full reference, config file format and API in the README.
Support this project
I build free, open-source tools that help developers ship safer websites. Every coffee helps keep them maintained, documented and free for everyone.
Buy me a coffee (opens Stripe in a new tab)Secure checkout by Stripe