Introduction

Publishing an npm package usually requires authentication between the CI/CD system and the npm registry.

For years, a common approach was to create an npm access token, store it as a CI secret, and use that token whenever the pipeline published a package.

That works, but long-lived credentials create an unnecessary security dependency. If a token is exposed, copied into the wrong environment, or remains active after a project changes ownership, it can become a supply-chain security problem.

npm Trusted Publishing provides another approach. Instead of storing a long-lived npm token in the CI environment, the package can be published using an identity established between npm and a supported trusted CI/CD provider through OpenID Connect (OIDC).

The result is a publishing workflow where the CI job proves its identity to npm without requiring a persistent npm publishing token.

What Is npm Trusted Publishing?

Trusted Publishing allows a supported CI/CD workflow to authenticate to npm using an OIDC identity token.

The basic model looks like this:

Developer
   |
   v
Git Repository
   |
   v
CI/CD Workflow
   |
   | OIDC identity
   v
npm Registry
   |
   v
Published Package

Instead of:

CI/CD
   |
   | Long-lived npm token
   v
npm Registry

the workflow obtains a short-lived identity assertion from the CI platform.

The npm registry verifies that the workflow is coming from a configured trusted environment.

Why Long-Lived npm Tokens Are Risky

A traditional publishing workflow might look like:

GitHub Actions
      |
      v
NPM_TOKEN
      |
      v
npm publish

The token must be stored somewhere.

Usually this means:

Every additional location increases the number of places where the credential could potentially be exposed.

A compromised token may also remain usable until it is revoked or expires.

Trusted publishing changes the credential model by reducing the need for a persistent npm publishing credential.

How OIDC Authentication Works

OIDC stands for OpenID Connect.

In this scenario, the CI platform acts as the identity provider and issues an identity token for the workflow.

Conceptually:

1. Workflow starts
       |
       v
2. CI platform identifies workflow
       |
       v
3. OIDC token issued
       |
       v
4. npm verifies token
       |
       v
5. npm allows publishing

The identity token can contain information about the workflow context.

Depending on the CI provider and configuration, this can include information such as:

npm can use that information when deciding whether the publishing request is trusted.

Trusted Publishing vs npm Tokens

Area

Long-Lived Token

Trusted Publishing

Persistent npm credential

Required

Not required for the publishing flow

Credential lifetime

Potentially long

Short-lived identity token

CI secret management

Required

Reduced

Workflow identity

Indirect

Explicit

Rotation

Must be managed

Short-lived credentials reduce rotation burden

Supply-chain exposure

Higher if token leaks

Reduced credential exposure

Initial setup

Familiar

Requires trusted publisher configuration

Trusted publishing does not eliminate every security risk.

The CI workflow itself still needs to be secured.

Supported CI/CD Workflow

A typical trusted publishing setup looks like:

Repository
    |
    v
CI Workflow
    |
    +---- Build
    |
    +---- Test
    |
    +---- OIDC Authentication
    |
    v
npm publish

The workflow should only publish after the package passes the required validation stages.

For example:

Checkout
   |
   v
Install Dependencies
   |
   v
Build
   |
   v
Test
   |
   v
Package Validation
   |
   v
Publish

Authentication should be associated with the publishing stage rather than unnecessarily exposing publishing credentials to earlier steps.

Configuring the npm Package

Before enabling trusted publishing, verify the package metadata.

A basic package.json might look like:

{
  "name": "@example/my-package",
  "version": "1.0.0",
  "description": "Example npm package",
  "main": "dist/index.js",
  "scripts": {
    "build": "npm run compile",
    "test": "npm test"
  }
}

For scoped packages, ensure the package name and npm organization configuration are correct.

The package must also be associated with the correct publishing account or organization.

Configure the Trusted Publisher

The npm package configuration needs to identify the trusted CI/CD relationship.

The exact fields depend on the supported CI provider.

Conceptually, the package stores information equivalent to:

Trusted Publisher
-----------------
CI Provider
Repository
Workflow
Environment

This creates an explicit trust relationship.

For example:

npm Package
     |
     v
Trusted Publisher
     |
     +---- CI Provider
     +---- Repository
     +---- Workflow

A workflow from an unrelated repository should not automatically inherit publishing permissions.

GitHub Actions Example

A typical GitHub Actions publishing workflow needs permission to request an OIDC identity token.

For example:

name: Publish Package

on:
  release:
    types: [published]

permissions:
  contents: read
  id-token: write

jobs:
  publish:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Test
        run: npm test

      - name: Publish
        run: npm publish

The important part is the OIDC permission:

permissions:
  id-token: write

Without permission to request an identity token, the workflow cannot use OIDC-based trusted publishing.

The exact workflow should be adapted to the project's release strategy and supported npm configuration.

Why id-token: write Does Not Mean npm Write Access

This permission can be confusing.

id-token: write

does not mean:

Write packages to npm

It allows the workflow to request an OIDC identity token from the CI platform.

npm independently decides whether that identity is trusted to publish the package.

The distinction is important:

CI Permission
      |
      v
Request Identity Token
      |
      v
npm Trust Configuration
      |
      v
Publishing Authorization

Both parts matter.

Removing the npm Token

After trusted publishing is correctly configured, the workflow should not continue depending on an unnecessary publishing token.

A traditional workflow might contain:

env:
  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

A trusted publishing workflow can remove that dependency when the package and CI provider support the trusted flow.

The goal is to reduce the number of long-lived secrets in the publishing pipeline.

Do not remove an existing credential until the new workflow has been tested successfully.

Protect the Publishing Workflow

Removing an npm token does not automatically make the pipeline secure.

An attacker who can modify the publishing workflow may still be able to influence the publishing process.

Protect:

The publishing workflow should be treated as part of the package's software supply chain.

Prevent Unauthorized Releases

A common pattern is to publish only from an approved release event.

For example:

on:
  release:
    types: [published]

This is generally easier to reason about than allowing every branch push to publish a package.

Another approach is to use a protected release branch or environment.

The exact policy depends on the package's release process.

Use a Build-Then-Publish Model

The publishing job should not be responsible for discovering whether the package works.

A stronger pipeline separates validation from publication:

Source
  |
  v
Build
  |
  v
Test
  |
  v
Package
  |
  v
Verify Package
  |
  v
Publish

For example:

npm ci
npm run build
npm test
npm pack --dry-run
npm publish

npm pack --dry-run can help inspect what would be included in the package before publishing.

This is useful for detecting:

Check the Published Package Contents

A package may contain files that were never intended to be distributed.

Before publishing:

npm pack --dry-run

Review the resulting file list.

For a production package, explicitly consider:

dist/
src/
README
LICENSE
package.json
tests/
configuration files

The final package should contain only what consumers need.

Prevent Secret Leakage

Trusted publishing reduces npm credential exposure, but CI logs can still leak secrets from other parts of the pipeline.

Avoid commands that print:

Environment variables
Authentication headers
Private configuration
Cloud credentials

Be particularly careful with debugging commands such as:

env
printenv
set

Never enable verbose logging around authentication unless you understand exactly what information is being exposed.

Trusted Publishing and Monorepos

Monorepos introduce another consideration.

Suppose one repository contains:

/packages/core
/packages/ui
/packages/cli

and each directory publishes a separate npm package.

The trust configuration must match the actual publishing architecture.

You should define:

Package A -> Approved workflow
Package B -> Approved workflow
Package C -> Approved workflow

rather than assuming every package in the repository should have identical publishing permissions.

This becomes particularly important when packages have different owners or release schedules.

Trusted Publishing and Package Provenance

Modern npm supply-chain security also involves package provenance.

A publishing workflow can provide stronger information about where an artifact originated.

Conceptually:

Source Repository
       |
       v
CI Workflow
       |
       v
Build Artifact
       |
       v
npm Package
       |
       v
Provenance Information

This helps consumers establish a relationship between the published package and its build environment.

Trusted publishing and provenance address related but different concerns.

Trusted publishing controls who is allowed to publish.

Provenance helps establish where the published artifact came from.

Common Mistakes

Leaving Old Publishing Tokens Everywhere

After moving to trusted publishing, audit old npm tokens and remove credentials that are no longer required.

Forgetting OIDC Permissions

The workflow must be permitted to request an identity token.

Trusting the Wrong Workflow

The trusted publisher configuration should identify the intended repository and workflow.

Publishing From Every Branch

Limit publishing to a controlled release process.

Giving the Entire Workflow Excessive Permissions

Use the minimum permissions required by each job.

Skipping Package Inspection

A successful build does not guarantee that the published package contains the correct files.

Treating OIDC as a Complete Security Solution

Trusted publishing protects the publishing credential model, but compromised source code or CI workflows can still produce malicious packages.

Troubleshooting Trusted Publishing

npm Rejects the Publishing Request

Check:

  1. The package's trusted publisher configuration

  2. Repository identity

  3. Workflow identity

  4. CI OIDC permissions

  5. Release environment

  6. Node.js and npm versions

  7. Package ownership

OIDC Token Is Not Available

Verify:

permissions:
  id-token: write

Also confirm that the job requesting the token inherits the required permission.

Local npm publish Works but CI Fails

Local publishing may use credentials stored in the developer's environment.

CI trusted publishing is a separate authentication path.

Test the workflow independently rather than assuming local credentials validate CI configuration.

Package Is Published From the Wrong Workflow

Review the trusted publisher configuration and the workflow that actually executes the publish step.

Authentication Works but Package Contents Are Wrong

Run:

npm pack --dry-run

and inspect the package contents before changing authentication settings.

Best Practices

  1. Prefer short-lived trusted identities over long-lived publishing tokens when supported.

  2. Keep OIDC permissions limited to the publishing job.

  3. Restrict which workflow can publish.

  4. Protect workflow files from unauthorized changes.

  5. Publish only after build and test validation.

  6. Inspect package contents before release.

  7. Remove obsolete npm tokens after migration.

  8. Use protected release environments where appropriate.

  9. Keep Node.js and npm versions controlled in CI.

  10. Audit package ownership and publishing permissions.

  11. Protect dependencies and build scripts.

  12. Review CI logs for accidental credential disclosure.

  13. Use provenance where it fits the package supply-chain model.

  14. Test the complete release process before removing existing credentials.

Advantages and Disadvantages

Advantages

Disadvantages

When Should You Use npm Trusted Publishing?

Trusted publishing is particularly useful when:

For a package published manually by a developer, the operational model is different. Trusted publishing is most valuable when publication is already automated.

Migration Checklist

Before switching a package:

  1. Identify the current publishing workflow.

  2. Record the existing npm authentication method.

  3. Verify package ownership.

  4. Configure the trusted publisher.

  5. Enable OIDC permissions in CI.

  6. Test the workflow in a controlled release process.

  7. Verify package contents.

  8. Confirm the published package version.

  9. Check provenance where applicable.

  10. Remove obsolete publishing credentials.

  11. Review repository and workflow permissions.

  12. Document the new release process.

Summary

npm Trusted Publishing changes the way CI/CD systems authenticate when publishing packages.

Instead of relying on a long-lived npm token stored as a secret, a supported workflow can use an OIDC identity that npm verifies against a configured trusted publisher.

The security benefit comes from reducing persistent credentials, but the broader release pipeline still needs protection. Workflow permissions, repository access, package contents, dependency security, and release controls remain important.

For teams already publishing npm packages through CI/CD, trusted publishing provides a cleaner authentication model and reduces one of the common sources of long-lived credentials in JavaScript software supply chains.