All posts

npm's Provenance Verified the Malware. That's the Problem.

On May 19, 633 malicious npm packages passed Sigstore checks using stolen maintainer credentials. The builds were real, certificates valid, logs complete. The gap is identity, not code

May 25, 20262 min read
Heavy black punk-zine style illustration of a stamp machine validating a swarm of malicious package boxes on an assembly line, driven by a stolen key silhouette above. Thick arrows

The Trust Signal That Became Camouflage

On May 19, someone published 633 malicious versions of npm packages. They did not exploit a compiler bug or forge a certificate from nothing. They logged into a maintainer account, generated a valid Sigstore signing certificate through the standard CI pipeline, and pushed the code. The transparency log recorded the event. Provenance verification passed. The packages looked legitimate because a legitimate process built them using legitimate credentials that happened to be stolen.

This is the kind of attack that keeps security engineers up at night because it turns your best defense into camouflage. Sigstore provenance designers built the system to answer a specific question: did a trusted environment build this package, and did a valid certificate sign it? The system answered that question faithfully. It cannot answer whether the human holding the password actually wanted the publish to happen. When identity and authorization live as separate concerns, attackers walk right through the gap.

Where Provenance Ends and Identity Begins

The frameworks for software supply chain security have spent years hardening the wrong wall. We automated build verification, certificate issuance, and immutable logging. We did not bring the same rigor to account takeover. A stolen password or compromised maintainer account does not trigger a red flag in the provenance layer because the layer never inspects intent. It validates pipelines, not people. That distinction mattered less when humans manually reviewed every dependency bump. It matters enormously now that AI agents and vibe-coding tools can add a dozen new packages to a project in a single prompt without asking where they came from.

If you ship apps with AI-generated code, you already operate at a speed that manual security review cannot match. The model suggests a package, writes the import statement, and moves on. It does not check if the maintainer enabled two-factor auth or whether an attacker published the latest patch version from a hijacked session. The convenience is real. So is the exposure. Every dependency is a trust decision you are delegating to a system that cannot see identity gaps.

What Builders Should Actually Do

Start with the basics that still work. Lock your dependency versions and review lockfile changes in pull requests, even when an agent drafted the code. Enable two-factor authentication on every publishing account you control, and treat maintainer access as a production credential. If you run a project with multiple contributors, require signed commits and staged releases rather than direct publish rights from individual laptops. None of this is new advice, but the npm incident proves that ignoring it now causes automated consequences at scale.

Botflow ships code to your own GitHub repo precisely because ownership and inspectability matter. When you generate an app, the package.json is yours to audit, the dependencies are yours to pin, and the deploy pipeline is yours to harden. Open source serves as a practical check on supply chain risk because you can see exactly what is running. The AI can write the boilerplate, but you still own the trust decisions. That has always been true. Last week, 633 malicious packages reminded us that the line between convenience and complacency is thinner than we thought.