Configuration🔗
Note
Configuration support was added in v0.2.0
.
zizmor
supports a small amount of configuration via YAML config files,
typically named zizmor.yml
.
Discovery🔗
Note
Configuration is always optional, and can always be skipped with
--no-config
. If --no-config
is passed, no configuration is ever loaded.
Tip
zizmor
's configuration discovery behavior changed significantly
in v1.13.0
. See the release notes for details.
zizmor
discovers configuration files in two conceptually distinct ways:
-
Global discovery: when explicitly given a configuration file via
--config
orZIZMOR_CONFIG
, that file is used for all inputs.In other words: when a global configuration file is used no other configuration files are discovered or loaded, even if they're present according to the local discovery rules below.
-
Local discovery: when no global configuration file is given,
zizmor
looks for configuration files for each given input. The rules for this discovery are as follows:-
File inputs (e.g.
zizmor path/to/workflow.yml
):zizmor
performs directory discovery starting in the directory containing the given file. -
Directory inputs (e.g.
zizmor .
):zizmor
looks for azizmor.yml
or.github/zizmor.yml
in the given directory or any parent, up to the filesystem root or the first.git
directory.Note
zizmor .github/workflows/
is a special case: in this case, discovery starts in.github/
, the parent of the given directory.This is done to avoid confusion between a
zizmor.yml
config file and azizmor.yml
workflow file. -
Remote repository inputs (e.g.
zizmor owner/repo
):zizmor
looks for azizmor.yml
or.github/zizmor.yml
in the root of the repository.
-
In general, most users will want to use local discovery, which is the
default behavior. Global discovery only takes precedence when explicitly
requested with --config
or ZIZMOR_CONFIG
.
Settings🔗
rules.<id>.disable
🔗
Type: boolean
Disables the audit entirely if true
.
Important
rules.<id>.disable
was added in v1.13.0
.
Warning
For most users, disabling audits should be a measure of last resort. Disabled rules don't show up in ignored or suppressed finding counts, making it very easy to accidentally miss important new findings.
Before disabling an audit entirely, consider one of the following alternatives:
- Ignoring specific findings via
rules.<id>.ignore
. - Changing your persona to a less sensitive
one. For example, consider removing
--persona=pedantic
or--persona=auditor
if you're using one of those.
When set, inputs covered by this configuration file will not be analyzed by the given audit.
For example, here is a configuration file that disables the
template-injection
audit:
Multiple audits can be disabled as well:
rules.<id>.ignore
🔗
Type: array
Per-audit ignore rules.
Each member of rules.<id>.ignore
is a workflow rule, formatted as follows:
where filename.yml
is the base filename of the workflow, and line
and
column
are both optional 1-based values indicating the exact line-and-column
location to ignore. If one or both are absent, then the rule applies to the
entire file or entire line.
Important
Composite action findings cannot be ignored via zizmor.yml
currently,
They can be ignored inline with comments.
For example, here is a configuration file with two different audit ignore rule groups:
rules:
template-injection:
ignore:
# ignore line 100 in ci.yml, any column
- ci.yml:100
# ignore all lines and columns in tests.yml
- tests.yml
use-trusted-publishing:
ignore:
# ignore line 12, column 10 on pypi.yml
- pypi.yml:12:10
rules.<id>.config
🔗
Type: object
Per-audit configuration, where id
is the audit's name, e.g.
unpinned-uses
.
Not all audits are configurable. See each audit's documentation for details.
Patterns🔗
Several audits support being configured with patterns, which can be used
to match things like uses:
clauses. These patterns share
common syntaxes, and are described here.
Repository patterns🔗
Repository patterns are used to match uses:
clauses.
The following patterns are supported, in order of specificity:
-
owner/repo/subpath@ref
: matches the exact repository, including subpath (if given) and ref. The subpath is optional.Example
github/codeql-action/init@v2
matchesuses: github/codeql-action/init@v2
, but notuses: github/codeql-action/init@main
. -
owner/repo/subpath
: match alluses:
clauses that are exact matches for theowner/repo/subpath
pattern. Thesubpath
can be an arbitrarily deep subpath, but is not optional. Any ref is matched.Example
github/codeql-action/init
matchesuses: github/codeql-action/init@v2
, but notuses: github/codeql-action@v2
. -
owner/repo
: match alluses:
clauses that are exact matches for theowner/repo
pattern. Any ref is matched.Example
actions/cache
matchesuses: actions/cache@v3
, but notuses: actions/cache/save@v3
oruses: actions/cache/restore@v3
. -
owner/repo/*
: match alluses:
clauses that come from the givenowner/repo
. Any subpath or ref is matched.Example
github/codeql-action/*
matchesuses: github/codeql-action/init@v2
,uses: github/codeql-action/upload-sarif@v2
, anduses: github/codeql-action@v2
itself. -
owner/*
: match alluses:
clauses that have the givenowner
. Any repo, subpath, or ref is matched.Example
actions/*
matches bothuses: actions/checkout@v4
anduses: actions/setup-node@v4
, but notuses: pypa/gh-action-pypi-publish@release/v1
. -
*
: match alluses:
clauses.Example
*
matchesuses: actions/checkout
anduses: pypa/gh-action-pypi-publish@release/v1
.