Problem
Standard supply-chain protections are absent from the CI/publishing pipeline (no known incident — this is hygiene). Repository-level settings (default GITHUB_TOKEN scope, Actions PR-approval, branch protection on main) are being hardened directly by the maintainers; this issue tracks the workflow-file and publishing changes that need code:
- No
permissions: blocks in either workflow, so every job — and every third-party action it invokes — runs with the repository-default token scope rather than least privilege.
- Third-party actions are pinned to mutable major tags (
conda-incubator/setup-miniconda@v4, coverallsapp/github-action@v2), which resolve to whatever the tag points at today and offer no integrity guarantee.
- PyPI publishing uses a long-lived
PYPI_TOKEN secret in the publish job. PyPI Trusted Publishing (OIDC) has been the recommended mechanism since 2023 — short-lived, workflow-bound credentials with nothing to leak at rest. The job also has no environment: gate, so there is no approval step between a tag push and a public release.
- Dependabot monitors
github-actions only, so Python dependencies get no automated freshness or vulnerability signal.
Proposed change
- Add a top-level
permissions: contents: read to both workflows; grant job-level extras only where needed (id-token: write on the publish job).
- Pin third-party actions to full commit SHAs with the version in a trailing comment (Dependabot updates SHA-pinned actions, rewriting SHA and comment together).
- Register the repo/workflow as a Trusted Publisher on PyPI; switch the publish step to OIDC; gate it behind a protected
environment: (e.g. pypi); revoke and delete PYPI_TOKEN once the first OIDC publish succeeds (verify on TestPyPI first).
- Add the
pip ecosystem to .github/dependabot.yml.
Acceptance criteria
From the July 2026 technical-debt audit (AI-assisted; claims verified against 28d4b3b and the GitHub API on 2026-07-25).
Problem
Standard supply-chain protections are absent from the CI/publishing pipeline (no known incident — this is hygiene). Repository-level settings (default
GITHUB_TOKENscope, Actions PR-approval, branch protection onmain) are being hardened directly by the maintainers; this issue tracks the workflow-file and publishing changes that need code:permissions:blocks in either workflow, so every job — and every third-party action it invokes — runs with the repository-default token scope rather than least privilege.conda-incubator/setup-miniconda@v4,coverallsapp/github-action@v2), which resolve to whatever the tag points at today and offer no integrity guarantee.PYPI_TOKENsecret in thepublishjob. PyPI Trusted Publishing (OIDC) has been the recommended mechanism since 2023 — short-lived, workflow-bound credentials with nothing to leak at rest. The job also has noenvironment:gate, so there is no approval step between a tag push and a public release.github-actionsonly, so Python dependencies get no automated freshness or vulnerability signal.Proposed change
permissions: contents: readto both workflows; grant job-level extras only where needed (id-token: writeon the publish job).environment:(e.g.pypi); revoke and deletePYPI_TOKENonce the first OIDC publish succeeds (verify on TestPyPI first).pipecosystem to.github/dependabot.yml.Acceptance criteria
permissions:explicit in every workflow; publish job uses OIDC in a protected environment; no PyPI secret remainsFrom the July 2026 technical-debt audit (AI-assisted; claims verified against
28d4b3band the GitHub API on 2026-07-25).