Trusted Publishing

Provenance and Trusted Publishing

A tarball on the registry proves nothing about where it came from. Provenance fixes that: the CI job that runs npm 2,036 publish also signs a statement naming the repository, commit and workflow that built the tarball, and puts it in Sigstore 69,885 's public transparency log, so anyone can check that the code on GitHub 29 is the code in the package. Trusted publishing removes the token as well — register the workflow as a trusted publisher on the package's settings page, and the runner exchanges a short-lived OIDC identity token for a credential that expires in minutes.

Trusted publishing: a short-lived identity replaces a stored token
Trusted publishing: a short-lived identity replaces a stored token
A GitHub Actions job that publishes with provenance and no tokenJavaScript
permissions:
  id-token: write
  contents: read
steps:
  - uses: actions/checkout@v5
  - uses: actions/setup-node@v5
    with: { node-version: '24', registry-url: 'https://registry.npmjs.org' }
  - run: npm ci
  - run: npm publish

id-token: write is the whole secret: it lets the job request the identity token. npm generates the provenance attestation automatically for a public package built from a public repository on GitHub Actions 29 or GitLab CI/CD 377 ; CircleCI 10,326 is a supported trusted publisher but does not produce provenance. Trusted publishing needs npm 11.5.1 or later on Node 22.14.0 or later, and only cloud runners qualify. Once the publisher is registered, switch the package to "require two-factor authentication and disallow tokens" so a stolen token cannot be used at all, and verify an installed tree with npm audit signatures.