---
title: "The Keyv npm Worm Planted Hooks in Your Editor"
pubDatetime: 2026-08-04T16:00:00.000Z
description: "A worm published through keyv@6.0.0 spread across nine organisations in about half an hour, and shipped .claude/settings.json and .vscode/tasks.json hooks alongside the usual preinstall script."
tags: [supply-chain, security, claude-code, keyv, ai-security, 2026, 2026-q3, 2026-08]
---
> [!tldr] TL;DR
> A worm published as `keyv@6.0.0` at 09:35 UTC today ran a malicious `preinstall` script that pulled down a Bun runtime and a 728KB obfuscated payload to harvest cloud, GitHub, npm, Vault and Kubernetes credentials, then republished itself under stolen npm identities. Three minutes later it had jumped outside the keyv and cacheable namespaces, and from 10:10 UTC a separate 32-minute cascade took down packages belonging to nine unrelated organisations. The new part: the poisoned source repo also carried `.claude/settings.json` and `.vscode/tasks.json` files wired to run a local script when a Claude Code session starts or the folder is opened. Those hooks need workspace trust to fire, so they are a second door rather than an automatic one. Clean versions are back as `latest` on npm for at least nine packages, including keyv@5.6.0, flat-cache@6.1.23 and cache-manager@7.2.9.

The credential-stealing `preinstall` script is the boring part. Supply-chain worms have done that since the first Shai-Hulud wave. What deserves your attention in [Socket's teardown](https://socket.dev/blog/popular-npm-packages-in-the-keyv-and-cacheable-namespaces-compromised-in-active-supply-chain) is the pair of config files committed to the compromised source repository: a `.claude/settings.json` with a SessionStart hook, and a `.vscode/tasks.json` with a folderOpen task. Both point at a local script. Neither has anything to do with `npm install`.

That is a second trigger path aimed at the developer rather than the build. Clone the repo to investigate the compromise, open it in your editor, start an agent session in it, and the payload gets a chance to run without a single package being installed.

## How fast it moved

Scoped `@keyv/*` packages went out at 09:30 to 09:32 UTC. `keyv@6.0.0` followed at 09:35. By 09:38 the first package outside those namespaces, `@thiennq/docs-viewer@1.6.2`, was live, which confirms the thing was propagating under credentials it had already stolen. The `cacheable` family, nine packages, fell between 10:09 and 10:14.

Then came the part that spread beyond anyone's own dependency tree. [SafeDep's analysis](https://safedep.io/keyv-npm-supply-chain-compromise/) tracks nine unrelated organisations going down sequentially from 10:10 to 10:43 UTC, roughly one every two to seven minutes, a 32-minute cross-org propagation window that started around 35 minutes after the initial poisoned keyv release. SafeDep also documents a dead-man's-switch in the payload, and is careful about attribution on the initial access. The commit that started this carries a spoofed `github-actions[bot]` author on an API-created commit, which SafeDep says "is consistent with a stolen token or session, and equally consistent with the account itself." Nobody outside knows which yet.

## The scope numbers disagree, and one of them is oversold

Three vendors published three counts on the same day. SafeDep: 1,684 poisoned versions across 420 package names. [Aikido](https://www.aikido.dev/blog/keyv-and-friends-compromised-in-npm-supply-chain-attack): at least 868 packages across 1,381 versions, with over 2 billion combined monthly installs. OX Security: 434 packages, 1,381 versions, same 2 billion figure. These are snapshots of a count that was still climbing intraday, so treat all three as lower bounds rather than competing final answers.

The 2 billion number deserves more scepticism than it has been getting. It counts normal monthly download volume for the affected package names, which is a different thing from installs of the poisoned versions. One [Hacker News commenter](https://news.ycombinator.com/item?id=49168572) put the objection plainly:

> [!quote]
> Who cares how many installations there are per month normally? The high install numbers are almost certainly from running in CI where such secrets don't exist. How many installs actually occur in a non CI environment and of those how many were the compromised version?

That is the right question, and no vendor writeup answers it. The malware wants cloud keys, GitHub tokens, npm credentials, Vault secrets and Kubernetes config. Plenty of CI runners hold exactly those, so the objection cuts both ways, but a headline install count remains a weak proxy for how many machines actually got robbed.

## Attestations signed a poisoned build

The malicious keyv release carried valid OIDC and SLSA attestations. The signing worked as designed and proved the artifact came from the build pipeline it claimed to. It said nothing about whether the source that went into that pipeline was safe.

That exact lesson landed once already this year, in May. The [TanStack postmortem](https://tanstack.com/blog/npm-supply-chain-compromise-postmortem) covers an 11 May compromise, 84 malicious versions across 42 `@tanstack/*` packages. Nothing about the signing pipeline has changed since, and here we are again. The wider malware lineage has been busy in parallel: on 30 April, [PyTorch Lightning on PyPI](https://www.aikido.dev/blog/pytorch-lightning-pypi-compromise-mini-shai-hulud) went down to a "Mini Shai-Hulud" variant in versions 2.6.2 and 2.6.3, a different registry and a different mechanism from the attestation problem. Build provenance is worth having. Reading it as a safety signal is a mistake.

## What the IDE hooks actually do

Be precise here, because the framing has run ahead of the mechanism. [The Hacker News](https://thehackernews.com/2026/08/keyv-linked-npm-worm-poisons-hundreds.html) points out that VS Code blocks automatic tasks in untrusted workspaces by default, and Claude Code applies its own workspace trust restrictions. A developer has to grant trust before the SessionStart hook or the folderOpen task runs. Cloning the repo and reading files detonates nothing.

The uncomfortable bit is how routinely people click through that prompt on a repo they cloned to take a quick look at. Workspace trust is the last control standing between a poisoned repo and an agent session with your credentials in scope, and most developers dismiss it by reflex. Attackers now know those hook files are worth planting.

## What to do

Audit lockfiles first. Clean versions are restored as `latest`, so a fresh install looks fine while an old lockfile still resolves to a poisoned version. Rotate everything the payload targeted if one of those versions ran anywhere with real credentials: cloud keys, GitHub and npm tokens, Vault secrets, Kubernetes config.

Then look at your CI privilege model. One [suggestion from the HN thread](https://news.ycombinator.com/item?id=49169530) beats the usual "ban install scripts" advice: split CI into an unprivileged build-and-test workflow holding no API keys, and a separate privileged publish workflow that only consumes the resulting artifact. Install scripts still run, they just run somewhere with nothing to steal.

And grep your repos for `.claude/settings.json` and `.vscode/tasks.json` files you did not write. That check belongs in review now.

---

*Sources: [SafeDep: npm worm poisons 400+ packages](https://safedep.io/keyv-npm-supply-chain-compromise/)  •  [Socket: keyv and Cacheable namespaces compromised](https://socket.dev/blog/popular-npm-packages-in-the-keyv-and-cacheable-namespaces-compromised-in-active-supply-chain)  •  [Aikido: Keyv and friends compromised](https://www.aikido.dev/blog/keyv-and-friends-compromised-in-npm-supply-chain-attack)  •  [TanStack postmortem](https://tanstack.com/blog/npm-supply-chain-compromise-postmortem)  •  [Aikido: PyTorch Lightning compromise](https://www.aikido.dev/blog/pytorch-lightning-pypi-compromise-mini-shai-hulud)*

*Coverage: [The Hacker News: Keyv-linked npm worm](https://thehackernews.com/2026/08/keyv-linked-npm-worm-poisons-hundreds.html)  •  [Hacker News discussion](https://news.ycombinator.com/item?id=49166874)*

*Related on this blog: [The Payload Was Never in the Package](/posts/ai-agent-skill-poisoning)  •  [The diffusers trust_remote_code Bypass Was Patched in May](/posts/diffusers-trust-remote-code-bypass)  •  [Three Indirection Steps From a Reverse Shell](/posts/ai-agent-security-lethal-trifecta)*