Skip to content
Latchkey

How to Publish an npm Package With Provenance in GitHub Actions

With id-token: write and npm publish --provenance, npm records a signed link from the published version back to this exact workflow run.

Provenance attaches a verifiable attestation showing where and how the package was built. Set the registry, grant id-token: write, and pass --provenance (or provenance=true in .npmrc) on publish.

Steps

  • Use actions/setup-node with registry-url: https://registry.npmjs.org.
  • Add permissions: id-token: write and contents: read.
  • Publish with npm publish --provenance --access public using an automation token.

Workflow

.github/workflows/publish.yml
permissions:
  id-token: write
  contents: read
jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          registry-url: https://registry.npmjs.org
      - run: npm ci && npm run build
      - run: npm publish --provenance --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Common pitfalls

  • Provenance requires id-token: write; without it npm publish --provenance exits with an error.
  • Provenance is only generated on supported CI (like GitHub Actions) and a public registry; it will not attach for a private scope.
  • A classic read-only token cannot publish; use an automation token with publish rights as NODE_AUTH_TOKEN.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →