Safeguard
Software Supply Chain Security

Trusted Publishing for npm: Why Only 14% of Compromised P...

Only 14% of packages compromised since npm launched Trusted Publishing use it. Here's how OIDC-based publishing works, why adoption lags, and what still gets missed.

Nayan Dey
Security Researcher
8 min read

In September 2025, the Shai-Hulud worm ripped through the npm ecosystem, self-replicating across hundreds of packages by harvesting maintainer credentials and publishing malicious versions within minutes of a compromise. A few weeks earlier, attackers had phished the maintainer of chalk, debug, and a dozen other packages with a combined 2+ billion weekly downloads, using a lookalike domain to steal an npm authentication token. Both incidents shared a root cause: long-lived npm tokens that, once stolen, could publish new versions with no further verification.

npm's answer, Trusted Publishing, replaces those static tokens with short-lived OIDC credentials issued per CI run. It closes the exact hole attackers keep walking through. Yet recent analysis of packages compromised since the feature's release found that only 14% of the affected maintainers had adopted it. This post breaks down why trusted publishing works, why adoption is stalling, and what Safeguard does to catch what token-based protections still miss.

What Is npm Trusted Publishing, and How Does It Work?

npm Trusted Publishing eliminates long-lived publish tokens by letting a CI/CD workflow authenticate directly with npm using a short-lived OpenID Connect (OIDC) token instead of a stored secret. When a maintainer configures trusted publishing for a package, they register a specific CI provider (currently GitHub Actions or GitLab CI), repository, and workflow file as the only source allowed to publish. During a release, the CI runner requests a signed OIDC identity token from its provider, npm's registry verifies that token's claims against the registered configuration, and, if it matches, issues a publishing credential that expires almost immediately.

The model mirrors what PyPI shipped in 2023 and what RubyGems and crates.io have since adopted: no npm token sits in a GitHub Secrets vault waiting to be exfiltrated by a phishing page, a compromised dependency, or a leaked CI log. Because the credential is scoped to one workflow and one run, an attacker who compromises a maintainer's laptop or steals a copy of .npmrc gets nothing usable. npm also layers on provenance attestations, so a package published via trusted publishing carries a cryptographically verifiable link back to the exact source commit and build steps that produced it, something registry-side malware scanners and downstream consumers can check before installing.

Why Do Only 14% of Compromised Packages Use It?

Adoption is low because trusted publishing requires maintainers to actively reconfigure their release pipeline, and most publish workflows were built years before the feature existed. Setting it up means updating a GitHub Actions workflow to request OIDC permissions, editing provenance settings, and registering the exact repo and workflow path in npm's package settings, a 15-to-30-minute task that only happens if someone remembers to do it. npm does not require trusted publishing; classic tokens keep working exactly as before, so there is no forcing function pushing maintainers to migrate.

The 14% figure also reflects a mismatch between who gets targeted and who has the resources to modernize. Packages attractive enough to attack, meaning high download counts and deep dependency trees, are frequently maintained by one or two volunteers rather than a team with a security backlog. Several packages hit in the September 2025 Shai-Hulud wave were transitive dependencies pulled in by thousands of downstream projects yet maintained by individuals who had not touched their publish workflow since the package's first release years earlier. The tooling exists; the incentive to migrate a workflow that isn't visibly broken only shows up after an incident.

What Happened in the Shai-Hulud and Chalk/Debug Attacks?

Both attacks succeeded by stealing static npm publish tokens, exactly the failure mode trusted publishing is built to close. In the chalk/debug incident, attackers sent a phishing email impersonating npm support that directed the maintainer to a lookalike domain designed to harvest their login session and, from there, an npm token. With that token, they pushed malicious versions of chalk, debug, ansi-styles, and other foundational packages, embedding a browser-based crypto-clipboard hijacker that swapped cryptocurrency wallet addresses mid-transaction. Because these packages sit deep in the dependency tree of thousands of applications, the blast radius extended far beyond anyone who had heard of the phishing email.

Shai-Hulud went further by turning the compromise into a worm: once it obtained one maintainer's token, malicious postinstall scripts scanned the infected environment for any other npm credentials or GitHub tokens available to that machine, then used them to publish trojanized versions of every other package the victim maintained. That self-propagation is why the incident spread to hundreds of packages within days. In both cases, if the compromised token had instead been a trusted-publishing OIDC credential scoped to a single CI workflow, the stolen session or script execution would have yielded nothing an attacker could use to publish.

Why Doesn't Trusted Publishing Alone Stop Supply Chain Attacks?

Trusted publishing stops credential theft, but it does not validate what code actually ships in a release, so a maintainer whose local machine or CI environment is already compromised can still push malicious code through a fully trusted pipeline. If an attacker gains code execution inside the GitHub Actions runner itself, for example through a compromised build dependency or a poisoned CI action, they can tamper with the package contents before publish, and the resulting release will carry a legitimate provenance attestation because it genuinely came from the registered workflow. Endor Labs and other supply chain security vendors have made a similar point in their own research: authentication controls close one attack surface while leaving build-time integrity, dependency confusion, and typosquatting largely untouched.

Trusted publishing also does nothing to catch malicious packages that were never legitimate in the first place, such as typosquats of popular libraries or brand-new packages laced with obfuscated exfiltration code from their very first version. It doesn't detect anomalous version bumps, like a stable package suddenly shipping a major version with a new postinstall script, and it doesn't help consumers who are pulling in a compromised transitive dependency published years before trusted publishing existed. Provenance tells you a build came from a specific pipeline; it does not tell you the pipeline's dependencies, the build script, or the published tarball are free of malicious behavior.

How Does npm's Approach Compare to PyPI and Other Registries?

npm's trusted publishing is a close port of the model PyPI pioneered in April 2023 after years of token-theft incidents in the Python ecosystem, and both work the same way: short-lived OIDC tokens scoped to a specific CI workflow replace static API keys. PyPI's rollout offers a useful preview of npm's adoption curve, since PyPI trusted publishing also launched to voluntary, opt-in uptake and only accelerated after PyPI began publicly labeling packages that used it and after several high-profile PyPI compromises made the token-theft risk concrete to maintainers. RubyGems and crates.io have since shipped comparable OIDC-based flows, and the pattern across all four registries is consistent: strong protection exists years before most of the ecosystem uses it.

The npm ecosystem's scale makes the lag more consequential. npm hosts more packages than PyPI, RubyGems, and crates.io combined, and its dependency trees run deeper, so a single unmigrated, widely-depended-upon package remains a high-value target regardless of how many other packages have moved to trusted publishing. Until npm follows PyPI's lead in surfacing trusted-publishing status on the registry itself, or until a critical mass of high-download packages migrate, downstream consumers cannot assume that popularity or maintenance activity correlates with credential hygiene.

How Safeguard Helps

Safeguard treats npm trusted publishing adoption as one signal among many, not a checkbox that clears a package as safe. Our platform continuously scans your dependency tree for the specific risk patterns behind both the chalk/debug and Shai-Hulud incidents: packages still relying on static publish tokens, sudden maintainer or publishing-source changes, and version bumps that introduce new install-time scripts or network calls without a corresponding source-code diff that explains them.

Because provenance attestations only prove where a build came from, not what it contains, Safeguard inspects the actual package contents at every version, flagging obfuscated code, unexpected binary payloads, and behavior changes between releases regardless of whether the publish pipeline used trusted publishing, a classic token, or manual npm publish. For your own packages, Safeguard identifies which of your published dependencies and internal packages still use long-lived tokens and provides a guided path to migrate them to OIDC-based trusted publishing, closing the exact gap that left 86% of recently compromised packages exposed.

Safeguard also correlates registry-level signals, such as a maintainer account's login history and 2FA status, with the CI provenance data npm exposes, so you can distinguish a legitimate release from a phishing-driven token theft even when the resulting package looks superficially normal. The goal isn't to replace trusted publishing but to cover what it was never designed to catch, giving you visibility into the full lifecycle of every package your applications depend on, from the maintainer's credentials to the bytes that land in your node_modules.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.