npm Trusted Publishing Failing? Check Expiry, Workflow Identity and Permissions

A failed npm release is not automatically a broken token. If your pipeline uses trusted publishing, investigate the configuration and the failing operation before replacing it with a long-lived credential. A successful dependency install, an authenticated local session and an authorized CI publish are different pieces of evidence.

Start here: identify the command that failed, check the trusted publisher’s status, then compare the workflow identity and allowed action. Do not keep rerunning a production release while changing several settings at once.

Evidence and scope: reviewed against official npm and GitHub documentation on 7 October 2026. CoreSecTech did not reproduce an authentication failure or publish a test package. The diagnostic order and evidence checklist below are CoreSecTech recommendations, not measured recovery results. This guide focuses on GitHub Actions publishing to npm, not GitHub Packages.

What changed in October 2026

GitHub’s 2 October announcement says an unvalidated trusted publisher expires 48 hours after creation. Its first successful publish validates it and removes that expiry. A repository or project identity change requires a new trust relationship; ordinary edits do not extend the original deadline. Expired entries remain visible but cannot authorize publishing. Other valid entries are unaffected.

The same notice rejects GitHub Actions OIDC tokens originating from issue_comment, in addition to pull_request_target. It names push, release and workflow_dispatch as permitted alternatives. These are distinct checks: recreating an expired entry does not make a prohibited event acceptable.

This is a configuration-lifetime rule, not a claim that all npm authentication errors began on 2 October. Record what changed in your own workflow before attributing a failure to the announcement.

1. Find the failing operation before changing credentials

Open the failed run and locate the first relevant error, not just the final red job status. Write down whether the failure occurred during dependency installation, package staging, direct publication or another registry operation. Save the command, timestamp and error text privately.

For example, if the job never reached the release step, investigate that earlier failure first. A later publish command cannot provide evidence about authentication if it never ran. Likewise, a successful unrelated job is not a controlled comparison.

Use this triage table to choose one next check. It lists possible explanations, not diagnoses inferred from an error code alone.

ObservationNext check
Trusted publisher is marked expiredConfirm the package, entry and creation time before recreating that entry.
Failure began after moving the release workflowCompare the registered identity with the actual run.
Direct publication fails but staging is intendedCheck the allowed action and the command the workflow actually runs.
Dependency installation fails before releaseInvestigate installation access separately from publication.
CI says staging succeeded but users cannot install the versionCheck staged review and approval status rather than rerunning publication.
Only a local authentication check succeedsCollect evidence from the relevant CI operation.

2. Inspect expiry and the exact publisher entry

Go to npmjs.com, open the package’s settings and inspect Trusted publishing. Record the affected entry’s provider and identifying fields. Do not assume that every entry on the package has the same status. The September multiple-publisher announcement explains that configurations are independent and additive; authorization can match any one of them.

If the relevant entry is expired, GitHub directs maintainers to recreate it to start another 48-hour window. Before doing that, preserve its intended identity and permissions in a private change record. Have a reviewed release ready; do not publish a meaningless version solely to beat the deadline.

Current npm documentation says existing connections cannot be edited in place: changing their fixed fields requires removal and replacement. Do not interpret the changelog’s “ordinary edits” wording as evidence that those fields are editable in today’s interface. Follow the actual supported controls, and leave unrelated working configurations alone.

The announcement describes validation after a successful publish. It does not establish in that notice that merely saving an entry—or merely submitting a staged package—validates it. Check its resulting status instead of treating either action as proof.

3. Compare runtime and workflow identity

The current npm trusted publishing guide requires npm 11.5.1 or later and Node.js 22.14.0 or later. It supports GitHub-hosted runners, not self-hosted runners. For GitHub, match the owner, repository, workflow filename and any configured environment exactly. The filename includes its extension, without the .github/workflows/ prefix. Also check the package’s repository URL. Reusable workflows need attention to the calling workflow identity.

Collect version information from the same job environment as the failed operation. Your laptop’s versions do not establish what CI used. In the package directory, these commands read versions and selected package fields; they do not publish or modify the package:

node --version
npm --version
npm pkg get name version repository.url

npm pkg get documentation confirms retrieval of multiple fields and nested properties. In a monorepo, verify that the working directory is the package you intend to release. Record missing or unexpected values rather than immediately rewriting the manifest.

To inspect the default registry configuration, use:

npm config get registry

This configuration lookup reads one setting. It is not proof of the final destination if package-specific or command-line configuration overrides it. Compare the actual release command and intended registry too. Do not paste entire configuration files into public issues; they may contain private registry details or credentials.

4. Separate OIDC permission from npm permission

GitHub documents id-token: write as the permission needed to request an OIDC identity token. It does not grant general write access to repositories or make npm accept an arbitrary workflow. Check the release job’s permission and, when relevant, caller/callee permissions against the OIDC reference.

Next inspect the entry’s allowed action. npm distinguishes direct publishing from staging and dist-tag management. Do not broaden a stage-only entry simply because a workflow runs the wrong command. First decide whether direct publication is actually intended.

The npm guide also warns that npm whoami is not a test of trusted publishing authorization, and that private dependency installation needs separate authentication. Keep those checks separate. Never print OIDC tokens or access tokens to make troubleshooting easier.

A permission correction should be specific to the release path. Review it with the maintainer responsible for publishing. GitHub’s secure-use guidance recommends least-privilege permissions and warns against exposing privileged workflows to untrusted input. Replacing a blocked event with another trigger requires reviewing who can cause it to run—not just changing the event name.

5. Do not confuse staged with published

Under npm staged publishing, CI can submit a package for review using npm stage publish. A maintainer approves it with 2FA before that version becomes publicly available. Staging needs npm 11.15.0 or later and Node.js 22.14.0 or later—different requirements from basic trusted publishing. Creating a new package through staging also creates a public placeholder, so it is not an invisible test.

Check the intended version in the Staged Packages tab before rerunning. The npm stage command reference says staged and published versions share the uniqueness constraint. It also provides review and download commands. Staging success is evidence of submission, not evidence that a maintainer approved the version or that its contents are safe.

Ask three separate questions: did CI submit the intended artifact, did a maintainer review it, and is the intended version publicly available? A “yes” to the first is not a “yes” to all three.

6. Make one correction and verify the intended result

Choose the smallest change supported by the evidence: replace an expired entry, correct an identity mismatch, update the runtime, or align the release command with the approved action. Document the previous state and the planned change before applying it. Do not remove a working fallback or revoke credentials until the intended replacement has been verified.

Verification must respect release safety. The npm publish reference describes a dry-run option that avoids registry publication; that does not prove npm accepted a real OIDC publish. Do not claim authentication is fixed because a dry run passes. Use the next authorized release, or a maintainer-approved staging workflow, and inspect the resulting operation and configuration status.

If the result remains unclear, stop and escalate with a sanitized evidence record. Avoid repeated production attempts, relaxing 2FA or adding a broad write token just to make the red status disappear.

A useful support record

  • Package and intended version; correct registry; whether this is direct publication or staging.
  • Failed run timestamp, run identifier, commit and triggering event.
  • Node.js and npm versions from that job, plus runner type.
  • Registered workflow identity compared with the actual run; entry status and creation time when available.
  • Exact failing command and sanitized error, without tokens, authorization headers or private package contents.
  • The one correction attempted and the observed result—not an assumed cause.

Frequently asked questions

Does every trusted publisher expire after 48 hours?
No. GitHub’s October notice applies to unvalidated configurations and exempts them after their first successful publish. Check the particular entry rather than assuming an existing working one expired.

Does staging prove the version is live?
No. Submission and maintainer approval are separate. Verify the intended version’s final status before telling users to install it.

Should I add a permanent npm token as the first fix?
No. Diagnose the failed operation and trust configuration first. A credential workaround can conceal the original problem and create another secret to protect.

Does trusted publishing prove a package is harmless?
No. Authorization identifies an allowed release path; it is not a review of every line or dependency. Keep artifact review and release authorization as separate decisions.

Final release checklist

  • The failure is assigned to the correct operation, not just the job’s final status.
  • The relevant publisher is not expired, and its identity matches the actual workflow.
  • The runtime and runner meet the requirements for the intended operation.
  • OIDC permissions, allowed action and event are appropriate without unnecessary expansion.
  • The intended artifact and version have been reviewed; staged and published states are not confused.
  • The final result is verified through the authorized operation, with no secret data exposed.

The objective is a trustworthy release path, not merely a green CI badge. Keep the evidence that explains why the correction was appropriate and what the successful operation actually established.