You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The # zizmor: ignore[github-env] annotation that PR #37586 added to the generator in pkg/workflow/ghes_host_step.go does not actually suppress the github-env finding. Per zizmor's own documentation, an ignore comment must be placed inside the span identified by the finding (i.e. on the run: line itself or inside the script body), not on a sibling YAML line above it. The generator emits the comment one line above run:, which zizmor treats as detached.
Live evidence: the daily static-analysis-report issue at HEAD still surfaces the same github-env High on dev-hawk.lock.yml, persisting roughly 19 days after #37586 merged on 2026-06-07. The persistence is repeatedly framed as "confirm value is not attacker-controlled," but the actual root cause is that the suppression never took effect.
This pattern (PR #37586: "adds a scoped zizmor: ignore[github-env] annotation as a standalone comment line immediately above run:, matching the # zizmor: ignore[...] - <reason> pattern used elsewhere in the codebase") implies the same placement may be used by other generators too. Every compiled .lock.yml that embeds the GHES host step is currently emitting an un-suppressed github-env High.
Where the bug lives
pkg/workflow/ghes_host_step.go, the string emitted by generateGHESHostConfigurationStep():
- name: Configure GH_HOST for enterprise compatibilityid: ghes-host-configshell: bash# zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.run: | GH_HOST="${GITHUB_SERVER_URL#https://}" GH_HOST="${GH_HOST#http://}" echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
The # zizmor: ignore[github-env] line sits as a top-level YAML comment on the step object, adjacent to but outside the run: value. zizmor parses the finding span as the multi-line block scalar belonging to run:; the comment is not within that span and therefore does not match.
What zizmor's docs say
From docs/usage.md of zizmorcore/zizmor (the "With comments" section):
An ignore comment can be placed anywhere in any span identified by a finding, so long as it can be identified as a YAML comment. In particular, this means that you can''t place an ignore comment in the middle of a string or a block literal.
The documented working pattern places the comment on the same line as the YAML key that owns the finding, e.g.:
The same template-string convention is referenced as "matching the pattern used elsewhere in the codebase" in #37586''s description, suggesting other generators may have the same defect.
Minimal repro
Compile any agentic workflow that includes the GHES host step, then run zizmor against the compiled .lock.yml:
gh aw compile <workflow-name>
docker run --rm -v "$(pwd):/workdir:ro" -w /workdir \
ghcr.io/zizmorcore/zizmor:1.25.2 \
--min-severity high --color=never \
.github/workflows/<workflow-name>.lock.yml
Expected (with #37586''s fix working): no github-env finding.
Actual: github-env High is reported on the echo "GH_HOST=..." >> "$GITHUB_ENV" line, despite the immediately preceding # zizmor: ignore[github-env] comment.
The same High shows up in this project''s own daily report -- see issue #38795 ("Top Priority #2: dangerous $GITHUB_ENV use ... @ dev-hawk.lock.yml:1718").
Proposed fix
Move the suppression onto the run: | line itself in pkg/workflow/ghes_host_step.go:
return` - name: Configure GH_HOST for enterprise compatibility id: ghes-host-config shell: bash run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input. GH_HOST="${GITHUB_SERVER_URL#https://}" GH_HOST="${GH_HOST#http://}" echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"`
That places the comment inside the span zizmor considers part of the finding.
Suggested follow-ups
Strengthen the test. The corresponding test in pkg/workflow/ghes_host_step_test.go should actually invoke zizmor against the generated YAML (or at minimum assert that the comment appears on the run: line, not on its own line), so a future regression of this exact pattern is caught before merge.
Sweep other generators. Grep pkg/workflow/ for occurrences of # zizmor: ignore[ to find other generators following the same pattern:
grep -rn ''# zizmor: ignore\['' pkg/workflow/
Any hit whose template emits the comment on a YAML line that is a sibling of run: (or uses:) rather than on the run:/uses: line itself has the same bug.
Add an integration test in static-analysis-report. When the daily run sees a finding whose source file is generator-emitted and whose immediately preceding line contains a # zizmor: ignore[<same-audit>] comment, file a higher-priority alert -- this is exactly the misplaced-suppression pattern.
Every gh-aw-managed repo that compiles workflows including the GHES host step ships a .lock.yml with an un-suppressed github-env High finding. Downstream consumers running zizmor as a pre-merge gate (e.g. with --min-severity high) will see this finding indefinitely until the placement is corrected upstream.
Summary
The
# zizmor: ignore[github-env]annotation that PR #37586 added to the generator inpkg/workflow/ghes_host_step.godoes not actually suppress thegithub-envfinding. Per zizmor's own documentation, an ignore comment must be placed inside the span identified by the finding (i.e. on therun:line itself or inside the script body), not on a sibling YAML line above it. The generator emits the comment one line aboverun:, which zizmor treats as detached.Live evidence: the daily
static-analysis-reportissue at HEAD still surfaces the samegithub-envHigh ondev-hawk.lock.yml, persisting roughly 19 days after #37586 merged on 2026-06-07. The persistence is repeatedly framed as "confirm value is not attacker-controlled," but the actual root cause is that the suppression never took effect.This pattern (PR #37586: "adds a scoped
zizmor: ignore[github-env]annotation as a standalone comment line immediately aboverun:, matching the# zizmor: ignore[...] - <reason>pattern used elsewhere in the codebase") implies the same placement may be used by other generators too. Every compiled.lock.ymlthat embeds the GHES host step is currently emitting an un-suppressedgithub-envHigh.Where the bug lives
pkg/workflow/ghes_host_step.go, the string emitted bygenerateGHESHostConfigurationStep():The
# zizmor: ignore[github-env]line sits as a top-level YAML comment on the step object, adjacent to but outside therun:value. zizmor parses the finding span as the multi-line block scalar belonging torun:; the comment is not within that span and therefore does not match.What zizmor's docs say
From
docs/usage.mdofzizmorcore/zizmor(the "With comments" section):The documented working pattern places the comment on the same line as the YAML key that owns the finding, e.g.:
The current
ghes_host_step.gooutput does not follow that pattern -- the comment is on the prior YAML key, not on therun:line.Root cause
# zizmor: ignore[<audit>] - <reason>is the correct syntax.run:line itself (or inside the script body as a shell#comment).github-envhighs by tightening env-file usage in generated workflow steps #37586) added a test that asserts the string is present in the generated YAML; the test does not actually run zizmor against the output to verify suppression. So the bug shipped green.The same template-string convention is referenced as "matching the pattern used elsewhere in the codebase" in #37586''s description, suggesting other generators may have the same defect.
Minimal repro
Compile any agentic workflow that includes the GHES host step, then run zizmor against the compiled
.lock.yml:Expected (with #37586''s fix working): no
github-envfinding.Actual:
github-envHigh is reported on theecho "GH_HOST=..." >> "$GITHUB_ENV"line, despite the immediately preceding# zizmor: ignore[github-env]comment.The same High shows up in this project''s own daily report -- see issue #38795 ("Top Priority #2: dangerous
$GITHUB_ENVuse ... @dev-hawk.lock.yml:1718").Proposed fix
Move the suppression onto the
run: |line itself inpkg/workflow/ghes_host_step.go:That places the comment inside the span zizmor considers part of the finding.
Suggested follow-ups
Strengthen the test. The corresponding test in
pkg/workflow/ghes_host_step_test.goshould actually invoke zizmor against the generated YAML (or at minimum assert that the comment appears on therun:line, not on its own line), so a future regression of this exact pattern is caught before merge.Sweep other generators. Grep
pkg/workflow/for occurrences of# zizmor: ignore[to find other generators following the same pattern:Any hit whose template emits the comment on a YAML line that is a sibling of
run:(oruses:) rather than on therun:/uses:line itself has the same bug.Add an integration test in
static-analysis-report. When the daily run sees a finding whose source file is generator-emitted and whose immediately preceding line contains a# zizmor: ignore[<same-audit>]comment, file a higher-priority alert -- this is exactly the misplaced-suppression pattern.References
github-envhighs by tightening env-file usage in generated workflow steps #37586 (introduced the bug): "Resolve dev-hawkgithub-envhighs by tightening env-file usage in generated workflow steps"github-envHigh persists in the daily reportdocs/usage.md"With comments" sectionEnvironment
Why this matters
Every gh-aw-managed repo that compiles workflows including the GHES host step ships a
.lock.ymlwith an un-suppressedgithub-envHigh finding. Downstream consumers running zizmor as a pre-merge gate (e.g. with--min-severity high) will see this finding indefinitely until the placement is corrected upstream.