Skip to content

[Code scan] Harden PyPI publish workflow trigger and OIDC permissions #565

Description

@njzjz

This issue was found during a Codex global code scan of the repository.

Baseline commit: e3c5b38

Problem

The PyPI release workflow runs on every push and pull request, but grants id-token: write at the job level before the tag-only publish step. The publish condition also accepts any pushed tag name.

Code references:

on: [push, pull_request]
name: Release to pypi
jobs:
release-to-pypi:
name: Release to pypi
runs-on: ubuntu-latest
permissions:
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write
steps:
- uses: actions/checkout@v5
- run: pipx run uv tool run --with build[uv] --from build python -m build --installer uv -o python_dist
- name: Publish a Python distribution to PyPI
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: python_dist/

Relevant snippet:

on: [push, pull_request]
...
permissions:
    id-token: write
...
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')

Impact

OIDC token minting permission is available to the whole job even for non-release events, and accidental tags such as test-release or latest would satisfy the publish gate. This increases the blast radius of the release workflow.

Suggested fix

Split build/test and publish into separate jobs. Give id-token: write only to a publish job with a job-level release condition, restrict triggers to version tags such as v* or v[0-9]*, and validate that the tag matches the package version before publishing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions