Make the zizmor check blocking - #6274
Merged
Merged
Conversation
main is clear of medium-and-above findings, so the advisory mode can come off: --no-exit-codes and the job's continue-on-error are gone and the check fails on anything at medium or higher. The reporting run is kept separate from the gate. It still emits SARIF at every severity so the Security tab keeps the low and informational findings the gate does not block on, and still writes them to file rather than the log. The gate prints, because anything it reports was introduced by the change under review and is already visible in its diff, and a gate that fails without saying why is not worth having. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6274 +/- ##
==========================================
- Coverage 72.73% 72.71% -0.03%
==========================================
Files 742 742
Lines 77299 77325 +26
==========================================
+ Hits 56224 56227 +3
- Misses 17113 17135 +22
- Partials 3962 3963 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
10 tasks
pipx resolved zizmor from PyPI at run time. The version was pinned but the artifact behind it was not, which is worth tightening for a check that is about to start blocking merges. Both steps now run the official container pinned by digest. A tag can be repointed; a digest cannot. The digest is the one zizmorcore/zizmor-action resolves 1.29.0 to, confirmed against the registry and by running the image, so it is the artifact upstream publishes and vets. The action itself was considered and not used: it tees its output, which would put the full finding inventory into a world-readable log, and its SARIF upload is skipped when the run fails, so findings would not reach the Security tab on exactly the pull requests that have them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The hand-rolled container invocation was replaced by two calls to zizmorcore/zizmor-action, which pins the zizmor image by digest itself, so the pinning that motivated the container approach is kept without the bespoke shell. Reporting and gating stay separate because the action cannot do both in one call: zizmor suppresses its findings exit code when the format is SARIF, which is what advanced-security selects. So the first call reports at every severity and uploads, and cannot fail; the second sets advanced-security false to restore human-readable output and the exit code, and gates at medium. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
/retest |
rdimitrov
approved these changes
Aug 10, 2026
This was referenced Aug 10, 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.
The last item in #6253.
mainis clear of medium-and-above findings, so the advisory mode can come off.Summary
mainhas zero findings at medium or above — down from 111 findings overall, of which 33 were high or medium.--no-exit-codesand the job'scontinue-on-errorwere there to keep the job green while that backlog was worked through. Both are gone, and the check now fails on anything at medium or higher.zizmorcore/zizmor-action, replacing a hand-rolledpipx run. The action resolves zizmor to a digest-pinned container image, so the artifact is pinned rather than just the version number — worth having for a check that is about to start blocking merges.medium, nothigh. The plan saidhigh, but medium is also at zero, so the stricter threshold is free. The three medium rules —secrets-inherit,ref-version-mismatchandexcessive-permissions— are all worth blocking on. Dropping tohighis a one-word change if it proves too tight.Why two calls to the action rather than one
They cannot be combined, for a reason that is not obvious:
zizmor suppresses its findings exit code when the output format is SARIF — and SARIF is what
advanced-security: trueselects. Measured against a checkout ofmainwith one medium finding injected, repeated three times each:--format=sarif --min-severity=medium--format=plain --min-severity=medium--format=github --min-severity=mediumSo the action's documented Advanced Security usage reports without gating. That is a sensible default for a scanner, but it means a single call cannot both upload SARIF and fail the build.
Hence:
advanced-securitytrue(default)falseThe first call reporting at every severity is deliberate: it keeps the low and informational findings visible in the Security tab even though the gate ignores them. The second sets
advanced-security: falseboth to restore the exit code and to avoid uploading a second, severity-filtered SARIF over the first.What is deliberately not blocked
24 findings remain, all low or informational, all in the four release workflows:
artipacked×7 — checkouts in release jobs, in workflows no pull request can exercise.template-injection×17 —github.repositoryand a semver-validated version, neither of which can carry a shell metacharacter.Lowering the threshold further means dealing with those first — #6275 makes a start. The trade is recorded in the job's comments, not just here.
Closes #6253
Type of change
Test plan
Unit tests (
task test)E2E tests (
task test-e2e)Linting (
task lint-fix)Manual testing (describe below)
Established the SARIF exit-code behaviour by measurement, not from documentation — three repeats of each format against a real checkout, as tabled above. It is the reason this is two steps, so it seemed worth being sure of.
Verified the gate actually bites. Injected a real regression — a pin with a mismatched version comment, a medium
ref-version-mismatch— and confirmed zizmor reports it with file, line, the offending text and a fix hint, and exits 13. Reverted afterwards. A gate that has never been seen to fail is not a gate.Confirmed the reporting run produces valid SARIF containing all 24 findings, so nothing disappears from the Security tab.
Confirmed the action pin
3dc1ecc9…is the commitv0.6.2points to.Confirmed the job no longer carries
continue-on-error, and that the steps are ordered checkout → report → gate.Workflow parses as YAML;
actionlintclean.This pull request exercises the change on itself —
security-scan.ymlruns on every pull request, so the gate is running here.Does this introduce a user-facing change?
Yes, for contributors: a pull request that introduces a medium-or-higher workflow finding will now fail CI rather than reporting quietly. That is the intent.
Special notes for reviewers
mediumcosts nothing today;highis more forgiving of future churn. I would rather start strict and relax if it annoys, but it is a team call.version:is only safe to a version that map knows; the action fails loudly on an unknown one.# zizmor: ignore[rule]comment carrying the reasoning — seeclaude.ymlandapi-compat.ymlfor existing examples.Generated with Claude Code