Signed doesn’t mean safe
Imagine an exam with a stamp on it. The stamp is real — Nobody forged it. But who applied it matters. A student with access to the stamp, marking their own completed paper, is vouching for themselves. In contrast, a proctor who stamps the paper is an independent witness. Same stamp. Very different claim.
What happened
On May 11, 2026, attackers pushed 84 malicious npm packages across 42 TanStack repositories. Those packages spread to 170 more repositories before anyone caught on. What made the “Mini Shai-Hulud” attack strange was that every one of those packages came with a cryptographically valid signature.
The kind that’s supposed to mean something.
Three things went wrong in sequence. First, a botched GitHub Actions workflow ran fork-contributed code inside the base repository’s trusted environment, a well-known antipattern. Next, that code poisoned a shared build cache. Finally, when the legitimate release workflow ran later and pulled from that cache, the attacker’s code ran inside the trusted environment, used the signing credential available there, and published directly to npm.
The packages pointed to the right repository, the right workflow, the right branch. And the stamp certified the room and the process.
The stamp just did not (could not) certify what had happened inside.
Where the trust boundary sits
Supply-chain Levels for Software Artifacts (SLSA) is a framework for software supply-chain integrity. It defines levels of assurance around how software gets built (what evidence the build platform produces, how tamper-resistant that evidence is), and what a consumer can actually rely on. Each level closes gaps the previous one leaves open.
npm’s built-in provenance meets SLSA Build Level 2. The build runs on a hosted platform; provenance is authenticated. That’s worth having. An attacker who doesn’t control your source repository can’t produce provenance claiming they do, which closes off a whole category of impostor packages.
But Build Level 2 skips isolation. Nothing requires the platform to keep builds from tainting each other or to keep signing credentials away from the build environment. That’s Build Level 3.
Think of a shared pile of tests at the front of the room, and a stamp sitting on the desk. The attacker came in under a pull request, slipped a malicious test into the pile, and left. When the legitimate release workflow arrived and pulled from that pile, it followed those instructions and–because the stamp was on the desk–stamped the result and submitted it. At Build Level 3, the proctor keeps the stamp and doesn’t hand it out. Students bring completed work to the desk; the proctor applies it themselves. The student never touches the stamp. And each student gets a fresh test directly from the proctor — no shared pile to tamper with.
The provenance becomes something the platform applies to the build from outside, not something the build applies to itself.
What policy can add
Policy decides whose stamp counts.
Checking for a valid signature is not the same as checking that the right builder produced it. Enforcing an expected pipeline helps, but it wouldn’t have caught this directly: The attestations correctly named the legitimate pipeline. Both malicious releases came from workflow runs that ended in failure: an anomaly that was there to be seen, but no standard registry tooling checks for it today. A consumer enforcing policy at install time (requiring the build to have completed successfully, for instance) is protected without depending on the producer or registry to act first.
Defining that policy is complex. Rebuilders are one answer to that. Independent parties take the same source, build it on their own isolated infrastructure, and publish what they get. They share nothing with the original pipeline — not its cache, not its environment, not its failure modes. You’re still trusting someone… but the structural guarantees are different. A rebuilder worth trusting runs its own pipeline at Build Level 3, verifies policy before publishing, and produces attestations you can check independently.
Red Hat Trusted Libraries work this way for the Python ecosystem: packages rebuilt on Build Level 3 infrastructure with policy verification gating each publish. Stay tuned for Trusted Libraries to expand to additional ecosystems, including npm. If you want what people thought TanStack already had (genuine SLSA Build Level 3 provenance), a rebuilder is the practical path today.
What to do
As a consumer: Know which build level your dependencies actually come from. L2 and L3 are not interchangeable, and the confusion between them is part of what this attack exposed. Enforce policy at install rather than trusting the registry to catch problems after the fact. For ecosystems where rebuilders exist, pulling from one with genuine L3 provenance is stronger than relying on the original pipeline.
As a producer: The workflow hygiene issues here are well-documented — Don’t run fork code in your trusted environment, pin actions to commit digests, apply least-privilege permissions, treat caches as trust boundaries. Those close immediate gaps. But they don’t get you to Build Level 3. That requires choosing a build platform where isolation and signing are platform properties, not things you configure correctly on a good day. The SLSA spec calls this choosing an appropriate build platform; Konflux is one that delivers it out of the box.
The build platform did its job. It recorded exactly what happened inside a compromised pipeline. The stamp was real. The exam had been tampered with before anyone walked in. At Build Level 2, those aren’t contradictions — That’s just how it works.
Signed doesn’t mean safe. It means someone stamped it.
Note: I also published a related post to the SLSA blog that goes into different details. Mini Shai-Hulud: Where SLSA’s Boundaries Fall
🤖 Assisted by Claude Sonnet 4.6
