Summary
Our GitHub Actions workflows have no static analysis in CI. security-scan.yml runs Grype and govulncheck — both look at our dependencies and our Go code, neither looks at the workflows themselves, so anti-patterns accumulate with no signal.
Separately, every security scan was running twice per pull request: security-scan.yml has its own pull_request trigger and was called as a reusable workflow from run-on-pr.yml. The same overlap existed on main between its push: trigger and the call from run-on-main.yml.
Scope
This issue now covers exactly the two changes in #6251:
| Change |
Detail |
| Adopt zizmor |
New job in security-scan.yml, reusing its existing security-events: write and the already-pinned upload-sarif. Advisory to start with — --no-exit-codes stops findings failing the job and continue-on-error stops a tool or network failure doing so. |
| Run each scan once |
Drop the security-scan call from run-on-pr.yml and the push: trigger from security-scan.yml, keeping the direct pull_request trigger for PRs and the run-on-main.yml call for main, which image-build-and-push gates on. |
Findings are written straight to SARIF and never printed — workflow logs and job summaries are world-readable on a public repo, so echoing them would publish them. The SARIF upload keeps them in the Security tab. The upload is skipped for fork PRs, whose token is read-only.
Follow-up
zizmor reports a backlog against the current tree, inventoried with per-file tables in #6253. That issue carries the cleanup work — pinning, expression binding, checkout credentials — and the final step of dropping --no-exit-codes and continue-on-error and adding --min-severity so the gate actually blocks.
Adopting the linter is deliberately separated from clearing what it finds, so neither blocks the other.
Summary
Our GitHub Actions workflows have no static analysis in CI.
security-scan.ymlruns Grype and govulncheck — both look at our dependencies and our Go code, neither looks at the workflows themselves, so anti-patterns accumulate with no signal.Separately, every security scan was running twice per pull request:
security-scan.ymlhas its ownpull_requesttrigger and was called as a reusable workflow fromrun-on-pr.yml. The same overlap existed on main between itspush:trigger and the call fromrun-on-main.yml.Scope
This issue now covers exactly the two changes in #6251:
security-scan.yml, reusing its existingsecurity-events: writeand the already-pinnedupload-sarif. Advisory to start with —--no-exit-codesstops findings failing the job andcontinue-on-errorstops a tool or network failure doing so.security-scancall fromrun-on-pr.ymland thepush:trigger fromsecurity-scan.yml, keeping the directpull_requesttrigger for PRs and therun-on-main.ymlcall for main, whichimage-build-and-pushgates on.Findings are written straight to SARIF and never printed — workflow logs and job summaries are world-readable on a public repo, so echoing them would publish them. The SARIF upload keeps them in the Security tab. The upload is skipped for fork PRs, whose token is read-only.
Follow-up
zizmor reports a backlog against the current tree, inventoried with per-file tables in #6253. That issue carries the cleanup work — pinning, expression binding, checkout credentials — and the final step of dropping
--no-exit-codesandcontinue-on-errorand adding--min-severityso the gate actually blocks.Adopting the linter is deliberately separated from clearing what it finds, so neither blocks the other.