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). Where the registry's own publishing documentation names no OIDC flow at all, which is the case for Hex, a token scoped to the single package being published is below the bar and permitted, and the registry limitation is reported beside it. 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 documents no OIDC flow. Its dashboard can issue a key for one package, as confirmed in the hexpm release controller and key controller. Hex 2.4.0 removed mix hex.user key generate, although the publish page still names it. hexpm/hexpm#1785 would retire the Hex fallback if trusted publishing ships. 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