Context
npm has deprecated classic tokens in favor of more secure granular access tokens with automatic expiration (max 90 days). Manual publishing using classic tokens is no longer sustainable.
Current State
- Publishing is done manually using classic tokens
.github/workflows/npm-publish.yml exists but not configured for automated publishing
- Trusted publisher already configured on npm for the workflow
Proposed Solution
Update to modern npm publishing with provenance (cryptographic supply chain security):
1. Enable npm Provenance
Benefits:
- ✅ Cryptographically signed packages
- ✅ Build transparency (users can verify package was built by GitHub Actions)
- ✅ npm shows "Provenance" badge on package page
- ✅ No long-lived tokens stored in GitHub
2. Use Granular Access Token
- Create granular token with 90-day expiration
- Scope:
@migration-script-runner/core (read/write)
- Enable "Bypass 2FA" for CI/CD automation
- Store in GitHub Secrets as
NPM_TOKEN
3. Choose npm 2FA Setting
Select: "Require two-factor authentication or a granular access token with bypass 2fa enabled"
- Allows automated publishing via GitHub Actions
- Still requires 2FA for manual publishing
- Compatible with provenance/OIDC
Implementation Tasks
Updated Workflow Structure
name: Publish to npm
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for provenance
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm test
- run: npm run build
- run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Expected Outcome
After implementation:
- Releases are automatically published to npm when GitHub release is created
- Published packages show "Provenance" badge on npm
- Users can verify packages were built by official GitHub Actions workflow
- Token expires automatically after 90 days (security improvement)
References
Context
npm has deprecated classic tokens in favor of more secure granular access tokens with automatic expiration (max 90 days). Manual publishing using classic tokens is no longer sustainable.
Current State
.github/workflows/npm-publish.ymlexists but not configured for automated publishingProposed Solution
Update to modern npm publishing with provenance (cryptographic supply chain security):
1. Enable npm Provenance
Benefits:
2. Use Granular Access Token
@migration-script-runner/core(read/write)NPM_TOKEN3. Choose npm 2FA Setting
Select: "Require two-factor authentication or a granular access token with bypass 2fa enabled"
Implementation Tasks
NPM_TOKENto GitHub repository secretspackage.jsonwithpublishConfig.provenance: true.github/workflows/npm-publish.yml:id-token: writepermissionnpm publish --provenance --access publicUpdated Workflow Structure
Expected Outcome
After implementation:
References