Skip to content

ci: GHA workflow security cleanup - #7

Merged
emptyhammond merged 5 commits into
mainfrom
worktree-fixup-workflows
Jun 25, 2026
Merged

emptyhammond merged 5 commits into
mainfrom
worktree-fixup-workflows

Conversation

@emptyhammond

Copy link
Copy Markdown
Contributor

Routine hygiene pass over the GitHub Actions workflows in this repo, addressing findings from a workflow security audit. Changes are split into five commits, one per finding type:

  • Disable credential persistence on actions/checkout steps so the default GITHUB_TOKEN is not left in the local git config after checkout.
  • Scope each job's permissions explicitly: top-level permissions: {}, with each job granted only the GITHUB_TOKEN scopes it actually needs (contents: read for check + build; the
    existing id-token: write is retained on the publish jobs).
  • Move workflow-context expansions (${{ steps.setup-python.outputs.python-path }}) out of run: shell source and into env: bindings.
  • Pin all third-party actions to commit SHAs (with the tag preserved as a trailing comment) so an upstream tag move can't silently change what runs in CI.
  • Drop the venv cache from the release workflow. Caches restored into the build that produces published artifacts are a poisoning vector, and the cache key referenced ${{
    matrix.python-version }} from a non-matrix job so it was resolving to an empty segment anyway. The check workflow still caches the venv across PR/push runs.

No behavioural changes intended — the workflows run the same checks against the same inputs.

Add persist-credentials: false to actions/checkout steps so the default
GITHUB_TOKEN is not left in the local git config after checkout. Steps
later in the job do not push to the repo.
Add top-level permissions: {} to both workflows and grant each job only
the GITHUB_TOKEN scopes it actually needs. The check job and the build
job in release only need contents: read; the publish jobs already
declare id-token: write for trusted publishing.
Bind ${{ steps.setup-python.outputs.python-path }} to an env variable
and reference it as "$PYTHON_PATH" in the shell script, so the value
is never interpolated into the script source.
Pin every external action reference to a full 40-char commit SHA, with
the previous tag preserved as a trailing comment. This prevents an
upstream tag move from silently changing what runs in CI.
Remove the actions/cache step (and its companion 'Ensure cache is
healthy' step) from the release build. Caches restored into the build
that produces published artifacts are a poisoning vector, and the cache
key referenced ${{ matrix.python-version }} from a non-matrix job so it
was resolving to an empty segment anyway. The check workflow still
caches the venv across PR/push runs.
@emptyhammond
emptyhammond requested a review from ttypic May 27, 2026 14:42
@emptyhammond
emptyhammond merged commit c94049b into main Jun 25, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants