Skip to content

INFR: Harden workflow permissions, action pinning, and PyPI publishing #872

Description

@mmcky

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:

  1. 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.
  2. 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.
  3. 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.
  4. Dependabot monitors github-actions only, so Python dependencies get no automated freshness or vulnerability signal.

Proposed change

  1. Add a top-level permissions: contents: read to both workflows; grant job-level extras only where needed (id-token: write on the publish job).
  2. 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).
  3. 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).
  4. Add the pip ecosystem to .github/dependabot.yml.

Acceptance criteria

  • permissions: explicit in every workflow; publish job uses OIDC in a protected environment; no PyPI secret remains
  • All third-party actions pinned to commit SHAs
  • A tagged release publishes successfully via the new path
  • Dependabot opens pip update PRs

From the July 2026 technical-debt audit (AI-assisted; claims verified against 28d4b3b and the GitHub API on 2026-07-25).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    high-priorityinfrastructureCI, build, packaging, and repo toolingsecuritySecurity-relevant (cross-cutting)

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions