Zizmor
Zizmor is a static analysis tool for GitHub Actions, designed to identify common security vulnerabilities in CI/CD setups. It detects issues such as template injection, accidental credential leakage, excessive permission scopes, and impostor commits. Currently at version 1.23.1, the project maintains an active development pace with frequent releases.
Warnings
- breaking Zizmor adopted Semantic Versioning starting with v1.0.0. While major versions guarantee breaking changes, pre-1.0.0 releases may have introduced them without strict adherence to semver.
- gotcha GitHub API rate limiting can be an issue when `zizmor` performs extensive 'online checks' (e.g., fetching tags and branches for actions) at scale on large projects. It can quickly hit the 15,000 calls per hour limit.
- gotcha Integrating `zizmor` with GitHub Advanced Security (recommended mode) requires your repository to be public or to have Advanced Security as a paid feature on private repositories. Otherwise, results are printed to the console rather than uploaded to Advanced Security.
- breaking In version 1.23.1, SARIF (Static Analysis Results Interchange Format) categories were regraded. Specifically, `zizmor`'s 'medium' severity now maps to SARIF's 'low' severity.
Install
-
pip install zizmor
Quickstart
import subprocess
import os
# Ensure zizmor is installed via 'pip install zizmor' and in your PATH.
# A GitHub token (GH_TOKEN) is often required for full functionality,
# especially for 'online audits' or resolving remote actions.
github_token = os.environ.get('GH_TOKEN', '')
try:
# Run zizmor audit on the current directory ('.')
# Replace '.' with your target GitHub Actions workflow directory if different.
command = [
"zizmor",
"audit",
"--target",
"."
]
if github_token:
command.extend(["--github-token", github_token])
print(f"Running command: {' '.join(command)}")
process = subprocess.run(
command,
capture_output=True,
text=True,
check=False # Set to True if you want an exception on non-zero exit codes
)
print("\n--- Zizmor Output ---")
print(process.stdout)
if process.stderr:
print("\n--- Zizmor Errors ---")
print(process.stderr)
if process.returncode != 0:
print(f"\nZizmor exited with non-zero status code: {process.returncode}")
else:
print("\nZizmor completed successfully.")
except FileNotFoundError:
print("Error: 'zizmor' command not found. Please ensure zizmor is installed and in your system's PATH.")
except Exception as e:
print(f"An unexpected error occurred: {e}")