Massive npm Security Overhaul: Staged Publishing & 2FA Approval Now Mandatory + Video

Listen to this Post

Featured Image

Introduction:

The npm ecosystem, the backbone of modern JavaScript development, has long been a prime vector for supply chain attacks. Malicious actors who compromise a maintainer’s account or CI/CD pipeline can instantly `npm publish` a poisoned update, affecting millions of developers within minutes. To combat this, GitHub has introduced staged publishing, a mandatory human‑approval gate that requires a maintainer to explicitly pass a two‑factor authentication (2FA) challenge before any new package version goes live. This feature transforms the publishing process from a single automated push into a secure, two‑step workflow that ensures every release is reviewed and authorised.

Learning Objectives:

  • Understand the risks of direct `npm publish` and how staged publishing mitigates them.
  • Learn to configure and use npm stage publish, npm stage list, and npm stage approve.
  • Implement staged publishing with trusted publishing (OIDC) in CI/CD pipelines.
  • Master the new `–allow-` install‑time controls to lock down non‑registry sources.

You Should Know:

  1. Understanding the Attack Vector – Why Direct npm publish is a Liability

Historically, any maintainer with write access could issue `npm publish` and immediately make a new version available to the entire ecosystem. Attackers exploited this by stealing long‑lived tokens, compromising CI/CD secrets, or taking over accounts. Once a malicious version is live, it can spread to thousands of downstream projects within hours.

Staged publishing breaks this direct chain. Instead of a tarball going straight to the live registry, it lands in a stage queue visible only to maintainers. Only after a human (with 2FA) explicitly approves it does the version become installable. This adds a verifiable “proof of presence” for every release, even those originating from fully automated CI workflows.

  1. Step‑by‑Step Guide to Staged Publishing with Trusted OIDC

The most secure setup pairs staged publishing with trusted publishing (OpenID Connect), which eliminates the need for long‑lived tokens. Here’s how to implement it.

Prerequisites:

  • npm CLI 11.15.0 or higher (npm install -g npm@latest)
  • Node.js 22.14.0 or higher
  • 2FA enabled on your npm account (choose “Authorization and publishing”)
  • A package already existing on the npm registry (brand‑new packages cannot be staged)

Configure Your npm Package for Stage‑Only Publishing on GitHub Actions

Create or modify your `.github/workflows/publish.yml`:

name: Publish Package

on:
push:
tags: ["v.."]

jobs:
stage:
runs-on: ubuntu-latest
permissions:
id-token: write  required for OIDC
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
registry-url: "https://registry.npmjs.org"
- run: npm ci
- run: npm run build  if needed
- name: Stage the package
run: npm stage publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}  granular or legacy token

⚠️ Even with OIDC, a granular access token is required until full OIDC stage support is finalised. Use a token limited to `npm stage publish` only.

Approve the Staged Package (with 2FA) via CLI

From any trusted device where you are logged into npm:

 List all staged packages you have access to
npm stage list

Inspect a specific staged package (e.g., [email protected])
npm stage view [email protected]

Download and examine the full tarball before approval
npm stage download [email protected]

Approve and publish – you will be prompted for a 2FA code
npm stage approve [email protected]

💡 Best Practice: Restrict your trusted publishing configuration to stage‑only. Add this to your package’s `.npmrc` or set it in the npm web interface under Settings > Publishing Access > Require two‑factor authentication and disallow tokens. Then, any `npm publish` from CI will be rejected – only `npm stage publish` works.

  1. New Install‑Time Controls – Locking Down Installation Sources

In addition to staged publishing, npm CLI 11.15.0 introduces explicit allow‑list flags for non‑registry installations. These flags protect developers from accidentally pulling packages from file paths, remote URLs, or local directories – common supply chain attack vectors.

| Flag | Purpose | Usage |

|||-|

| `–allow-file` | Local file paths and local tarballs | `npm install –allow-file=none` |
| `–allow-remote` | Remote URLs, including https tarballs | `npm install –allow-remote=all` |
| `–allow-directory` | Local directories | `npm install –allow-directory=none` |
| `–allow-git` | Any Git source (GitHub, GitLab, etc.) | `npm install –allow-git=none` |

Example – Restrict all non‑registry sources in a project

Create an `.npmrc` file in your project root:

allow-file=none
allow-remote=none
allow-directory=none
allow-git=none

Now, `npm install` will only fetch packages from the official npm registry. Any attempt to install from a local path, remote tarball, or Git repository will fail, preventing many dependency confusion and typosquatting attacks.

4. Hardening Your CI/CD Pipeline for Staged Publishing

The highest‑value setup is to have your CI publish to the stage queue and a maintainer approve from a trusted device. This keeps the pipeline non‑interactive while still enforcing human review.

Windows / Linux – Configuring Stage‑Only OIDC in Azure DevOps

Add the following to your `azure-pipelines.yml`:

trigger:
tags:
include: ["v.."]

pool: ubuntu-latest

steps:
- task: NodeTool@0
inputs:
versionSpec: "22.x"
- script: npm ci
- script: npm run build
- script: npm stage publish
env:
NPM_TOKEN: $(NPM_TOKEN)  store granular token as a secret

After the CI run, have a designated maintainer run `npm stage list` to see the pending version, inspect it, and approve. This way, no single compromised token can ever push a live malicious version without a second authorised human.

5. Verifying Supply Chain Integrity with Provenance

npm now automatically generates provenance statements for staged packages, identical to direct publishes. Provenance publicly establishes where and how a package was built, increasing transparency for downstream consumers.

To enable provenance, add this to your `.npmrc`:

npm provenance = true

When you approve a staged package, npm records the build environment and the OIDC identity that triggered the stage. Consumers can run `npm audit signatures` to verify a package’s provenance.

What Undercode Say:

  • Every npm release now requires a human 2FA gate – Even fully automated CI pipelines must be followed by a maintainer approval, effectively killing “push‑and‑forget” supply chain attacks.
  • Stage‑only publishing plus new install controls close multiple attack vectors – By restricting CI to `npm stage publish` and disallowing tokens, you eliminate the risk of stolen tokens being used to publish directly. The new `–allow-` flags further protect consumers from non‑registry sources.

Staged publishing is not just another npm feature – it represents a fundamental shift in how open‑source ecosystems approach security. For years, the npm registry prioritised speed and convenience, inadvertently enabling the rapid spread of malicious packages. With this change, every release must pass a human checkpoint enforced by 2FA. This is a direct response to massive supply chain breaches like Shai‑Hulud 2.0 and the TeamPCP campaign, which poisoned thousands of projects by compromising automated publishing workflows. While staged publishing adds an extra step, it also provides a verifiable audit trail and a mandatory second approval that no automated system can bypass. Organisations that adopt staged publishing immediately harden their software supply chain against one of the most common attack patterns in modern development.

Expected Output:

After configuring staged publishing and approving a package, the npm registry will show the new version as publicly available. The maintainer’s activity log will include entries like:

2026-05-24 10:32:15 - Package [email protected] staged by CI pipeline (job id: 7421)
2026-05-24 11:05:42 - Package [email protected] approved and published by Undercode (2FA verified)

End users running `npm install my-package` will download the approved version, and `npm audit signatures` will display the provenance metadata.

Prediction:

Over the next 12 months, staged publishing will become the default for all npm packages, with GitHub eventually deprecating direct `npm publish` for organisations. This will force the entire JavaScript ecosystem to adopt human‑gated releases, dramatically reducing the window of opportunity for supply chain attackers. Expect similar gated publishing models to appear in other package managers (PyPI, RubyGems, Maven) as they follow npm’s lead. Meanwhile, attackers will shift their focus to compromising the approval accounts themselves, leading to increased demand for hardware security keys (WebAuthn) and mandatory 2FA for all maintainers. The arms race continues, but staged publishing raises the bar significantly.

▶️ Related Video (86% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Gvarisco Staged – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky