Introduce Zizmore to audit Github actions - #946
Conversation
Introduces zizmor for GitHub Actions security linting. All rules that currently fail are ignored for now; each will be addressed and its ignore removed in a follow-up commit.
actions/checkout now sets persist-credentials: false so the checked out repo's git credentials aren't persisted for later steps (or leaked via uploaded artifacts). Neither job performs git operations after checkout, so this is safe. Applied via `zizmor --fix=unsafe-only`; removes the artipacked ignore now that it's resolved.
Pin all third-party actions (actions/checkout, ruby/setup-ruby, browser-actions/setup-firefox, actions/upload-artifact, actions/stale) to a commit SHA rather than a mutable tag, so a compromised or force-pushed tag can't silently swap in different code. Applied via `zizmor --fix=unsafe-only`; removes the unpinned-uses ignore now that it's resolved.
Adds a dedicated job that runs zizmor against the workflow definitions on every push and PR, using the .github/zizmor.yml config to skip the one remaining finding (unpinned-images) that has no auto-fix.
Since we control this image we can trust updates to it
There was a problem hiding this comment.
Pull request overview
This PR hardens GitHub Actions security posture by pinning reusable actions to immutable SHAs and adding a dedicated zizmor workflow analysis job to the existing CI pipeline.
Changes:
- Pin GitHub Actions (
checkout,setup-ruby,setup-firefox,upload-artifact,stale) to commit SHAs (with version comments). - Add a new
zizmorjob to lint/analyze workflows viauvx zizmor .. - Disable
persist-credentialson checkouts to avoid leaving credentials in the Git workspace.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| .github/workflows/close_stale_issues_and_prs.yml | Pins actions/stale to a specific commit SHA for supply-chain safety. |
| .github/workflows/ci.yml | Pins key actions to SHAs, disables checkout credential persistence, and adds a zizmor workflow scanning job (with one suppression). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Test coverage92.18% line coverage reported by SimpleCov. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5e6705e. Configure here.
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 |
There was a problem hiding this comment.
Pinned actions lack Dependabot
Medium Severity
Actions were switched from floating tags to immutable SHAs, but Dependabot still only watches bundler. Those pins will not receive automated update PRs, so security fixes in checkout, setup-ruby, upload-artifact, stale, and setup-uv can sit unpatched until someone updates them by hand.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 5e6705e. Configure here.
There was a problem hiding this comment.
This is a tradeoff. I'm not sure how common security issues are in actions
Matches editor-ui's convention of pinning the zizmor package version via uvx, alongside the already SHA-pinned setup-uv action.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (2)
.github/workflows/ci.yml:57
- Prefer
${{ github.token }}over${{ secrets.GITHUB_TOKEN }}for the built-in workflow token to stay consistent with the rest of this workflow (e.g. the coverage comment step usesGITHUB_TOKEN: ${{ github.token }}at line 171) and to avoid unnecessary reliance on thesecretscontext.
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
.github/workflows/ci.yml:103
- With zizmor now running in CI, note that other service images in this workflow (e.g.
postgres:12,redis:6.2-alpine) may also be flagged by theunpinned-imagesrule if it requires digest pinning. If the zizmor job fails on those, you’ll need to either pin them to digests or apply the samezizmor: ignore[unpinned-images]approach consistently.
image: 'ghcr.io/raspberrypifoundation/heroku-connect' # zizmor: ignore[unpinned-images]
adrian-rpf
left a comment
There was a problem hiding this comment.
Looks interesting to me.


Status
What's changed?