Skip to content
oss-kit
Install

The publish job authenticates to the registry with trusted publishing, not a stored token

Rule
R-PUB-02
Forge scope
GitHub and GitLab
Fixed by
oss-publish

A long-lived registry token in CI secrets is the single credential that turns any workflow compromise into a supply-chain compromise. Trusted publishing exchanges a short-lived OIDC token per run, so there is nothing to steal between releases.

Observable check

the publish job requests id-token: write and publishes through the registry's OIDC flow (npm trusted publishing, PyPI trusted publishers, RubyGems OIDC, crates.io trusted publishing, or Hex Workload Identity for existing public packages on GitHub Actions). Where the registry's own publishing documentation names no supported OIDC flow for the actual package and forge combination, a token scoped to the single package being published is below the bar and permitted, and the registry limitation is reported beside it. This includes Hex first publication and unsupported providers, not its supported Workload Identity flow. That is not the same as a registry documenting a flow this standard has not enumerated, which is unverified rather than absent: read the registry's documentation and report the rule unknown until the flow is checked, because the scoped-token fallback would otherwise pass a repository that could have used OIDC. Where the registry documents no credential narrower than the publishing account, which is the case for Maven Central, an account-scoped token is below the bar and permitted. Report the compensating controls that keep it below the bar rather than at it: an expiry set when the token is generated, revocation and replacement on compromise, namespace ownership verified against the account, and credentials available only to the forge job after its native publication gate passes. Sonatype has announced namespace-scoped and artifact-scoped tokens without shipping them, so re-read the registry's token documentation before accepting this fallback rather than treating it as settled. A repository that publishes to no registry, shipping only built assets on a forge release, falls outside this rule rather than failing it.

Where this comes from

Last read against these sources on 2026-08-07.

npm, PyPI, RubyGems, and crates.io document OIDC publishing with short-lived credentials. Hex supports GitHub Workload Identity, checked 2026-10-11 against its publishing page and official setup source. Existing public packages exchange OIDC for a short-lived package token. Unsupported providers retain the scoped dashboard-key fallback. The linked public setup guide returned 404, so target deployment availability still needs checking. Other registry claims retain their earlier verification dates. Maven Central also documents no OIDC flow and no artifact-scoped or namespace-scoped token. Sonatype documents token expiry, revocation, namespace ownership, and autoPublish for CI. The Portal API uses the same user token for upload and for the publish endpoint. A USER_MANAGED deployment therefore provides an optional review stop, but it does not protect publication from CI that still holds that token. The compensating control requires the Central token and signing secret to become available only after a native forge gate. GitHub environment secrets become available after environment approval. GitLab protected environments can limit deployment variables and blocking manual jobs to authorized users. Sonatype's 2025 roadmap lists scoped tokens as planned. Re-read the token page before accepting this fallback.

Read the whole standard