The most important thing about the Mini Shai-Hulud campaign is not that attackers poisoned npm packages. That has happened before. The important part is that the poisoned packages could look legitimate while they were doing it.

On May 11, TanStack disclosed that an attacker published 84 malicious versions across 42 @tanstack/* packages. The chain combined three failures that many engineering teams still treat as separate risks: a pull_request_target workflow that crossed a trust boundary, a GitHub Actions cache that could carry attacker-controlled state into a release job, and an OIDC trusted-publishing token extracted from runner memory. The result was malware shipped through the project's own release path, with the kind of provenance signal many teams increasingly use as shorthand for safe.

That is the uncomfortable lesson. Provenance tells you where an artifact came from. It does not prove that the place it came from was clean.

The build became the payload

The TanStack postmortem describes a precise six-minute publish window, from about 19:20 to 19:26 UTC, in which malicious versions landed on npm. The payload ran during install through an optional dependency trick, executed an obfuscated JavaScript file, and searched for the credentials developers and CI runners tend to keep nearby: cloud keys, Kubernetes service-account tokens, Vault tokens, npm tokens, GitHub tokens, and SSH private keys.

That moves the incident out of the old mental model of a bad package sitting in a registry. The package was only the distribution layer. The real target was the development environment that installed it. Once the malware ran in a CI runner or a maintainer workstation, it could harvest secrets, inspect package ownership, and attempt to republish infected versions of other packages controlled by the same account.

StepSecurity called out the same escalation: the campaign used the project's release pipeline and hijacked OIDC tokens, then propagated through package ownership. Valid-looking build metadata becomes a weaker signal when the attack is designed to execute inside the system that creates that metadata.

This is bigger than one JavaScript project

TanStack's response was fast. The project says external detection arrived within roughly 20 to 26 minutes, affected versions were deprecated, npm security was engaged, and follow-up releases were prepared. That matters, but it also shows how much of the open-source security stack still depends on humans noticing badness after publication.

The campaign did not stop at one namespace. Security researchers and The Register reported a later May 19 wave that infected hundreds more npm packages, including popular modules such as size-sensor and echarts-for-react. The later payloads reportedly scanned for developer and cloud credentials, abused GitHub as a command-and-control path, and injected settings into local projects for execution by AI coding tools such as Claude Code or Codex.

That last detail is the new pressure point. AI coding agents are becoming normal participants in local repositories, CI jobs, and release processes. A package-install compromise no longer has to steal only a token. It can also plant instructions, hooks, or project files that an agent may later execute with the user's trust and context. The attack surface is not just npm, PyPI, or GitHub Actions. It is the whole developer workstation as an automation substrate.

What changes now

The answer is not to abandon trusted publishing, provenance, CI, or AI coding tools. Those are useful technologies. The answer is to stop treating any one of them as a final trust stamp.

Release jobs need narrower permissions than most teams give them. A workflow that can mint an npm publish token should not also be restoring caches that untrusted pull requests can influence. pull_request_target should be treated as a loaded footgun whenever it checks out or builds fork code. Cache scope should be understood as a write path, not just a performance feature. Package installation in CI should be allowed to run lifecycle scripts only when the project has made that decision consciously.

For developers, the practical response is boring but serious: pin versions, rebuild from clean lockfiles after an incident, rotate every credential reachable from an exposed install host, and watch for strange GitHub repositories, unexpected workflow runs, and project files that appeared outside normal review. For organizations, the deeper work is to inventory which machines, runners, agents, and package managers can touch production secrets.

Mini Shai-Hulud is a useful warning because it does not require science-fiction assumptions. It stitched together known behavior in GitHub Actions, npm lifecycle scripts, trusted publishing, cache reuse, and credential sprawl. That is exactly why it matters. The next supply-chain defense cannot be one more badge on a package page. It has to be a set of boundaries that still hold when the build system itself is part of the attack path.

Sources