Streamlining npm Publishing with OIDC in GitHub Actions: A Key Development Activity
Publishing packages to npmjs.com using GitHub Actions and OpenID Connect (OIDC) offers enhanced security and streamlined workflows. However, as Arad1el discovered in a recent GitHub Community discussion, integrating OIDC with Yarn can present some "teething issues," often manifesting as a cryptic "Not found" error during the publish step. This insight delves into the problem and provides a robust solution, ensuring your development activities remain smooth and secure.
The OIDC Publishing Challenge with Yarn in GitHub Actions
Arad1el was attempting to publish a security update to an existing npm package. Their setup involved GitHub Actions with OIDC Trusted Publisher configured on npmjs.com, targeting a specific repository and workflow file (npm-publish.yml). The workflow used Yarn for dependency installation and building, culminating in yarn publish --provenance. Despite careful configuration, the workflow failed with the error: error Couldn't publish package: "https://registry.npmjs.org/[package-name]: Not found".
This error is a common point of confusion. While it suggests the package doesn't exist, the reality, as explained by community experts like shivrajcodez and MHassan-Tariq, is that it's almost always an authentication failure. The npm registry returns a 404 when it cannot properly identify or authorize the publishing entity, rather than explicitly stating an authentication problem.
Unpacking the Root Cause: Yarn v1 vs. OIDC
The core of the issue lies in the compatibility between Yarn v1 (Classic) and the modern OIDC/Provenance handshake required by npm's Trusted Publisher feature. Yarn v1's publish command is built on an older architecture that doesn't natively understand how to exchange a GitHub OIDC token for an npm session. When yarn publish --provenance is executed, it fails to provide the necessary credentials, leading the npm registry to deny access and respond with the misleading "Not found" error.
The Solution: Leveraging npm publish for OIDC-Enabled Development Activities
The most stable and recommended fix, especially for projects still using Yarn v1, is to use the npm CLI for the final publishing step. The npm CLI (version 9.5.0+) is officially designed to handle the OIDC token exchange and provenance generation seamlessly. This approach allows you to continue using Yarn for your installation and build development activities, while relying on npm for the secure deployment.
Here's the updated workflow structure:
name: Publish to npmjs
on:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write # Required for OIDC
contents: read
# packages: write # Only needed if publishing to GitHub Packages; npm only needs id-token
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24 # Good choice, includes npm v11+
registry-url: 'https://registry.npmjs.org/'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build package
run: yarn build
- name: Publish to npm via OIDC
run: npm publish --provenance --access public
# NODE_AUTH_TOKEN is NOT REQUIRED with OIDC; leave this out!
Critical Checklist for Seamless Trusted Publishing
Even with the correct npm publish command, OIDC is highly sensitive to exact configurations. If you still encounter issues, double-check these critical "invisible" settings:
- Case Sensitivity: In your npmjs.com Trusted Publisher settings, ensure the Organization/User and Repository names match the casing in your GitHub URL exactly (e.g.,
Arad1elvsarad1el). - Workflow Filename: The filename configured in npm's Trusted Publisher settings must precisely match your GitHub Actions workflow file (e.g.,
npm-publish.yml). package.jsonRepository Field: Yourpackage.jsonshould include arepositoryfield that accurately points to your GitHub repository:"repository": { "type": "git", "url": "https://github.com/arad1el/your-repo-name.git" }- Scoped Packages: If your package is scoped (e.g.,
@user/package), ensure"publishConfig": { "access": "public" }is present in yourpackage.json, unless it's a private package. - Release Trigger: Confirm your workflow is triggered by a GitHub Release (
on: release: types: [created]), not just a pushed tag, as OIDC validation checks the workflow context carefully.
By making these adjustments, particularly switching to npm publish for the final step, you can overcome common OIDC integration hurdles and ensure your package publishing development activities are secure and efficient. The community's collaborative spirit, as demonstrated in this discussion, continues to be a vital resource for navigating complex developer challenges.