Skip to content

ci: address zizmor findings across workflows#11608

Merged
zkochan merged 1 commit into
mainfrom
zizmor-fixes
May 12, 2026
Merged

ci: address zizmor findings across workflows#11608
zkochan merged 1 commit into
mainfrom
zizmor-fixes

Conversation

@zkochan

@zkochan zkochan commented May 12, 2026

Copy link
Copy Markdown
Member

Summary

Resolves all 30 zizmor alerts reported on main after #11607 wired up the scanner.

Rule Count Action
template-injection (error) 19 Move ${{ … }} to env: and reference shell vars
artipacked (note) 8 Add persist-credentials: false to actions/checkout (1 inline-ignored)
dependabot-cooldown (warning) 1 Add 7-day cooldown in dependabot.yml
ref-version-mismatch (warning) 1 Fix comment: the SHA points at v2, not v2.0.0
superfluous-actions (note) 1 Inline-ignored with justification — see below

Notable decisions

  • update-lockfile.yml keeps the persisted checkout token because the later git push -f origin chore/update-lockfile step depends on it. The line has # zizmor: ignore[artipacked] plus a comment explaining why.
  • release.yml keeps softprops/action-gh-release. zizmor's suggestion (use gh release create) is valid in principle, but the release pipeline is sensitive and the action is battle-tested. Inline-ignored with justification.
  • test.yml:76 (running pn run ${{ steps.test-scope.outputs.script }}) was technically a false positive — the upstream step hardcodes the output to one of two literals — but moved to env: anyway for consistency and to keep the rule on by default.

Verification

Ran zizmor locally against the modified workflows (with online audits enabled):

$ GH_TOKEN=… zizmor --persona regular .github
…
No findings to report. Good job! (2 ignored, 32 suppressed)

The 2 "ignored" are the inline-justified release.yml and update-lockfile.yml cases above. After merge, the zizmor workflow itself will re-run on main and the Code scanning dashboard should drop to 0 open alerts.

Test plan


Written by an agent (Claude Code, claude-opus-4-7).

Summary by CodeRabbit

  • Chores
    • Enhanced GitHub Actions workflow security by disabling credential persistence across multiple workflows (audit, CI, CodeQL, Docker, release, and test pipelines).
    • Refactored workflows to use environment variables for improved configuration management and maintainability.
    • Updated Dependabot configuration to set a 7-day cooldown window for GitHub Actions updates.

Review Change Stack

Resolves all 30 zizmor alerts reported on main after #11607:

- template-injection (19): move `${{ ... }}` interpolations in `run:` blocks
  to `env:` so untrusted-ish values (workflow_dispatch inputs, github.ref_name,
  github.actor) can't break out of shell quoting.
- artipacked (8): add `persist-credentials: false` to `actions/checkout` in
  audit, benchmark, ci, codeql-analysis, docker, release, test workflows.
  `update-lockfile.yml` keeps the persisted token (later step pushes to a
  branch) with a `zizmor: ignore[artipacked]` comment and justification.
- dependabot-cooldown (1): add a 7-day cooldown so brand-new (potentially
  malicious) Actions releases don't get auto-PR'd day-of-release.
- ref-version-mismatch (1): `bluwy/release-for-reddit-action` SHA pointed at
  the `v2` tag, not a non-existent `v2.0.0`. Fix the comment.
- superfluous-actions (1): mark `softprops/action-gh-release` with a
  `zizmor: ignore` and justification — the release pipeline is sensitive and
  the action is battle-tested; we're not swapping it for `gh release` here.

Verified locally with `zizmor --persona regular .github` (online audits on):
  No findings to report. Good job! (2 ignored, 32 suppressed)

---
Written by an agent (Claude Code, claude-opus-4-7).
Copilot AI review requested due to automatic review settings May 12, 2026 19:56
@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d163900d-b411-469a-b4c4-3a047366b503

📥 Commits

Reviewing files that changed from the base of the PR and between 6335860 and 66a6708.

📒 Files selected for processing (10)
  • .github/dependabot.yml
  • .github/workflows/audit.yml
  • .github/workflows/benchmark.yml
  • .github/workflows/ci.yml
  • .github/workflows/codeql-analysis.yml
  • .github/workflows/docker.yml
  • .github/workflows/release.yml
  • .github/workflows/test.yml
  • .github/workflows/update-latest.yml
  • .github/workflows/update-lockfile.yml
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Agent
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Compile & Lint
🔇 Additional comments (14)
.github/workflows/update-lockfile.yml (1)

18-21: Clear and justified exception for persisted checkout credentials.

The inline zizmor ignore and added rationale are appropriate here, and they directly document why credential persistence is required for the later forced push step.

.github/dependabot.yml (1)

14-15: Nice addition—this cooldown setting is clean and consistent with the PR goal.

No concerns on this change.

.github/workflows/codeql-analysis.yml (1)

46-47: Good hardening on checkout credentials.

Disabling credential persistence here is the right security posture for this job.

.github/workflows/audit.yml (1)

16-17: Checkout token persistence is correctly disabled.

Nice security improvement with no functional downside in this workflow.

.github/workflows/ci.yml (1)

21-22: CI checkout hardening looks good.

persist-credentials: false is correctly applied in this non-push job.

.github/workflows/docker.yml (1)

29-30: Secure checkout setting applied correctly.

Great to disable persisted checkout credentials in the Docker workflow too.

.github/workflows/release.yml (2)

25-26: Release checkout hardening is correct.

This keeps token exposure minimized while preserving release functionality.


70-72: Inline ignore is clearly justified and documented.

Keeping the pinned, battle-tested release action with rationale here is a solid tradeoff.

.github/workflows/benchmark.yml (2)

37-37: Checkout credentials are now safely non-persistent.

Nice consistency with the other workflows.


79-87: The env-driven command refactor is well executed.

Good cleanup moving workflow expressions out of run: and relying on explicit environment variables.

Also applies to: 99-103, 106-106, 115-115, 118-119, 123-123

.github/workflows/test.yml (2)

33-34: Reusable test workflow checkout is properly hardened.

Disabling persisted credentials is the correct default here.


41-45: Shell-variable migration in run steps looks good.

The switch to env-backed variables is consistent and avoids inline expression interpolation in bash.

Also applies to: 64-67, 84-85

.github/workflows/update-latest.yml (2)

24-32: Excellent security hardening.

Moving github.event.inputs.* interpolation from the run: block to env: variables correctly mitigates template-injection risk. The shell variable references maintain proper quoting and preserve the original dist-tag logic.


51-51: LGTM – comment now matches the pinned reference.

Correcting the version annotation from v2.0.0 to v2 aligns the comment with the actual tag the SHA corresponds to, addressing the ref-version-mismatch finding.


📝 Walkthrough

Walkthrough

GitHub Actions workflows across the pnpm repository are hardened with credential persistence disabled in checkout steps, environment variable refactoring for safer parameter passing in benchmark and test execution, and configuration updates to dependabot and release automation tooling.

Changes

GitHub Actions Security and Configuration Hardening

Layer / File(s) Summary
Checkout credential hardening across workflows
‵.github/workflows/audit.yml‵, ‵.github/workflows/ci.yml‵, ‵.github/workflows/codeql-analysis.yml‵, ‵.github/workflows/docker.yml‵, ‵.github/workflows/release.yml‵, ‵.github/workflows/benchmark.yml‵
Six workflows now set persist-credentials: false in actions/checkout steps to prevent credential leakage in runner environments.
Benchmark workflow PR comment refactoring
‵.github/workflows/benchmark.yml‵
PR benchmarking logic is refactored to compute PR_NUMBER and comment metadata via explicit environment variables; includes fallback to gh pr list for PR discovery and environment-driven comment body generation with run metadata.
Test workflow environment variable hardening
‵.github/workflows/test.yml‵
Test reusable workflow now passes Node version, Git reference name, and test script through step environment variables (NODE_VERSION, REF_NAME, TEST_SCRIPT) instead of embedding template expressions in shell commands.
Release and versioning configuration updates
‵.github/workflows/release.yml‵, ‵.github/workflows/update-latest.yml‵, ‵.github/dependabot.yml‵, ‵.github/workflows/update-lockfile.yml‵
Release workflow adds explanatory comments; update-latest uses VERSION/TAG environment variables in dist-tag commands and updates action version comments; dependabot adds 7-day cooldown for github-actions updates; update-lockfile adds zizmor ignore annotation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • pnpm/pnpm#11607: Both PRs modify GitHub workflow checkout behavior by setting actions/checkout with persist-credentials: false.

Poem

🐇 With credentials tucked away so tight,
And variables flowing left and right,
The workflows now run safe and sound,
Where hardened checks and vars abound!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: addressing zizmor security findings across GitHub workflow files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch zizmor-fixes

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the repository’s GitHub Actions and Dependabot configuration to remediate zizmor security findings introduced/flagged after adding zizmor scanning, primarily by hardening workflow shell execution and reducing credential persistence.

Changes:

  • Mitigates potential workflow template injection by moving ${{ ... }} interpolations out of run: blocks into env: and referencing shell variables instead.
  • Reduces “credential persistence” findings by setting persist-credentials: false on actions/checkout in workflows that don’t need to push.
  • Adds a 7-day cooldown to Dependabot updates and fixes an action pin comment to match the referenced version.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
.github/workflows/update-lockfile.yml Keeps persisted credentials intentionally for a later git push, with inline zizmor ignore + justification.
.github/workflows/update-latest.yml Moves workflow inputs into env for safer shell usage; fixes pinned action comment version.
.github/workflows/test.yml Disables persisted checkout credentials and moves GitHub context usage into env for shell steps.
.github/workflows/release.yml Disables persisted checkout credentials; keeps softprops/action-gh-release with inline ignore + rationale.
.github/workflows/docker.yml Disables persisted checkout credentials (no push needed).
.github/workflows/codeql-analysis.yml Disables persisted checkout credentials for CodeQL workflow.
.github/workflows/ci.yml Disables persisted checkout credentials for CI workflow.
.github/workflows/benchmark.yml Disables persisted checkout credentials; moves GitHub context usage into env for shell steps.
.github/workflows/audit.yml Disables persisted checkout credentials for audit workflow.
.github/dependabot.yml Adds Dependabot cooldown to reduce update churn per zizmor recommendation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@zkochan zkochan merged commit 6b2a955 into main May 12, 2026
19 checks passed
@zkochan zkochan deleted the zizmor-fixes branch May 12, 2026 20:03
zkochan added a commit that referenced this pull request May 14, 2026
Without an explicit shell, the step ran under PowerShell on
windows-latest, where `$TEST_SCRIPT` is not a variable (PowerShell
exposes env vars as `$env:TEST_SCRIPT`). `pn run ""` then exited 0
and just listed available scripts — the Windows test legs have been
silently no-op'ing since the env-var move in #11608.
zkochan added a commit that referenced this pull request May 14, 2026
…1659)

Without an explicit shell, the step ran under PowerShell on
windows-latest, where `$TEST_SCRIPT` is not a variable (PowerShell
exposes env vars as `$env:TEST_SCRIPT`). `pn run ""` then exited 0
and just listed available scripts — the Windows test legs have been
silently no-op'ing since the env-var move in #11608.

The sibling `Verify Node version` and `Determine test scope` steps
already pin `shell: bash`; this brings `Run tests` in line.

---
Written by an agent (Claude Code, claude-opus-4-7).
zkochan added a commit that referenced this pull request May 15, 2026
…short names (#11661)

`os.tmpdir()` on GitHub's Windows runners returns the 8.3 short-name form
of the user-profile directory (e.g. `C:\Users\RUNNER~1\AppData\Local\Temp`)
because `runneradmin` is longer than 8 characters. The `~` then trips the
`quoteShellArg` allowlist regex and every test that calls `sendLineScript`
or `generateSendStdinScript` throws "Unsupported character in shell argument".

The tilde is safe to allow:
- cmd.exe performs no tilde expansion at all.
- POSIX shells only expand `~` when it is unquoted at the start of a word;
  inside the double-quoted `"${arg}"` wrapper produced here it is literal.

The matching CodeQL shell-injection sanitization argument is unchanged —
the allowlist is still anchored and still rejects every metacharacter.

The bug was masked until #11659 because the Windows test legs had been
silently no-op'ing since #11608.

---
Written by an agent (Claude Code, claude-opus-4-7).
github-actions Bot pushed a commit to Eyalm321/pnpm that referenced this pull request May 18, 2026
…pm#11659)

Without an explicit shell, the step ran under PowerShell on
windows-latest, where `$TEST_SCRIPT` is not a variable (PowerShell
exposes env vars as `$env:TEST_SCRIPT`). `pn run ""` then exited 0
and just listed available scripts — the Windows test legs have been
silently no-op'ing since the env-var move in pnpm#11608.

The sibling `Verify Node version` and `Determine test scope` steps
already pin `shell: bash`; this brings `Run tests` in line.

---
Written by an agent (Claude Code, claude-opus-4-7).
github-actions Bot pushed a commit to Eyalm321/pnpm that referenced this pull request May 18, 2026
…short names (pnpm#11661)

`os.tmpdir()` on GitHub's Windows runners returns the 8.3 short-name form
of the user-profile directory (e.g. `C:\Users\RUNNER~1\AppData\Local\Temp`)
because `runneradmin` is longer than 8 characters. The `~` then trips the
`quoteShellArg` allowlist regex and every test that calls `sendLineScript`
or `generateSendStdinScript` throws "Unsupported character in shell argument".

The tilde is safe to allow:
- cmd.exe performs no tilde expansion at all.
- POSIX shells only expand `~` when it is unquoted at the start of a word;
  inside the double-quoted `"${arg}"` wrapper produced here it is literal.

The matching CodeQL shell-injection sanitization argument is unchanged —
the allowlist is still anchored and still rejects every metacharacter.

The bug was masked until pnpm#11659 because the Windows test legs had been
silently no-op'ing since pnpm#11608.

---
Written by an agent (Claude Code, claude-opus-4-7).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants