Skip to content

ci: pin GitHub Actions to commit SHAs and add zizmor to CI - #126

Merged
randomparity merged 4 commits into
mainfrom
chore/pin-actions-shas-zizmor-124
Jul 28, 2026
Merged

ci: pin GitHub Actions to commit SHAs and add zizmor to CI#126
randomparity merged 4 commits into
mainfrom
chore/pin-actions-shas-zizmor-124

Conversation

@randomparity

Copy link
Copy Markdown
Owner

Pins every GitHub Actions reference to a commit SHA and adds a zizmor gate to CI.

Closes #124

Changes

Pin actions to commit SHAs. All 8 references to actions/checkout and
actions/setup-python across lint.yml, test.yml, and sync-wiki.yml move
from the mutable @v7 major tag to a full commit SHA with a trailing # v7
comment:

Action SHA
actions/checkout 3d3c42e5aac5ba805825da76410c181273ba90b1
actions/setup-python 5fda3b95a4ea91299a34e894583c3862153e4b97

Renovate keeps digests current. helpers:pinGitHubActionDigests is added to
extends in renovate.json5. The existing automerge rule already lists
digest in matchUpdateTypes, so digest refreshes merge without review burden.

zizmor runs in CI. zizmor==1.28.0 is added to requirements-dev.txt, which
the lint job already installs, and the lint job gains a
zizmor --min-severity high .github/workflows/ step that fails the build on
High-severity findings. Installing via pip rather than a marketplace action
avoids introducing another action dependency to pin, and keeps local runs on the
same version as CI. The exact pin means a new zizmor release cannot turn a fresh
audit rule into an unrelated CI failure; Renovate proposes bumps as PRs.

Least-privilege permissions. lint.yml and test.yml had no permissions:
block and inherited the default token scope. Both now declare workflow-level
contents: read.

Credential persistence. persist-credentials: false is set on the four
checkouts that only read.

The wiki checkout in sync-wiki.yml is deliberately left persisting its
credentials: the git push step relies on WIKI_TOKEN being written to that
checkout's .git/config. Setting persist-credentials: false there — which
zizmor offers as an auto-fix — would break the wiki sync. The step carries a
comment explaining this and a # zizmor: ignore[artipacked] marker so the
auto-fix is not applied later.

Also included

.secrets.baseline recorded the open_notebook molecule test password at line 28;
it has been at line 39 for some time, so prek run --all-files failed on main
before this branch. The baseline is refreshed. No new secrets are baselined —
the diff is one line number and the timestamp.

Verification

Run locally on the branch head, each checked by exit code:

Check Result
zizmor .github/workflows/ 0 findings at every severity
zizmor --min-severity high .github/workflows/ pass (the CI invocation)
actionlint pass
make lint pass
.venv/bin/pytest pass (29 tests)
prek run --all-files pass

zizmor on main reported 8 High (unpinned-uses), 4 Medium
(excessive-permissions), and 5 Low (artipacked). All 17 are resolved; the one
remaining finding is the intentional wiki-checkout artipacked, explicitly
ignored.

Checked that nothing depended on what was removed: neither lint.yml nor
test.yml runs any git operation, requirements.yml sources no collections over
SCM, and Molecule pulls fedora:43 from Docker Hub rather than GHCR, so no
packages:read scope is required.

🤖 Generated with Claude Code

randomparity and others added 4 commits July 28, 2026 15:28
Replace the mutable @v7 major tags on actions/checkout and
actions/setup-python with full commit SHAs plus a trailing version
comment, so a repointed upstream tag cannot inject new code into CI.

Refs #124

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add workflow-level 'permissions: contents: read' to lint.yml and
test.yml, which previously inherited the default token scope. Set
persist-credentials: false on every checkout that only reads.

The wiki checkout in sync-wiki.yml keeps its persisted credentials --
the push step depends on them -- and carries a comment plus a zizmor
ignore so the unsafe auto-fix is not applied to it.

Refs #124

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add zizmor to requirements-dev.txt (pinned, so CI and local runs agree)
and run 'zizmor --min-severity high .github/workflows/' in the lint job,
which fails the build on High-severity findings.

Extend renovate with helpers:pinGitHubActionDigests so newly added
actions are pinned and existing digests stay current; the automerge rule
already covers the resulting digest updates.

Refs #124

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The baseline recorded the open_notebook molecule test password at line
28; it has been at line 39 for some time, so 'prek run --all-files'
failed on main. No new secrets are baselined.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@randomparity

Copy link
Copy Markdown
Owner Author

Review — issue #124

  • Verdict: approve
  • Findings: 2 raised, 2 resolved, 0 open
    1. Deliberate zizmor finding left unmarked — the wiki checkout's intentional credential persistence was documented only in a human-readable comment, leaving it exposed to zizmor --fix. Resolved by adding # zizmor: ignore[artipacked] alongside the comment, taking the workflows to 0 findings at every severity.
    2. Pre-existing red guardrailprek run --all-files failed on main due to a stale .secrets.baseline line number for a file outside this change's scope. Resolved in its own commit so the CI gate this PR adds lands on a green baseline.
  • Iterations: 1 (self-review; scope is declarative CI config with no logic paths)
  • Security review status: performed as part of the review, since this change is a supply-chain hardening change. Verified: (a) both pinned SHAs resolve to real commits on the v7 lightweight tags via the GitHub API, not invented; (b) nothing depended on the removed credentials — no git operations in lint.yml/test.yml, no SCM-sourced Galaxy collections; (c) contents: read is sufficient — Molecule pulls fedora:43 from Docker Hub, so no packages:read is needed; (d) the sync-wiki.yml push path is untouched and still receives its WIKI_TOKEN.
  • Residual risk / follow-up: sync-wiki.yml keeps job-level contents: write, but its push authenticates with WIKI_TOKEN rather than GITHUB_TOKEN, so that scope may be reducible to contents: read. zizmor does not flag it and it cannot be verified without a live wiki-sync run, so it is left as-is — worth a separate issue rather than an untested change here.

@randomparity
randomparity merged commit c0ab605 into main Jul 28, 2026
6 checks passed
@randomparity
randomparity deleted the chore/pin-actions-shas-zizmor-124 branch July 28, 2026 22:37
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.

Pin GitHub Actions to commit SHAs and add zizmor to CI

1 participant