npm provenance is not a safety check: what the tensorlake worm shows
The green provenance badge on an npm package tells you where the package was built. It does not tell you the code is safe. According to the pwn.watch incident tracker, tensorlake@0.5.144 was published on 8 October 2026 from the project's real GitHub repository, with npm provenance, and carried a preinstall hook that installs a credential-stealing worm of the Shai-Hulud kind. If your team treats provenance as a trust signal, this is the case worth reading, because the badge was genuine.
What the tracker reports
Everything in this section is the tracker's summary, one aggregator's account, and the package's own advisory is the thing to check before you act. The tracker lists the entry as partly patched. It says the hook harvests npm, GitHub, cloud, SSH and AI-tool secrets, spreads to other packages, and installs a watcher named "gh-token-monitor" that wipes the home directory if the stolen GitHub token is revoked. Its advice: pin 0.5.143, and remove that watcher before you rotate tokens. That last point reverses the usual instinct to revoke first, which is why it matters.
What provenance proves, and what it does not
This is general knowledge about how provenance works. Provenance is a signed statement that a given repository and workflow produced the package. It closes one gap well: someone publishing a lookalike from a laptop with a stolen token cannot fake it. It says nothing about whether the code in that repository, at that moment, is benign. If an attacker gets into the build pipeline or a maintainer's account, the malicious release is built from the real repository and carries real provenance.
GitHub has been tightening the publishing side. Its changelog says npm trusted-publishing configurations that are not validated now expire after 48 hours, trusted-publishing tokens from issue_comment events are rejected, and npm stage publish needs a maintainer to promote the first version of a new package. GitHub also says malware increasingly acts at install time, harvesting credentials on CI hosts and workstations without your app ever running the package's code. That is the shape of this incident, and it is why the defence has to sit at install.
The path from npm install to your secrets
General knowledge again: preinstall and install scripts run during npm install with your user's permissions, so whatever your shell can read, the script can read. On a laptop that is your SSH keys and cloud config. On a CI runner it is every secret injected into the job.
Cut 1, choose what gets installed. Commit the lockfile and install from it, so a new release only arrives when you decide. A cooldown, not adopting releases younger than a few days, buys time, because malicious releases are often caught within days. GitHub's package firewall, in public preview for Enterprise Cloud and npm only, offers a configurable cooldown of this kind. Cut 2, do not run install scripts by default. npm ci --ignore-scripts skips them; some packages genuinely need theirs, so allow those deliberately. Cut 3, keep secrets away from the install step. A CI job that installs dependencies does not need your deploy keys in its environment.
npm ci --ignore-scripts
npm ls tensorlake
If tensorlake 0.5.144 ran on a machine
The general order is: isolate the machine or runner, find out what ran, then rotate every secret it could read, from a clean machine. For this case, per the tracker's claim, look for and remove the token watcher before revoking the GitHub token. Confirm each step against the package's own advisory, not only this summary.
Notes from readers