npm Stage-Only Tokens: Safer GitHub Actions Publishing

Use npm stage-only tokens to let CI submit package versions for review without giving automation direct publish access. Includes setup, commands, and migration tips.

A package moving through an automated security gate before release

A CI job should be able to build and submit a package without being able to publish it directly to every consumer. npm’s new Read and write (stage only) granular access token gives you that boundary: automation stages a version, then a maintainer reviews and approves it with two-factor authentication. GitHub announced the option on September 18, 2026. Read npm’s staged publishing guide and GitHub’s announcement for the current behavior.

This is useful for release workflows that still need token authentication, especially while teams move toward trusted publishing with OIDC. It also matters because npm is targeting January 2027 to remove direct publishing through bypass-2FA tokens.

What a stage-only token changes

A normal publish workflow ends with npm publish. A stage-only workflow ends with npm stage publish. The first makes a new version available immediately. The second uploads it to npm’s staging area, where it is not publicly installable until a maintainer approves it with 2FA.

The token rejects direct npm publish attempts for new versions. That is the key safety property: stealing the CI token does not give an attacker the final publish action. The token still has other write capabilities, including moving dist-tags and deprecating versions, so store and scope it like any other write credential.

# CI: submit the package for human review
npm stage publish

# Maintainer: inspect pending versions
npm stage list <package-name>
npm stage view <stage-id>
npm stage download <stage-id>

# Maintainer: publish after review, with 2FA
npm stage approve <stage-id>

# Or discard the staged version
npm stage reject <stage-id>

Requirements before you migrate

The package must already exist on npm. Staged publishing is for new versions of an existing package, not the first publish of a brand-new package. The account also needs publish access and 2FA enabled for the approval step.

Use npm CLI 11.15.0 or later and Node.js 22.14.0 or later. Check the versions inside the CI runner, not just on your laptop:

node --version
npm --version
npm whoami

Do not log the token, pass it in a command argument, or print the complete environment while debugging. Let the CI platform inject it as a secret and keep the package name and registry explicit in the workflow.

A minimal GitHub Actions migration

The smallest useful change is to keep your build and versioning steps intact, replace the token permission with Read and write (stage only), and replace the final publish command. Keep approval outside the automated job so the human review remains a real boundary.

name: stage-package

on:
  workflow_dispatch:

jobs:
  stage:
    runs-on: ubuntu-latest
    permissions:
      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 test
      - run: npm stage publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_STAGE_TOKEN }}

The exact workflow will vary if you use pnpm, Yarn, a release tool, or a reusable workflow. The important parts are the stage-only token, npm stage publish, and a separate approval step. Do not leave a second npm publish command in a fallback branch, release script, or composite action.

Review the package before approval

The staging step is not the review. It only moves the proposed version into a holding area. Before approval, inspect the staged tarball and verify:

• the package version and dist-tag;
• the files included in the tarball;
• generated code, install scripts, and dependency changes;
• provenance or release metadata expected by your consumers;
• the commit, workflow run, and reviewer that produced the artifact.

Stage-only tokens versus trusted publishing

Trusted publishing uses OIDC instead of a long-lived npm token and is usually the better end state for a fixed CI provider and repository. npm’s trusted publisher documentation describes that model. Stage-only tokens are the practical bridge when your automation still needs a granular access token, or when you want a human approval gate even with OIDC.

Do not treat stage-only as a complete token lockdown. It blocks direct publication of new versions, but it does not remove every package write capability. If you keep using a token, limit it to the packages and workflow that need it, rotate it, and move to trusted publishing when the integration is ready.

Migration checklist

1. Upgrade the release runner to Node.js 22.14.0 or later and npm 11.15.0 or later.
2. Create a granular npm token with Read and write (stage only) permission for the required packages.
3. Replace npm publish with npm stage publish.
4. Test the workflow against an existing package and verify that the version is staged, not live.
5. Review the tarball and approve it with 2FA.
6. Delete the old bypass-2FA token after the new path is proven.
7. Plan the move to trusted publishing before the January 2027 direct-publishing change.

The short version

CI should prepare releases; a maintainer should approve the artifact that becomes public. npm stage-only tokens make that separation available now. Swap the token, change one command, review the staged tarball, and keep trusted publishing on the roadmap.