← May 2026
App Idea Cards 2026-05-11

Hookgate

Hookgate

Hookgate

A drop-in wrapper around npm, pnpm, and yarn install that diffs every package's lifecycle scripts against its previous published version and refuses the install when a new preinstall, install, or postinstall hook appears in a patch release.

Problem

The March 31, 2026 Axios compromise was a patch-bump (1.14.01.14.1) that introduced a single new dependency, plain-crypto-js, whose only job was to run a postinstall hook that downloaded a cross-platform RAT — and it sat in the registry for ~3 hours, long enough to seed CI pipelines around the world. Existing defenses ask developers to either disable lifecycle scripts entirely (which breaks legitimate packages like node-gyp, puppeteer, and playwright) or maintain a static allowlist (which decays the second a real maintainer adds a hook to their next release). Neither approach catches the actual signal: this package never had a postinstall hook before, and now it does.

Target user

Engineering leads and platform/security engineers at small-to-midsize Node.js shops who own npm install in CI and on developer laptops. The job-to-be-done: "stop a Sapphire-Sleet-style patch-version compromise from running arbitrary code on my fleet, without making npm install so painful that engineers --ignore their way around it."

MVP scope

  • Wrapper command hookgate install that resolves the lockfile, downloads each tarball with --ignore-scripts, and reads the scripts.preinstall|install|postinstall field from every package.json in the tree.
  • For each package, fetch the registry metadata for the immediately prior published version and diff the lifecycle script bodies (SHA-256 + literal text). Cache diffs locally in ~/.hookgate/cache/.
  • Block (exit non-zero) when ANY hook is newly added, materially changed, or downloads a binary at install time; surface a one-screen report listing the offending packages, old hash, new hash, and the diff.
  • hookgate approve <package>@<version> to record an explicit human approval; approvals are committed to .hookgate.lock so the team shares the trust set.
  • JUnit XML output so the CLI plugs into GitHub Actions, GitLab CI, and Buildkite as a failing test.
  • Standalone Go binary (single static executable, no Node runtime required) so it can run as the first step in a hardened CI image.

Monetization

Freemium. Core CLI is MIT-licensed and free forever. Hookgate Cloud ($15/seat/month, $99/mo team flat) continuously diffs the public npm registry and pushes a webhook the moment ANY package in your committed .hookgate.lock ships a new lifecycle script — so the team gets paged on the registry-side change, not after CI fails three hours later. Enterprise tier adds SSO, audit log export, and a private mirror for internal packages.

Why now

The Axios compromise on March 31, 2026 affected a package with ~100M weekly downloads and was attributed to North Korea's Sapphire Sleet group within days. It is the third major npm supply-chain incident in eight weeks — the SAP-related npm packages compromise on April 29, 2026 and the self-propagating "Shai-Hulud" worm that hit npm, PyPI, and Docker Hub in a 48-hour window between April 21 and 23, 2026 both used the same pattern: a freshly added preinstall or postinstall hook. Existing OSS tools (can-i-ignore-scripts, npm-viewscripts, @lavamoat/allow-scripts) list or allowlist hooks but do not diff against the previous version, which is exactly the signal Axios would have tripped. Microsoft, Datadog, Elastic, Palo Alto Unit 42, and StepSecurity have all published detailed post-mortems calling out the missing per-version behavioral diff as the gap.

Risks & open questions

  • Demand-side: will dev teams adopt a wrapper around npm install, given the friction of approving every legitimate hook change? Mitigation: ship sensible defaults that auto-approve no-op changes (whitespace, version bumps inside the script body that don't add side effects) and surface only the genuinely new hooks.
  • Build-side: registry metadata for the "previous version" requires network calls to npmjs.org during install — slow CI, and breaks air-gapped builds. Mitigation: pre-warmed cache image; daily sync to a self-hosted mirror.
  • Bypass: a sophisticated attacker may modify the resolved tarball contents without changing package.json (e.g. via a malicious main entry that runs on require()). Hookgate explicitly scopes itself to lifecycle scripts — the README must say so, and a "Hookgate is not enough" section in the docs should point users at complementary controls (sandboxed CI runners, egress allowlists).
  • Differentiation: how to keep from being a thin feature inside Snyk, Socket.dev, or GitHub Dependabot — they could add per-version hook-diff in a sprint. Mitigation: ship the OSS CLI first and become the de-facto standard people pin in their package.json scripts before incumbents move.
  • Maintenance: the prior-version-fetch needs to handle deprecations, unpublished versions, and packages with no prior version (first release) — none of which can be assumed safe.

Next step

Promote to a weekly prototype: build the Go CLI against the live npm registry, ship a canned demo that reproduces the Axios 1.14.01.14.1 diff and blocks the install end-to-end.

Sources

More from App Idea Cards