Skip to content

zizmor findings backlog: pins, expressions and checkout credentials #6253

Description

@ChrisJBurns

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.

What landed

PR What
#6251 Adopt zizmor (advisory); stop running each security scan twice per PR
#6254 unpinned-uses ×11, ref-version-mismatch ×4
#6255 artipacked ×20 across 12 CI workflows
#6258 template-injection ×16, artipacked ×7, excessive-permissions ×1
#6259 Size labeler no longer takes its target from an artifact a pull request controls
#6260 @claude gated on write access rather than contribution history
#6261 Removed the now-unread PR number from the size artifact
#6262 Four findings suppressed, each with its reasoning in the workflow
#6263 releaser.yml permissions scoped; tag expression bound
#6266 Release app token scoped to contents + pull-requests
#6269 Test workflows receive one named secret instead of every repository secret
#6270 helm-publish.yml GHCR credentials and chart version bound
#6272 The last two app tokens scoped; commit trailer bound
#6274 The check now blocks, at medium
#6275 helm-publish.yml cleared entirely
#6281 The last 13 — create-release-tag.yml, releaser.yml, create-release-pr.yml

Every 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.ymldangerous-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.ymlartipacked. contents: write exists so Claude can push commits; the credential is in use. Do not "fix" this one.
  • api-compat.ymlartipacked. 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 consumers 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_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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions