The attestation was valid. That was the problem. (external link)
On 4 August, between 09:02 and 10:28 UTC, eleven releases went out across
keyv, the @cacheable family, flat-cache, file-entry-cache,
cache-manager and ecto, each carrying a preinstall hook that pulled down a
728KB second stage and went looking for GitHub tokens, npm credentials, cloud
keys, private keys, database strings and Kubernetes tokens.
Every one of those releases had a valid npm provenance attestation.
Not forged. Valid. Snyk's line is the one to sit with: "the malicious source was present in the tagged repository state, so the legitimate workflow built and attested the malicious artifact." The attacker had write access to the repository, so the malicious commit was the source of truth. The signature faithfully certifies that this tarball was built by that workflow from that commit. It is completely accurate and completely useless, because provenance was never a claim about whether the code is good — only about where it came from.
We have spent three years telling people to check for provenance. A generation of tooling now shows a green badge for it. That badge was green here.
Two things follow.
The first is that npm's staged publishing, which I linked on Monday, is the control that actually addresses this shape of attack — it requires a human 2FA approval that a repository-write compromise does not grant. The gap between the two stories is four days. I would like to say the industry moves quickly, but the honest reading is that the fix shipped just before the attack that needed it, and adoption is opt-in.
The second is the part specific to this site. The payload also wrote a
SessionStart command into .claude/settings.json and a task into
.vscode/tasks.json. Opening the repository in your editor, or pointing a
coding agent at it, executes the attacker's code. Agent configuration files are
now an execution vector, and unlike package.json nobody is scanning them,
nobody diffs them carefully, and every tool in this space encourages you to
accept whatever the repo ships.
Mitigations in the post are sensible and ordered correctly: isolate before you
rotate, hunt the gh-token-monitor persistence before rotating tokens, pin to
known-good versions, and reinstall with npm ci --ignore-scripts. That last
flag should probably be your default and we all know it.