Publishing on npm is no longer a simple command...
It’s a security-critical operation.
Every website you visit, every app you build…
runs on code you probably never think about.
We believe Trusted Publishing represents the future, but it’s not yet ready for adoption in critical projects, as in its current state it wouldn’t prevent attacks such as Shai-Hulud and other recent ones.
Powers 17 millions registered developers worldwide.
Handles ~370B monthly downloads
The average JS projects pulls ~683 transitive dependencies.
Altogether, its ecosystem exceeds 3.7+ million packages published.
The backbone of Modern JS development
It is a self-propagation worm
It is an ongoing campaign with waves (1.0, 2.0, 3.0?...)
Almost 700 packages affected including important packages and organizations
25k GitHub public repositories created by the attackers with exfiltrated secrets
It includes a persistent backdoor on GitHub self-hosted runners
This campaign targets Open Source maintainers
Francesco Cipollone
Phoenix security
Charlie Eriksen
Aikido
If your project already uses CI for releases, be aware that recent changes to npm’s token system will affect your workflows. Starting December 9, npm will revoke all existing classic tokens and prevent the creation of new ones.
Even if you’ve migrated to granular tokens, any existing tokens with longer expiration dates will be automatically capped to February 3, 2026. After that date, all newly created tokens with write access scope will have a maximum allowed lifespan of 90 days, requiring regular rotation.
These changes may disrupt existing release pipelines, including those that follow the previously recommended setup in GitHub's official documentation.
by team size:
One person publish (solo maintainer, freelance....)
Few or many people publish (corporations, etc...) can require automation
by criticality:
low impact: few downloads, small amount or dependants
high/critical impact: millions of downloads per week or having a huge amount of dependants.
by surface:
Local publication the publishers runs the publication from a local computer (laptop, vm, etc..)
CI publication the publishers delegates the publication to an external system like GitHub Actions using a personal token to impersonate them (new npm granular tokens)
OIDC Trusted publishing the publisher delegates the publication to a CI/CD Provider (like GH Actions) that has a trusted relationship with npm, so the npm token is generated once the publication process starts (short-lived OIDC identity token)
Publishing locally with strong personal auth (non-SMS 2FA) remains the most predictable and secure route for many projects.
Why
Trade-offs
When to favor it: Security-critical libraries with a small, trusted maintainer set.
For an in-depth review: Check this GitHub repository
Automating releases via CI centralizes the workflow for multi-maintainer projects, but adds risk.
Benefits
Risks
Hardening tips
Trade-offs
For an in-depth review: Check this GitHub repository
We believe Trusted Publishing represents the future, but it’s not yet ready for adoption in critical projects, as in its current state it wouldn’t prevent attacks such as Shai-Hulud and other recent ones.
Why (current gaps)
For an in-depth review: Check this GitHub repository
| Approach | Best for | Strengths | Cautions |
|---|---|---|---|
| Local Publish | Small/critical libs | Maximum Control, public identity, fewer moving parts | Manual steps; slower for large teams |
| CI Publish | Multi-maintainer projects | Automation; consistent workflow | Bot Opacity, private logs, CI compromise risk |
| Trusted Publishing | Future adoption | Token-less model, nice UX when harrdened | Not yet ready |
90 days mandatory token rotation without automation
No easy way to transition to trusted publishing when you manage many packages (manual clicks for every package onboarding)
The npm tokens are personal, so CI workflows with multiple releasers are not simple to setup (ad hoc)
OIDC workflows do not support 2FA the same way we do in local publication.
Securing GitHub Actions is not trivial at all and now we need to blindly trust the CI for publication (example)
The GitHub Actions logs are not retained for enough time (90 days)
NPM allows 2FA TOTP token reuse within the token’s validity window (demo)
Given that npm is the best website in the world and users want to spend as much time on it as possible, the only supported way of setting up trusted publishing is manually, package by package. Unfortunately, I have to do it for 200 packages, and as much as I love the npm website I also have a life and I cannot spend all day clicking buttons.
Read more in Strengthening supply chain security: Preparing for the next malware campaign
OpenJS Security collab Space: we meet every Monday
OpenJS Slack: The #npm channel is awesome
GitHub Community Discussion: Our plan for a more secure npm supply chain #174507
If you’ve ever run npm install…
you’re already part of this story.
✨ THIS TALK IS SPONSORED
BY ORBITANT ✨
♥️ Thank You! ♥️