ci: fix zizmor security findings across all GitHub Actions workflows - #4460
Merged
Conversation
zizmor (run via qlty on every PR) flags several classes of workflow
hardening issues; this fixes every one it reports under its default
persona, repo-wide:
- pin every third-party/first-party action to a commit SHA instead of
a mutable tag, so a compromised or force-moved tag can't silently
swap in different code (unpinned-uses)
- set persist-credentials: false on every actions/checkout step that
doesn't need to push, so the job's GITHUB_TOKEN isn't left on disk
for later steps/processes to read (artipacked)
- add least-privilege permissions to every job that was relying on
the broad default token permissions, plus a deny-all top-level
permissions: {} on each workflow so a future job added without its
own block gets nothing by default (excessive-permissions)
- disable Go module/build caching on the two workflows that publish
artifacts on release/push, so a poisoned cache can't taint a
published build (cache-poisoning)
- route template-expanded values used inside shell run: blocks
through env: vars instead of interpolating them directly, so a
value that happens to contain shell metacharacters can't break out
of the intended string (template-injection)
- document why maintainer-pr-notify.yml's pull_request_target trigger
is safe as-is (no checkout, allowlisted same-repo senders only, all
PR data passed through toJSON()) with a zizmor ignore comment rather
than changing its trigger semantics (dangerous-triggers)
Re-ran zizmor locally after: 0 findings under the default persona,
0 medium/high findings even under --persona=pedantic.
Assisted by AI
reinkrul
requested review from
Dirklectisch,
JorisHeadease,
gerardsn,
stevenvegt and
woutslakhorst
as code owners
August 19, 2026 11:38
Contributor
|
Coverage Impact This PR will not change total coverage. 🚦 See full report on Qlty Cloud »🛟 Help
|
stevenvegt
approved these changes
Aug 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
qlty runs zizmor (a GitHub Actions security linter) on every PR. Running it repo-wide against
mastersurfaced 71 findings across every workflow file (7 informational, 9 low, 9 medium, 46 high). This fixes all of them.persist-credentials: falseadded to everyactions/checkoutstep that doesn't need to push, so the job'sGITHUB_TOKENisn't left in.git/configfor later steps to read.permissions:added to every job that was relying on broad default token permissions, plus a deny-all top-levelpermissions: {}on each workflow (same pattern already used inmaintainer-pr-notify.yml) so a future job added without its own block gets nothing by default.cache: falseon the twoactions/setup-gosteps that run in workflows publishing artifacts onrelease/push(build-binaries.yaml,e2e-tests.yaml), so a poisoned Go module cache can't taint a published build.${{ }}expressions insiderun:shell blocks routed throughenv:vars instead, so a value containing shell metacharacters can't break out of the intended string.maintainer-pr-notify.yml'spull_request_targettrigger flagged generically. Reviewed it — it's already safe (no checkout, restricted to same-repo PRs from an allowlist of maintainers, all PR data passed throughtoJSON()/format()rather than shell-interpolated). Added a# zizmor: ignore[dangerous-triggers]comment documenting why, instead of changing the trigger.Verified locally with
zizmor .github/workflows/: 0 findings under the default persona, 0 medium/high findings even under--persona=pedantic. The remaining pedantic-only findings (missing workflowname:fields, missingconcurrency:blocks, undocumented permission comments) are cosmetic code-smell suggestions, not security issues, and out of scope here.Not included
This branch is off
masterdirectly and does not include the docs-only-CI-skipchangesjob pattern from #4459/#4455 — kept separate on purpose.Test plan
zizmorre-run locally confirms 0 findings (default persona) / 0 medium+ findings (pedantic persona)qlty checkshows 0 blocking issues on this PR