Skip to content

ci: switch PyPI publish to trusted publishing (OIDC)#59

Merged
skuenzli merged 1 commit intomainfrom
chore/pypi-trusted-publishing
Apr 22, 2026
Merged

ci: switch PyPI publish to trusted publishing (OIDC)#59
skuenzli merged 1 commit intomainfrom
chore/pypi-trusted-publishing

Conversation

@skuenzli
Copy link
Copy Markdown
Contributor

Summary

Switches cedarpy's PyPI publish step from a long-lived API token to PyPI's Trusted Publishing (OIDC). Aligns with our supply-chain hardening work; the PYPI_API_TOKEN secret has already been deleted.

Changes in .github/workflows/CI.yml

  • Remove env: MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} from the Publish to PyPI step — PyO3/maturin-action@v1 auto-detects OIDC when id-token: write is present and no token env is set
  • Add environment: pypi to the release job so it runs in a protected GitHub environment, which:
    • Narrows the OIDC claim so other workflows/branches cannot mint a release token
    • Enables deployment protection rules (manual approval, tag-pattern restrictions, reviewer list)

id-token: write was already present (used for build provenance) and now also covers PyPI publishing.

Prerequisites (must be done before the next v* tag push)

These are manual user actions — this PR only stages the workflow side.

1. Configure PyPI trusted publisher

At https://pypi.org/manage/project/cedarpy/settings/publishing/ add a publisher with:

  • PyPI project name: cedarpy
  • Owner: k9securityio
  • Repository name: cedar-py
  • Workflow name: CI.yml
  • Environment name: pypi

2. Create the pypi GitHub environment

In repo Settings → Environments → New environment:

  • Name: pypi
  • Deployment branches and tags: restrict to tags matching v*
  • Required reviewers: add yourself (recommended — gives a manual approval gate before each release)

Why this is safer than a PyPI API token

  • No long-lived secret to steal
  • OIDC tokens are minted per-run, expire in minutes
  • Environment + tag-pattern rule means a compromised feature branch cannot publish
  • Optional manual approval gate adds a human checkpoint

Test plan

  • PR merges, CI green on PR (no release step runs on PR)
  • After merge, push a test tag (or use the v4.8.1 release) and verify the release job waits for environment approval, then publishes successfully via OIDC
  • Confirm new wheels appear on PyPI with provenance attestations

🤖 Generated with Claude Code

Stop using a long-lived PyPI API token; instead mint a short-lived
OIDC token per release via PyPI's trusted publisher integration.

- Remove MATURIN_PYPI_TOKEN env (secret has been deleted)
- Add `environment: pypi-release` at release job level so the job
  runs in a protected GitHub environment, narrowing the OIDC claim
  and enabling deployment protection rules (manual approval, tag
  pattern, etc.)
- `id-token: write` permission was already present for build
  provenance attestation; it now also covers PyPI publishing

Prerequisites before next release tag is pushed:
1. Configure PyPI trusted publisher for `cedarpy` at
   https://pypi.org/manage/project/cedarpy/settings/publishing/
   with repo `k9securityio/cedar-py`, workflow `CI.yml`, and
   environment `pypi-release`.
2. Create the `pypi-release` GitHub environment in repo settings and
   configure deployment protection rules (recommended: restrict to
   tags matching `v*`, require manual approval).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@skuenzli skuenzli force-pushed the chore/pypi-trusted-publishing branch from 93bb390 to 66d7e07 Compare April 22, 2026 23:09
@skuenzli skuenzli merged commit ac9c9ef into main Apr 22, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant