Skip to content

ci: harden workflows per zizmor audit#4643

Merged
fzipi merged 1 commit into
coreruleset:mainfrom
fzipi:ci/zizmor-workflow-hardening
May 27, 2026
Merged

ci: harden workflows per zizmor audit#4643
fzipi merged 1 commit into
coreruleset:mainfrom
fzipi:ci/zizmor-workflow-hardening

Conversation

@fzipi

@fzipi fzipi commented May 25, 2026

Copy link
Copy Markdown
Member

what

  • add persist-credentials: false to every actions/checkout call so the default GITHUB_TOKEN is not persisted into .git/config (artipacked). duty-scheduler.yaml now pushes via an explicit https://x-access-token:${GH_TOKEN}@github.com/${REPOSITORY} URL instead of relying on persisted creds.
  • restructure quantitative.yaml to the safe two-workflow pattern. the test job now runs on pull_request (no secrets, read-only token, fork-safe) and writes pr_comment.md + a regex-validated pr_number.txt to an artifact. a new quantitative-comment.yaml triggers on workflow_run with pull-requests: write, downloads the artifact, and upserts the PR comment via gh api (marker <!-- quantitative-tests-comment -->). this eliminates the pull_request_target + PR-head checkout pwn-request antipattern (dangerous-triggers) and also drops the thollander/actions-comment-pull-request third-party dependency.
  • matrix values in the test step moved to env: to avoid ${{ ... }} interpolation inside run: bodies.
  • new .github/zizmor.yml ignores the remaining safe findings with justification:
    • check-pr-dependencies.yaml, check-pr-title.yamlpull_request_target is the standard pattern here; neither workflow checks out PR code, both consume only PR metadata via pinned actions with pull-requests: read.
    • quantitative-comment.yamlworkflow_run is the privileged half of the safe pattern; it consumes only artifact contents (markdown + numeric PR id) and never executes PR-supplied code.

why

zizmor flagged 8 findings on this repo's workflows: 3 high-severity dangerous-triggers (pull_request_target) and 5 artipacked warnings. the quantitative.yaml finding is genuinely exploitable — pull_request_target runs with the base repo's secrets and pull-requests: write, and the workflow then checks out ${{ github.event.pull_request.head.sha }} and operates on PR-controlled files. switching to the pull_request + workflow_run pattern keeps the same UX (a PR comment with the false-positive diff) while removing fork code from any privileged context.

after the changes, zizmor reports: No findings to report. Good job! (3 ignored, 35 suppressed).

refs

ai disclosure

  • tools used: Claude (Opus 4.7, 1M context) via Claude Code
  • assisted with: running zizmor on .github/workflows/, drafting the safe two-workflow split for quantitative.yaml, writing .github/zizmor.yml with per-rule justifications, replacing thollander/actions-comment-pull-request with a gh api-based marker upsert, looking up the actions/[email protected] SHA via the GitHub API for pinning, drafting this PR description.
  • review performed: re-ran zizmor .github/workflows/ after each change and confirmed final state is clean (3 ignored, 35 suppressed); ran actionlint on all workflow files (no new findings introduced by these changes); confirmed all actions/download-artifact and actions/checkout SHAs match the documented tags; manually traced the pull_requestworkflow_run data flow to confirm no PR-controlled code executes in the privileged half and that the pr_number.txt artifact is regex-validated (^[0-9]+$) before use in gh api paths.

resolves zizmor findings on .github/workflows/:

- add `persist-credentials: false` to all `actions/checkout` calls; the
  duty-scheduler push now uses an explicit token URL instead of relying
  on persisted creds (artipacked)
- restructure quantitative tests to the safe two-workflow pattern: the
  test job moves to `pull_request` (no secrets, read-only token) and a
  new `quantitative-comment.yaml` posts the result on `workflow_run`
  with `pull-requests: write`. comment posting uses `gh api` with a
  marker-based upsert, removing the `thollander/actions-comment-pull-request`
  third-party dependency. eliminates the `pull_request_target` + PR-head
  checkout pwn-request antipattern (dangerous-triggers)
- add `.github/zizmor.yml` with justified ignores for the remaining
  safe `pull_request_target` workflows (check-pr-dependencies,
  check-pr-title — metadata-only, no checkout) and the new
  `workflow_run`-triggered comment workflow (artifact-only, no PR code
  execution)

zizmor result: no findings reported (3 ignored, 35 suppressed)
@github-actions

Copy link
Copy Markdown
Contributor

📊 Quantitative test results for language: eng, year: 2023, size: 10K, paranoia level: 1:
🚀 Quantitative testing did not detect new false positives

@fzipi
fzipi requested a review from theseion May 25, 2026 10:18
@fzipi fzipi added the release:ignore Ignore for changelog release label May 25, 2026
@fzipi
fzipi requested a review from a team May 25, 2026 10:18
Comment thread .github/workflows/quantitative-comment.yaml
Comment thread .github/workflows/test.yml
Comment thread .github/workflows/quantitative.yaml
Comment thread .github/workflows/quantitative.yaml
@fzipi
fzipi added this pull request to the merge queue May 27, 2026
Merged via the queue into coreruleset:main with commit 5a805f3 May 27, 2026
10 checks passed
@fzipi
fzipi deleted the ci/zizmor-workflow-hardening branch May 27, 2026 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:ignore Ignore for changelog release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants