Trusted Publishing trusted the wrong identifier
npm's Trusted Publishing feature exists to remove long-lived publish tokens from the equation, letting a package maintainer authorize releases straight from a GitHub Actions workflow instead of storing a credential that can leak. The mechanism works by recording which repository is allowed to publish a given package. Bloom Security found that npm recorded that binding using the repository's owner and name, the human-readable slug, rather than the permanent numeric IDs GitHub actually embeds in its OIDC identity tokens. npm never checked those IDs against what it had stored.
That distinction sounds academic until a repository gets renamed, transferred to a new owner, or deleted, all of which are routine events in any organization that reorganizes repos as projects evolve. The moment that happens, the old slug becomes available again. Anyone can then create a new repository under that exact name, add a workflow file with a matching filename, and GitHub will issue them a legitimate publish credential for a package they have never touched, because npm is still checking the name it remembers rather than the identity that actually owns it.
The scale makes this more than a theoretical flaw
Bloom Security, the firm that found and reported the issue, counted more than 1,500 npm packages exposed to this weakness, carrying over 10 million downloads in total and more than a million downloads every month. That is not a handful of niche utilities. At that download volume, the exposed set almost certainly includes packages sitting somewhere in the dependency tree of production applications across a meaningful share of the enterprises reading this, whether they know it or not, since few organizations maintain a full transitive dependency map down to this level of detail.
Golan Myers, the Bloom security researcher behind the finding, confirmed the team validated the attack end to end using infrastructure it controlled: publishing a malicious release from a second organization's repository after claiming a freed slug. The resulting release carried a valid provenance attestation naming the attacker's own repository, the exact signal that provenance checks exist to catch. Myers said it remains unknown whether anyone exploited this in the wild before GitHub's fix, which is the honest and uncomfortable answer most supply chain disclosures eventually land on.
Provenance signals were never the safety net they looked like
The detail that should worry security teams most is that a malicious package published through this technique would carry a technically valid provenance attestation, the same cryptographic signal that package registries, CI pipelines, and increasingly, automated dependency-review tools treat as evidence a release is clean. Bloom's finding demonstrates that provenance metadata correctly describes where a build happened without guaranteeing that the entity controlling that location is the one your organization trusts.
GitHub's own name-retirement protections offered a partial brake, since it holds names from repositories with over 100 clones for a window before allowing an owner rename or deletion to free the name for reuse. That protection has an obvious gap: it is based on clone counts, not on whether a package built from that name is still being pulled by npm install across thousands of production CI pipelines. A quiet, low-clone repository behind a widely depended-on package would sail through that threshold with no protection at all.
The disclosure timeline is its own finding
Bloom reported the vulnerability through GitHub's HackerOne program on June 6, and GitHub validated the report on June 9, a reasonably fast initial turnaround. Then the process stalled. Bloom says GitHub's last substantive reply came on July 8, and that six separate follow-up attempts after that, including an escalation through HackerOne's mediation process, went unanswered. GitHub finally shipped a fix on October 2, roughly four months after validating the report and nearly three months after its last response to the researcher who found it.
That gap matters beyond the optics. A validated, unpatched vulnerability sitting quietly for months is functionally equivalent to an undisclosed one for anyone who independently discovers it in the meantime, with the added disadvantage that the original researcher has already stopped actively monitoring for exploitation. The fix itself, expiring unvalidated Trusted Publishing configurations after 48 hours, is a sound mitigation. It just arrived on a timeline that no enterprise relying on GitHub's registry security would have chosen if given the option.
AI coding agents turn a slow leak into a fast one
Bloom's most consequential figure for enterprise risk may be the one about AI coding agents rather than the vulnerability itself: it estimates these agents install roughly 70 packages a month on a typical endpoint, and close to 350 on active developer machines, often without a human reviewing what got pulled in. That consumption pattern was built for a world where package registries are assumed trustworthy by default, which is precisely the assumption this vulnerability broke.
A supply chain weakness that might once have taken months to reach a meaningful number of downstream installs through normal human-paced dependency updates can now propagate at whatever cadence an organization's coding agents run. The governance conversation CTOs are already having about agent permissions and autonomy needs an explicit line item for what those agents are allowed to pull into the build without a second set of human eyes on it.
What this changes for supply chain governance
Bloom's practical recommendation is to run npm trust list across your organization's maintained packages and confirm every listed repository still belongs to the account that should own it, rebinding any configuration that points to a renamed or transferred repo, and removing bindings before a repository is deleted rather than after. For packages you consume rather than publish, checking that a dependency's provenance attestation names the repository the project is actually supposed to come from is now a meaningful control, not a formality.
The deeper lesson is about where trust actually lives in a modern software supply chain. Cryptographic provenance, signed commits, and trusted publishing all describe a verifiable chain of custody, but that chain is only as strong as the identifiers underneath it, and this flaw shows registries have been trusting human-readable names in places that needed permanent, immutable identity. Any build-vs-buy decision about supply chain security tooling should now include the specific question of whether the tool checks identity or merely checks naming, because this incident proves those are not the same guarantee.


-6.png?w=1024)
