| name | npm-oidc-publishing |
| description | Set up and troubleshoot npm Trusted Publishing with OIDC in GitHub Actions. Use when configuring passwordless npm publishing, debugging ENEEDAUTH errors, or migrating from 90-day npm tokens to OIDC authentication. |
| allowed-tools | Read, Write, Edit, Bash, Grep, Glob, WebSearch |
npm OIDC Trusted Publishing Setup
Overview
This skill helps configure npm Trusted Publishing using OpenID Connect (OIDC), eliminating the need for 90-day rotating npm tokens in GitHub Actions. Instead, GitHub cryptographically proves the workflow's identity to npm.
When to Use This Skill
- Setting up GitHub Actions to publish npm packages without tokens
- Debugging
ENEEDAUTHor404 Not Founderrors during npm publish - Migrating from npm token-based to OIDC-based authentication
- Configuring automated versioning with Changesets
Prerequisites
- npm Account with 2FA enabled (required for Trusted Publishing)
- GitHub repository with Actions enabled
- Node.js 24+ (includes npm 11.5.1+ which supports OIDC)
- Package already published to npm at least once
Step-by-Step Setup
1. Configure npm Trusted Publisher
Go to your package settings on npmjs.com:
URL: https://www.npmjs.com/package/@YOUR_SCOPE/PACKAGE_NAME/access
- Scroll to "Trusted Publisher" section
- Select "GitHub Actions" as publisher
- Fill in the form EXACTLY (case-sensitive, no extra spaces):
| Field | Value | Common Mistakes |
|---|---|---|
| Organization/User | Your GitHub org (e.g., Tasty-Maker-Studio) |
❌ lowercase ❌ different org name |
| Repository | Repository name (e.g., Discourser-Design-System) |
❌ lowercase ❌ wrong repo |
| Workflow | release.yml |
❌ release.yml (space before)❌ release.yml (space after)❌ .github/workflows/release.yml |
| Environment | Leave completely empty | ❌ typing "blank" ❌ any text or spaces |
- CRITICAL: Click "Set up connection" button to activate
- Verify you see the active connection listed with GitHub icon
2. Configure GitHub Actions Workflow
Create .github/workflows/release.yml:
name: Release
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
id-token: write # Required for OIDC
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 24
cache: 'pnpm'
# DO NOT set registry-url - conflicts with OIDC
- run: pnpm install --frozen-lockfile
- run: pnpm build
- name: Publish to npm with OIDC
run: npm publish --provenance --access public
env:
# No NPM_TOKEN needed - OIDC handles auth
Key Points:
- ✅
id-token: writepermission is required - ✅ Node.js 24+ for npm 11.5.1+ (OIDC support)
- ❌ DO NOT set
registry-urlin setup-node (creates .npmrc that conflicts) - ❌ DO NOT use
NODE_AUTH_TOKENenvironment variable - ✅
--provenanceflag helps npm detect OIDC
3. Verify No Conflicting Configuration
Check for files that might interfere:
No npm tokens in GitHub Secrets:
- Settings → Secrets → Actions
- Should have NO
NPM_TOKENsecret
No auth in .npmrc:
.npmrcshould only have config, not authentication- Remove any
//registry.npmjs.org/:_authToken=lines
Correct repository URL in package.json:
{ "repository": { "type": "git", "url": "https://github.com/YOUR_ORG/YOUR_REPO.git" } }
Troubleshooting
Error: ENEEDAUTH - need auth
Cause: npm cannot authenticate with OIDC
Solutions:
Verify Trusted Publisher is ACTIVE (not just configured)
- Go to npmjs.com package settings
- You should see the connection listed with Edit/Delete buttons
- If you see an empty form, you need to click "Set up connection"
Check for typos in npm configuration:
- Click "Edit" on your Trusted Publisher
- Verify NO extra spaces in workflow field
- Verify exact capitalization matches GitHub
Verify OIDC environment: Add debug step to workflow:
- name: Debug OIDC run: | npm --version echo "OIDC URL set: ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL != '' }}"
Error: 404 Not Found - PUT https://registry.npmjs.org/@scope/package
Cause: npm Trusted Publisher configuration doesn't match running workflow
Solutions:
Configuration mismatch - Verify EXACT match:
- Organization: must match GitHub URL (case-sensitive)
- Repository: must match repo name (case-sensitive)
- Workflow: must be exactly
release.yml(no path, no spaces) - Environment: must be empty (not "blank", not spaces)
Workflow file renamed:
- If you renamed
release.ymlto something else, update npm config
- If you renamed
Environment field has value:
- If npm config has environment set to "production", add to workflow:
jobs: release: environment: production # Must match npm config
- If npm config has environment set to "production", add to workflow:
Error: Access token expired or revoked
Cause: npm is trying to use token auth instead of OIDC
Solutions:
Remove
registry-urlfrom setup-node:# ❌ WRONG - creates .npmrc with token - uses: actions/setup-node@v4 with: registry-url: 'https://registry.npmjs.org' # ✅ CORRECT - allows OIDC - uses: actions/setup-node@v4 with: node-version: 24 cache: 'pnpm'Delete
NPM_TOKENfrom GitHub SecretsCheck for
.npmrcwith auth token in repository
Automated Versioning with Changesets
Install Changesets
pnpm add -D @changesets/cli @changesets/changelog-github
pnpm changeset init
Configure .changeset/config.json:
{
"changelog": ["@changesets/changelog-github", {
"repo": "YOUR_ORG/YOUR_REPO"
}],
"access": "public",
"baseBranch": "main"
}
Workflow with Changesets
- name: Create Release PR or Publish
uses: changesets/action@v1
with:
version: pnpm changeset version
publish: pnpm changeset publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# No NPM_TOKEN - using OIDC
Using Changesets
1. Make code changes
2. Create a changeset (not a version bump!):
pnpm changeset
# Select: patch | minor | major
# Write summary of changes
3. Commit the changeset file:
git add .changeset/*.md
git commit -m "feat: add new feature"
git push
4. Workflow creates "Version Packages" PR automatically
5. Merge PR → Auto-publishes to npm via OIDC
Benefits of OIDC Publishing
✅ No token management - No 90-day rotation ✅ Better security - Short-lived, workflow-specific tokens ✅ No secrets - Nothing to leak or expose ✅ Automatic provenance - Cryptographic proof of origin ✅ Easier onboarding - Team members don't need npm tokens
Verification Checklist
Before asking for help, verify:
- npm package has Trusted Publisher ACTIVE (not just configured)
- Clicked "Set up connection" button on npmjs.com
- Workflow has
id-token: writepermission - Using Node.js 24+ in workflow
- NO
registry-urlin setup-node - NO
NPM_TOKENin GitHub Secrets - Organization/Repository/Workflow match EXACTLY (case-sensitive)
- Environment field is completely empty (not "blank")
- Workflow file is named exactly
release.yml
Common Questions
Q: Do I still need npm tokens for local development?
A: Yes, OIDC only works in CI/CD. Local npm publish requires npm login.
Q: Can I use OIDC with private packages? A: Yes, OIDC works with both public and private packages.
Q: Does OIDC work with monorepos? A: Yes, but each package needs its own Trusted Publisher configuration.
Q: Can I have multiple workflows publish the same package? A: Yes, configure multiple Trusted Publishers (one per workflow file).