You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
zizmor runs in CI as a blocking check (#6251 added it advisory, #6274 made it gate at medium). This issue tracked working through what it reported.
111 findings at the start → 0.
GH_TOKEN=$(gh auth token) pipx run zizmor==1.29.0 --persona=regular .github/
No findings to report. Good job!
zizmor defaults to offline mode — run it with GH_TOKEN set or the numbers won't match, since offline hides some rules and rates artipacked higher than it deserves.
The four that are suppressed rather than fixed (#6262)
Each carries its justification inline, so the reasoning sits with the code:
pr-size-label-apply.yml, release-notes.yml — dangerous-triggers. The workflow_run trigger cannot be dropped in either case; the weakness that made the first dangerous was fixed in Derive PR number from the triggering run in the size labeler #6259, and the second checks out the default branch rather than an event-supplied ref.
claude.yml — artipacked. contents: write exists so Claude can push commits; the credential is in use. Do not "fix" this one.
api-compat.yml — artipacked. Cannot push, runs a git fetch, and is the repository's only required status check.
Things worth remembering
--format=sarif suppresses zizmor's findings exit code. The zizmor action's documented Advanced Security usage therefore reports without gating. security-scan.yml calls the action twice for that reason: once to report at every severity and upload SARIF, once with advanced-security: false to gate.
workflow_run.pull_requests is empty for fork pull requests — and for most same-repository ones. Measured over 30 runs before relying on it.
A job's permissions: is the reliable test for whether a checkout needs its credential, far more so than grepping for git push. A job with contents: read cannot push whatever it runs.
arduino/setup-task@v2 was a branch, not a tag. Worth checking before assuming a @vN reference is immutable.
Follow-up
The gate sits at medium. With nothing left for it to catch, it could drop to low or lower — worth doing once a release has passed through the changed release workflows unchanged, rather than stacking two untested changes on the same release.
actionlint is still not in CI, which is how #6265 went unnoticed.
zizmor runs in CI as a blocking check (#6251 added it advisory, #6274 made it gate at
medium). This issue tracked working through what it reported.111 findings at the start → 0.
zizmor defaults to offline mode — run it with
GH_TOKENset or the numbers won't match, since offline hides some rules and ratesartipackedhigher than it deserves.What landed
unpinned-uses×11,ref-version-mismatch×4artipacked×20 across 12 CI workflowstemplate-injection×16,artipacked×7,excessive-permissions×1@claudegated on write access rather than contribution historyreleaser.ymlpermissions scoped; tag expression boundcontents+pull-requestshelm-publish.ymlGHCR credentials and chart version boundmediumhelm-publish.ymlcleared entirelycreate-release-tag.yml,releaser.yml,create-release-pr.ymlEvery rule reached zero:
unpinned-uses,ref-version-mismatch,template-injection,artipacked,secrets-inherit,github-app,excessive-permissions,dangerous-triggers.The four that are suppressed rather than fixed (#6262)
Each carries its justification inline, so the reasoning sits with the code:
pr-size-label-apply.yml,release-notes.yml—dangerous-triggers. Theworkflow_runtrigger cannot be dropped in either case; the weakness that made the first dangerous was fixed in Derive PR number from the triggering run in the size labeler #6259, and the second checks out the default branch rather than an event-supplied ref.claude.yml—artipacked.contents: writeexists so Claude can push commits; the credential is in use. Do not "fix" this one.api-compat.yml—artipacked. Cannot push, runs agit fetch, and is the repository's only required status check.Things worth remembering
--format=sarifsuppresses zizmor's findings exit code. The zizmor action's documented Advanced Security usage therefore reports without gating.security-scan.ymlcalls the action twice for that reason: once to report at every severity and upload SARIF, once withadvanced-security: falseto gate.workflow_runconsumers always run the copy of the workflow on the default branch. A pull request can change a producer but not the consumer reading its output, which is why Derive PR number from the triggering run in the size labeler #6259 and Stop writing the PR number into the size label artifact #6261 had to be split.workflow_run.pull_requestsis empty for fork pull requests — and for most same-repository ones. Measured over 30 runs before relying on it.permissions:is the reliable test for whether a checkout needs its credential, far more so than grepping forgit push. A job withcontents: readcannot push whatever it runs.arduino/setup-task@v2was a branch, not a tag. Worth checking before assuming a@vNreference is immutable.Follow-up
The gate sits at
medium. With nothing left for it to catch, it could drop tolowor lower — worth doing once a release has passed through the changed release workflows unchanged, rather than stacking two untested changes on the same release.actionlintis still not in CI, which is how #6265 went unnoticed.