Skip to main content
FieldValue
CategoryCICD-SEC-2
SeverityMEDIUM
ConfidenceHIGH
OWASPCICD-SEC-2: Inadequate Identity and Access Management
Auto-fix

What the check does

Flags a publishing step that authenticates to a package registry with a long-lived token where the registry supports OIDC trusted publishing:
  • PyPI via pypa/gh-action-pypi-publish with a password: input
  • npm publish with NODE_AUTH_TOKEN
  • cargo publish with CARGO_REGISTRY_TOKEN
  • gem push with GEM_HOST_API_KEY

Why it matters

A long-lived registry token is a standing secret: if it leaks (a poisoned dependency, a log spill, a compromised runner) an attacker can publish malicious package versions until someone notices and rotates it. OIDC trusted publishing replaces the standing token with a short-lived credential minted per run and scoped to the specific workflow, so there is no durable secret to steal.
- uses: pypa/gh-action-pypi-publish@<sha>
  with:
    password: ${{ secrets.PYPI_TOKEN }}   # ← standing secret

Safe alternative

Configure trusted publishing on the registry and drop the token. For PyPI:
permissions:
  id-token: write            # ← OIDC token for this run
steps:
  - uses: pypa/gh-action-pypi-publish@<sha>   # no password: needed
See PyPI trusted publishers and the equivalent OIDC flows for npm, crates.io, and RubyGems.