Security rules target the dangerous parts of workflow YAML
zizmor statically inspects GitHub Actions workflows and actions, Dependabot files, and experimental pre-commit configuration. Its audit list covers template injection, excessive permissions, persisted credentials, unpinned actions and images, impostor commits, ref confusion, secret inheritance, self-hosted runners, cache poisoning, and unsafe release patterns. It reads definitions without executing the workflow, which makes it suitable for pull requests containing untrusted changes.
The distinction from a general YAML linter matters. A workflow can be syntactically valid and still run attacker-controlled text in a privileged shell, leave checkout credentials on disk, or grant more token scope than a job needs. zizmor models GitHub concepts and points findings at the relevant span. Use actionlint beside it for expression and syntax checking; neither tool replaces the other.
Packaged installs avoid a 352-second source setup
Users can install zizmor through Homebrew, PyPI, crates.io, Docker, Conda, Nix, and several Linux package repositories. The docs warn ordinary users away from direct source installs and call release binaries best effort because libc compatibility can vary. PyPI wheels are also offered on a best-effort basis, so a pinned package-manager path is preferable to grabbing an arbitrary executable.
The source project is Rust, with Python packaging that exposes the command through common Python installers. Cargo users are told to pass --locked so dependency resolution matches upstream testing. A team standardizing the scanner should pin both the zizmor version and its delivery channel. That prevents a developer laptop, pre-commit hook, and CI runner from silently evaluating the same workflow with different rule sets.
What happened when we ran it
Our sandbox installed commit 11bbf7e in 352 seconds. That step added 34 packages and occupied 62 MB, while the build finished successfully in 5 seconds. Pip-audit reported 0 known vulnerabilities in the installed Python packages. The checkout itself was 3.9 MB, with 657 files and approximately 55,578 lines of source.
The lab did not run tests because its Python-oriented harness found no test script or target. The repository has Rust test code nested under its crates, but there was no top-level tests directory in our signal scan. This result is therefore install and build evidence, not a claim that the project's test suite passed. We also found 11 CI workflow files and a Dockerfile.
The 352-second install is the main local cost in our run, especially compared with the 5-second build. A precompiled package should remove much of that contributor-oriented work for ordinary use. We did not measure scan speed, finding accuracy, or false-positive rate, so teams should trial the tool against several known-safe workflows and a few intentionally vulnerable fixtures before making it a required check.
Offline mode skips audits that need GitHub facts
Local workflow files can be scanned with no token. Without GH_TOKEN, GITHUB_TOKEN, or ZIZMOR_GITHUB_TOKEN, the command defaults to offline mode. Remote repository inputs and online audits need API access. Private repositories also require read permission appropriate to the token type, while a GitHub Actions integration may need contents: read and other permissions for SARIF upload.
Online checks add useful facts, such as whether a commit belongs to an expected repository or whether an action reference is stale. They also add network and rate-limit dependencies. The --no-online-audits option can fetch remote inputs while skipping online rule work. Security teams should decide which findings must remain available during a GitHub outage and document that offline output is a reduced scan, not equivalent coverage.
SARIF needs policy because findings still exit zero
zizmor emits terminal text, versioned JSON, SARIF, and GitHub workflow annotations. SARIF fits GitHub code scanning, while annotations work without Advanced Security. The integration guide warns that GitHub displays only 10 annotations from one step, so longer result sets remain in logs. JSON is the better input when another system needs every finding and its severity, confidence, location, and suggested fixes.
SARIF mode intentionally returns exit code 0 when findings exist. Consumers expect results inside the SARIF file and reserve nonzero status for producer errors. A workflow can therefore show green after uploading serious alerts. Repositories that want blocking behavior need code-scanning rulesets, while command-line integrations can use zizmor's severity-based exit codes. That setup detail belongs in the acceptance test, not in a later incident review.
Automatic fixes are limited and still require review
The regular persona aims for high-signal findings. Pedantic and auditor modes widen the net for style concerns or security review. Teams can filter by severity and confidence, suppress one line with an inline comment, ignore paths in zizmor.yml, remap severity, or disable a rule. The docs caution that disabling a rule hides even the suppressed count, making narrow ignores easier to audit later.
Safe auto-fixes are available for a subset of findings, and unsafe fixes require an explicit mode. Fixes modify local files in place, do not apply to remote inputs, and may need GitHub access to choose a current commit. Review the diff even in safe mode because workflow permissions and pinned refs control deployment authority. An automatic edit can be mechanically sound while conflicting with an organization's release policy.
Active development still leaves edge-case gaps
GitHub recorded a push on August 26, 2026. Release v1.29.0 arrived on August 1, and the repository had 6,394 stars with 163 combined issues and pull requests when fetched. The release added experimental pre-commit scanning and an insecure URL rule, while changing ref and image pinning responsibilities. Frequent rule changes are a reason to pin versions and read release notes.
Issue 2324 reports that ref-version-mismatch and stale-action-refs skip job-level reusable-workflow calls. Issue 2321 describes a confusing diagnostic when a tag and branch share a name. Issue 286 tracks self-hosted runners that omit the usual label. These are bounded gaps, not reasons to dismiss the scanner. They are reasons to keep human workflow review and avoid treating one clean zizmor result as proof that CI is safe.

