by Ulises Gascón

Publishing JavaScript

Securely

in 2026

Publishing on npm is no longer a simple command...
It’s a security-critical operation.

Ulises Gascón

  • Express.js Technical Committee Member
  • Node.js Core Collaborator and releaser
  • Lodash Technical Steering Committee Member
  • Yeoman Core Team Member
  • Webpack Security Triage Team Member
  • OpenJS CNA Team Member
  • OpenJS Cross Project Council Voting Member and TC39 Delegate
  • Senior SWE at NodeSource

@UlisesGascon

@kom_256

@UlisesGascon

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.

The OpenJS Foundation

The npm Scale

npm

  • 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

Shai Hulud

The Key Takeaways

  • 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

Thanks for the coverage...

Francesco Cipollone

Phoenix security

Charlie Eriksen

Aikido

Going Deeper

What Changed on npm

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.

Personas and Options

Personas

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:

  • one or few packages
  • many packages (corporations, prolific maintainers)

Options

  • 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)

Local Publishing

Publishing locally with strong personal auth (non-SMS 2FA) remains the most predictable and secure route for many projects.

Why

  • Clear public auditability of the publisher’s identity
  • Fewer opaque moving parts than CI pipelines
  • Lower blast radius if something goes wrong

Trade-offs

  • Manual/serial process can slow larger teams
  • Requires careful handling of local credentials
  • Always logout after the publication

Local Publishing

When to favor it: Security-critical libraries with a small, trusted maintainer set.

 

For an in-depth review: Check this GitHub repository

Local Publishing

CI Publishing

Automating releases via CI centralizes the workflow for multi-maintainer projects, but adds risk.

Benefits

  • Repeatable, standardized releases for larger teams
  • Single, controlled entry point for publish
  • Supports 2FA before publishing (but is easy and common to accidentally use in a one-factor manner)

Risks

  • Bot accounts obscure who actually published
  • Private audit logs mean the broader ecosystem can’t quickly validate anomalous publishes
  • Any CI compromise can lead to silent, high-impact incidents
  • Requiring npm 2FA requires a third-party server

CI-Based Publishing

Hardening tips

  • Use a dedicated “release” repo with very limited access
  • Require review gates/environments; alert via Slack/webhooks on publish
  • Keep least-privilege scoped tokens and short lifetimes where required

Trade-offs

  • Requires a manual token rotation at minimum every 90 days by design from Nov 19.
  • The 2FA step requires additional setup and trust an additional external service like step-security/wait-for-secrets

For an in-depth review: Check this GitHub repository

CI-Based Publishing

OIDC Trusted Publishing

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.

The OpenJS Foundation

Why (current gaps)

  • Incomplete controls (e.g., 2FA enforcement paths)
  • Edge-case weaknesses that maintainers can’t fully mitigate yet
  • Fragile provenance configuration in setup, like case-sensitivity, mismatched registry URLs, or naming inconsistencies, can silently break provenance and cause confusing publish failures.
  • On-boarding packages is a manual per-package process and manually configuring individual workflows and repositories for each is not scalable today..
  • Once onboarded, packages with directly added users can still be published via token based workflows, additionally it can just turned off or edited in case of an account takeover

For an in-depth review: Check this GitHub repository

TL:DR;

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

Recent Discussions

  • 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.

 

Nicolo Ribaudo (babel) in npm-set-trusted-publishing

 

What’s Next for npm

  • Bulk OIDC onboarding: Streamlined tooling to help organizations migrate hundreds of packages to trusted publishing at scale.
  • Expanded OIDC provider support: Adding support for additional CI providers beyond GitHub Actions and GitLab.
  • Staged publishing: A new publication model that gives maintainers a review period before packages go live, with MFA-verified approval from package owners. This empowers teams to catch unintended changes before they reach downstream users—a capability the community has been requesting for years 🥹.

 

Read more in Strengthening supply chain security: Preparing for the next malware campaign

Join the discussions

If you’ve ever run npm install

you’re already part of this story.

THIS TALK IS SPONSORED

BY ORBITANT

♥️ Thank You! ♥️