zizmor: Audit GitHub Actions for Security Issues
zizmor statically audits GitHub Actions workflows and reusable actions for security problems like template injection, unpinned actions, and dangerous pull_request_target usage.
actionlint checks that a workflow is valid; zizmor checks that it is safe. It catches classes of supply-chain and injection bugs that a schema linter cannot see.
What it does
zizmor runs a set of audits over workflow YAML and composite actions, reporting findings by severity and confidence. It detects ${{ }} template injection into run: blocks, actions pinned by tag instead of SHA, pull_request_target with checkout of untrusted code, and excessive permissions.
Common usage
zizmor .github/workflows/ci.yml # audit one workflow
zizmor .github/workflows/ # audit a directory
zizmor --format sarif . > zizmor.sarif
zizmor --min-severity high . # only high-severity findingsOptions
| Flag | What it does |
|---|---|
| --format <fmt> | Output format: plain, json, or sarif |
| --min-severity <level> | Filter findings below this severity (low/medium/high) |
| --min-confidence <level> | Filter findings below this confidence |
| --persona <persona> | auditor, pedantic, or regular sensitivity |
| --offline | Skip audits that need network (e.g. online SHA checks) |
| --gh-token <token> | GitHub token for online audits |
In CI
Run zizmor in a PR check with --format sarif and upload the SARIF to GitHub code scanning so findings show inline. Combine with pinning tools (pinact, ratchet) so the "unpinned action" findings get fixed automatically.
Common errors in CI
Findings read like template-injection and unpinned-uses: action is not pinned to a hash with a severity and a code frame. error: failed to load ...: invalid workflow means the YAML is malformed (run actionlint first). Online audits that hit the API rate limit report github api error and are fixed with --gh-token or --offline.