Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion .github/workflows/gate-failure-watch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,31 @@ name: Scheduled Gate Failure Watch
# update the same issue with the current rows and their delta; the next green
# closes it.

on:
# zizmor flags `workflow_run` categorically -- "almost always used
# insecurely", at Medium audit confidence. The two ways it IS used insecurely
# are both closed here, in code, and each is checkable in one line:
#
# 1. It never runs for untrusted input. The `observe` job's `if:` admits only
# `schedule`, or `workflow_dispatch`/`repository_dispatch`/`push` whose
# head_branch is `main` or a `v*` tag. A fork PR's run satisfies none of
# those, so the write-capable token is never reachable from a
# contributor-controlled trigger.
# 2. It never executes the triggering run's code. The checkout pins
# `ref: main` with `persist-credentials: false`, and the only thing run is
# `scripts/gate_failure_watch.py` out of that trusted default-branch
# checkout. Nothing is taken from the triggering run -- no artifact
# download, no `head_sha` checkout.
#
# Permissions are `actions: read`, `contents: read`, `issues: write`: enough to
# read a run's conclusion and file one issue, nothing more.
#
# Dropping the trigger is not an alternative -- observing another workflow's
# completion IS the feature (#9830 measured a correctly-failing scheduled
# workflow staying red for nineteen days with nobody noticing).
#
# Ratchet: if this workflow ever gains an artifact download, a `head_sha`
# checkout, or a looser `if:`, delete the marker and let the gate fail.
on: # zizmor: ignore[dangerous-triggers]
workflow_run:
workflows:
- Auto-Optimize App Patterns
Expand Down
20 changes: 20 additions & 0 deletions changelog.d/10386-zizmor-workflow-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Unbreak the `zizmor` gate, red on `main` since 2026-09-06 on one high finding:
`dangerous-triggers` against `gate-failure-watch.yml`'s `workflow_run`.

zizmor flags that trigger categorically ("almost always used insecurely", at
Medium audit confidence). Both insecure uses are already closed in the file: the
`observe` job's `if:` admits only schedule, or dispatch/push on `main` or a `v*`
tag, so a fork PR's run can never reach the write-capable token; and the
checkout pins `ref: main` with `persist-credentials: false` and executes only
the default-branch `scripts/gate_failure_watch.py`, so the triggering run's code
is never run and none of its artifacts are downloaded.

Suppressed inline rather than in `.github/zizmor.yml`, so the justification sits
beside the trigger it excuses and carries its own ratchet: an artifact download,
a `head_sha` checkout, or a looser `if:` means deleting the marker and letting
the gate fail again.

Verified against the pinned zizmor 1.28.0 with the workflow's own invocation —
`zizmor .github/ --min-severity high` goes from exit 14 with one high finding to
exit 0. The marker must trail the `on:` key; the identical text as a comment
block above it suppresses nothing.
Loading