Safeguard
Supply Chain•

npm vs PyPI trusted publishing: how the two differ

Both npm and PyPI trusted publishing swap long-lived tokens for short-lived OIDC credentials. Compare providers, requirements, expiry and provenance.

Safeguard Security Team
3 min read

Both npm and PyPI trusted publishing replace long-lived publishing tokens with short-lived credentials issued through OpenID Connect from your CI provider. They differ in supported providers, tool requirements, token lifetime details and provenance. Either way, a stolen token stops being the easy path to a malicious release.

The shared idea

A CI service that acts as an OIDC identity provider issues a short-lived token identifying the workflow and repository. The registry is configured to trust that specific workflow. If the identity matches, the registry accepts the publish. No one pastes a long-lived API token into CI secrets, so there is nothing durable to steal.

PyPI

PyPI's documentation describes the flow in four steps: the CI service issues a token, a PyPI project is configured to trust a specific CI configuration, the job sends its token, and PyPI returns a short-lived API token scoped to that project. That PyPI token expires 15 minutes after creation. The page names GitHub Actions as an example provider and links to quickstarts for setup. It does not list every supported provider, so check the quickstarts.

npm

npm's documentation lists GitHub Actions, GitLab CI/CD on GitLab.com shared runners, and CircleCI cloud. Self-hosted runners are not supported yet. Requirements are npm CLI 11.5.1 or later and Node 22.14.0 or higher.

Setup details differ by provider:

  • GitHub Actions: grant id-token write permission.
  • GitLab: set id_tokens with the audience npm:registry.npmjs.org.
  • CircleCI: set the NPM_ID_TOKEN variable from the CircleCI OIDC command.

Each package supports up to 10 publishers. npm does not validate the configuration when you save it, so mistakes appear at publish time, and a new configuration must complete a first successful publish within 2 days or it expires.

Provenance

For GitHub Actions and GitLab, npm generates provenance attestations automatically when you publish a public package from a public repository. CircleCI does not generate provenance. I did not find equivalent provenance statements on the PyPI page I read, so check PyPI's docs if you need that.

Side by side

npmPyPI
CredentialShort-lived OIDC basedShort-lived token, 15 minutes
Providers namedGitHub Actions, GitLab.com, CircleCIGitHub Actions named as example
Version needsnpm 11.5.1+, Node 22.14.0+See quickstarts
Automatic provenanceGitHub and GitLabNot confirmed here

Do this regardless of registry

  • Remove old publishing tokens once trusted publishing works. npm recommends restricting traditional token publishing in package settings and revoking unused automation tokens.
  • Restrict who can edit the workflow that publishes. Whoever controls that file controls the release.
  • Keep the publishing workflow separate from untrusted pull request code. See Scorecard Dangerous-Workflow.

For a real incident involving expiry rules in trusted publishing, see the npm trusted publishing 48 hour expiry write-up.

Quick check

Does trusted publishing stop a compromised workflow?

No. It removes stored tokens, but anyone who can change the trusted workflow can still publish. Protect that file and its triggers.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.