Marcus Chen, YuSMP Group
Marcus Chen Staff Engineer, Backend & Cloud, YuSMP Group · Java, JVM services and infrastructure security for US/EU teams
Isometric illustration of a red worm spreading across a chain of glowing software package cubes, one with a broken padlock, leaking golden keys and credential tokens toward a shadowy hooded figure on a dark blue grid

The short answer

On 4 August 2026, attackers hijacked a maintainer account and published a malicious version of keyv — an npm package downloaded roughly 127 million times a week — which then spread as a self-replicating worm to hundreds of packages across the keyv and cacheable ecosystems. The payload runs during npm install and steals cloud, CI/CD, Kubernetes, Vault, SSH and AI-agent credentials, then uses the stolen tokens to poison more packages. Wiz counted more than 400 affected packages; SafeDep tracked the footprint past 1,600 poisoned versions, and Aikido reported figures higher still. Researchers tie it to the "Shai-Hulud" malware family seen in earlier npm and PyPI attacks.

What makes this one hard to dismiss is that the poisoned releases were signed and attested. The attacker pushed the code through the project's own GitHub Actions pipeline, so the malicious keyv version shipped with valid provenance. If you build in the JavaScript ecosystem, this is a live secrets-exposure incident for your CI/CD and DevOps estate, not a distant advisory.

What happened

According to a timeline published by cloud-security vendor Wiz, the attack began at about 09:00 UTC on 4 August 2026 when a compromised GitHub maintainer account was used to introduce a malicious payload into keyv, a popular key-value caching library. From there the malware behaved like a worm: it stole publishing tokens from each machine it landed on and used them to poison additional packages that the compromised maintainers owned or that depended on the affected libraries. Widely used names such as @cacheable/utils, cache-manager and cacheable-request were caught in the blast.

Totals differ by researcher because the campaign was still spreading as they counted. Wiz reported more than 400 affected packages. SafeDep initially verified 353 poisoned versions across 79 names, then watched that grow past 1,600 versions across more than 400 names. Aikido reported at least 868 packages across 1,381 versions. What is consistent across the reports is the mechanism and the speed: SafeDep observed the worm jumping between organisations every few minutes, completing a cross-organisation publishing burst in roughly half an hour. The overlapping indicators — the same setup filenames and tooling seen in an April 2026 PyPI compromise — led analysts to place the campaign in the "Shai-Hulud" family.

Why signing did not stop it

The uncomfortable part of this incident is that the standard supply-chain defences worked exactly as designed and still let the malware through. The poisoned keyv release carried valid OpenID Connect and SLSA build-provenance attestations, and the commit that planted the hooks showed a GitHub-verified badge listing github-actions[bot] as its author. Everything a consumer would check to confirm a package was "legitimately built" passed.

That is because provenance answers a narrower question than teams assume. It establishes the path — this artifact was built by this workflow, in this repository, from this commit — but not the intent behind that commit or who controlled the credential that triggered the build. When the attacker owns the maintainer's account and pushes malicious code straight to the main branch, then cuts a release through the normal pipeline, the resulting package is genuinely signed and attested. Provenance raised the bar for outright typosquats and forged artifacts; it does not catch a hijacked account producing an authentic-looking build. Treat verification as one signal among several, not a green light.

What the malware takes

The payload is a credential harvester with a wide net. When an affected package is installed — via a preinstall script that pulls down and runs a compiled bundle — it sweeps the host for GitHub and npm tokens, cloud provider credentials, SSH keys, Terraform state credentials, and CI/CD material such as Jenkins keys and Argo CD configuration. Notably for modern teams, it also targets configuration for AI coding agents, including Claude, OpenAI, Cursor and Gemini, alongside cryptocurrency wallets and system files.

The Kubernetes behaviour is worth calling out because it turns a developer-machine compromise into a cluster problem. Running inside a pod, the malware reads the mounted service-account token, CA certificate and namespace from /var/run/secrets/kubernetes.io/serviceaccount/, then uses that token to query the Kubernetes API directly and pull every secret it can reach in the namespace. So a poisoned dependency in a build job or an in-cluster tool does not just leak the tokens on disk; it can pivot to whatever that pod's service account is allowed to see. This is the argument for tight Kubernetes RBAC and namespace isolation stated as a live threat rather than a checklist item.

What it means for US & EU software teams

If your applications, tools or CI jobs pull from npm — and almost all JavaScript and TypeScript work does — assume you were in scope until you prove otherwise. The immediate risk is not that keyv is broken; it is that any machine which installed an affected version between the compromise and your cleanup may have leaked long-lived credentials. Those credentials are the real prize: a stolen cloud key or Kubernetes token outlives the removal of a bad package by weeks if you do not rotate it.

For regulated sectors the framing is familiar. Under SOC 2, DORA and the GDPR, credential theft through a dependency is a security incident with notification and change-control obligations, and "it came in through npm" is not an exemption. The pragmatic response is to fold this into normal security-audit and secrets-hygiene practice: know which dependencies you pulled, treat exposed hosts as compromised, rotate in the correct order, and — the durable fix — reduce how much a single install can reach in the first place by scoping credentials down and turning off install scripts you never needed.

How to respond right now

This is a contain-then-rotate incident. The steps below take an exposed estate from "we installed something bad" to "the stolen tokens are worthless."

  1. Find affected versions. Compare your lockfiles and resolved dependency versions against the published affected-package lists from Wiz, SafeDep, Aikido and Socket; check CI caches and Docker layers, not just developer laptops.
  2. Remove the revocation watcher first. The malware installs a token-revocation watcher; remove it before you rotate, or your rotations can be quietly undone.
  3. Rotate every exposed credential. GitHub and npm tokens, cloud keys, Kubernetes service-account tokens, Vault secrets, SSH keys, Terraform and AI-agent credentials on any host that ran an affected install.
  4. Pin to known-good versions. Roll dependencies back to versions published before the compromise and hold them there until the ecosystem stabilises.
  5. Disable install scripts. npm 12 blocks unapproved lifecycle scripts by default; on older npm use --ignore-scripts and allowlist the few packages that genuinely need them.
  6. Hunt for use of stolen tokens. Review cloud, GitHub, Kubernetes and Vault access logs for anomalous activity and unfamiliar published package versions.

The strategic signal from the keyv worm is one worth internalising: install scripts are remote code execution you agreed to, and a build pipeline holds far more privilege than the code it builds. Teams that scope credentials to short-lived, least-privilege tokens, disable install scripts by default, and isolate Kubernetes namespaces come out of an incident like this with tokens to rotate but no lasting damage — and an estate that would have contained the worm even before the advisories landed.

Frequently asked questions

What is the keyv npm worm and when did it start?

On 4 August 2026, attackers who had compromised a maintainer account published a malicious version of keyv, a caching library that sees roughly 127 million downloads a week, and it spread as a self-replicating worm across the keyv and cacheable package ecosystems. Wiz reported more than 400 affected packages; SafeDep tracked the footprint growing to over 1,600 poisoned versions across more than 400 package names, and Aikido reported figures higher still. Researchers link the campaign to the "Shai-Hulud" malware family seen in earlier npm and PyPI compromises. The malicious code runs automatically during npm install and steals credentials before infecting more packages.

What secrets does the malware steal?

When an affected package is installed, the payload harvests a broad set of secrets from the machine: GitHub and npm tokens, cloud provider credentials, Kubernetes configuration and service-account tokens, HashiCorp Vault secrets, CI/CD material such as Jenkins and Argo CD keys, SSH keys, Terraform credentials, and configuration for AI coding agents including Claude, OpenAI, Cursor and Gemini. Inside a Kubernetes pod it reads the mounted service-account token and uses it to query the Kubernetes API and pull other secrets in the namespace. Stolen tokens are then used to republish poisoned packages and spread further.

How did signed, verified packages still ship malware?

Because the attacker pushed the malicious code through the project's own GitHub Actions pipeline. The poisoned keyv release carried valid OpenID Connect and SLSA build-provenance attestations and a GitHub-verified commit badge, so it passed automated supply-chain checks. Provenance proves how and where a package was built, not whether the source was safe or who controlled the credentials that triggered the build. A hijacked maintainer account producing a signed, attested release is exactly the case provenance alone does not catch.

How do we contain and clean up an exposure?

Treat any machine or CI runner that installed an affected version as credential-exposed. The malware installs a token-revocation watcher, so responders should remove that watcher first and then rotate every exposed token and key, in that order, or rotations can be undone. Compare your lockfiles and resolved versions against the published affected-package lists, pin to known-good versions, and disable install scripts (npm 12 blocks unapproved lifecycle scripts by default; older npm can use --ignore-scripts). Audit cloud, GitHub, Kubernetes and Vault access logs for use of the stolen credentials.

Why does this matter beyond one npm incident?

It is a template, not a one-off. A single hijacked maintainer account on a high-traffic package became a self-propagating worm that turned every install into a credential-harvesting event and used stolen tokens to spread within about half an hour. The durable lessons are that build provenance verifies the path but not the intent, that install scripts are remote code execution you opted into, and that developer laptops and CI runners hold cloud, Kubernetes and Vault credentials an attacker can reach through the dependency tree. Least-privilege, short-lived scoped tokens and script controls are what limit the blast radius.

Sources

Wiz — keyv and cacheable npm Supply Chain Attack
The Hacker News — Keyv-Linked npm Worm Poisons Hundreds of Packages
Aikido — Keyv and friends compromised in npm supply chain attack