Skip to content

zizmor

Related: GitHub

zizmor is a static analysis tool for GitHub Actions workflows. It finds common security problems such as template injection, unpinned actions, overly broad permissions, dangerous triggers like pull_request_target, and credentials persisted by actions/checkout. These are the same issues covered in the GitHub guideline.

zizmor runs locally in a few seconds, so you get feedback before you push. Install it with Homebrew, or run it with uvx without installing anything:

Terminal window
brew install zizmor
zizmor .github/workflows
# or, without installing
uvx zizmor .github/workflows

When scanning a single file, give it a path. A bare filename is treated as something else:

Terminal window
zizmor workflow.yml # doesn't work
zizmor ./workflow.yml # works

Many findings can be fixed automatically with zizmor --fix .github/workflows. Review the changes before committing.

Add zizmor-action as a workflow so every change to the workflows is checked. On private repositories we don’t have GitHub Advanced Security, so set advanced-security: false. Findings are then shown as annotations on the pull request and fail the job:

.github/workflows/zizmor.yml
name: zizmor
on:
push:
branches: ["main"]
pull_request:
branches: ["**"]
permissions: {}
jobs:
zizmor:
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4
with:
advanced-security: false

Add the zizmor job as a required status check in the branch ruleset so findings block the merge.

On public repositories, you can leave out advanced-security: false and add security-events: write to the job permissions instead. Findings then show up in the Security tab alongside CodeQL alerts. In that mode the job doesn’t fail on findings, so use a code scanning rule in the branch ruleset to block merges.