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
-
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)
-
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
-
Add a pypi-production GitHub environment with required reviewer approval as an extra gate.
-
Delete the PYPI_API_TOKEN repo secret once verified.
Same change can be applied to TEST_PYPI_API_TOKEN / Test PyPI.
References
Summary
publish-pypi.ymlcurrently authenticates to PyPI using a long-livedPYPI_API_TOKENrepo 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:Steps
On PyPI, add a Trusted Publisher for
tabcmd:tableautabcmdpublish-pypi.ymlpypi-production(create this environment on the repo with required reviewers)Update
publish-pypi.yml:permissions: id-token: writeto the jobpassword: ${{ secrets.PYPI_API_TOKEN }}from the publish stepAdd a
pypi-productionGitHub environment with required reviewer approval as an extra gate.Delete the
PYPI_API_TOKENrepo secret once verified.Same change can be applied to
TEST_PYPI_API_TOKEN/ Test PyPI.References