Skip to content

security: migrate PyPI publish to Trusted Publishing (OIDC) #417

Description

@jacalata

Summary

publish-pypi.yml currently authenticates to PyPI using a long-lived PYPI_API_TOKEN repo secret. This is a security risk: if the secret is ever leaked or the repo is compromised, the token can be used to publish arbitrary versions to PyPI indefinitely.

Recommended fix

Migrate to PyPI Trusted Publishing (OIDC), which is supported natively by pypa/gh-action-pypi-publish. With trusted publishing:

  • No long-lived token is stored anywhere
  • PyPI issues a short-lived token scoped to a specific GitHub repo + workflow + environment for each publish run
  • Even if the workflow is triggered unexpectedly, the token expires immediately after use

Steps

  1. On PyPI, add a Trusted Publisher for tabcmd:

    • Owner: tableau
    • Repository: tabcmd
    • Workflow: publish-pypi.yml
    • Environment: pypi-production (create this environment on the repo with required reviewers)
  2. Update publish-pypi.yml:

    • Add permissions: id-token: write to the job
    • Remove password: ${{ secrets.PYPI_API_TOKEN }} from the publish step
    • The action authenticates automatically via OIDC
  3. Add a pypi-production GitHub environment with required reviewer approval as an extra gate.

  4. Delete the PYPI_API_TOKEN repo secret once verified.

Same change can be applied to TEST_PYPI_API_TOKEN / Test PyPI.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions