chore(ci): zizmor hardening — pin reusable, narrow permissions, drop persisted credentials#62
Conversation
…persisted credentials
Closes the three actionable zizmor findings on main:
- security.yml:24 (unpinned-uses, error): pin
`security-scan.yml` to SHA 23ce94e (the same SHA already used in ci.yml
for required.yml + node-ci.yml — consistent across all three reusables).
- ci.yml:27 (excessive-permissions, warn): drop workflow-level
`security-events: write` + `pull-requests: read`. Each job now grants
only what it needs: `gates` keeps both for CodeQL/SARIF + PR-diff
scanning; `client` and `client-budget` are read-only; `required`
aggregator gets `permissions: {}` (pure shell on env vars).
- ci.yml:88 (artipacked, warn): add `persist-credentials: false` to the
`actions/checkout` in `client-budget`. The next step uploads
`wwwroot/` as an artifact; without this, a credentialed `.git/config`
could ride along.
Deferred (require org-reusable interface knowledge): the three
`secrets-inherit` warnings (#14, #16, #25). Will tighten once the
`secrets:` declarations of required.yml / node-ci.yml / security-scan.yml
are mapped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Note Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported. |
📝 WalkthroughWalkthroughThe pull request tightens GitHub Actions security by applying the principle of least privilege. Permissions are moved from top-level configuration to individual job-level declarations with only necessary scopes, credential persistence is disabled in the checkout step, and the security workflow is pinned to a specific commit SHA instead of dynamically tracking the main branch. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/security.yml (1)
24-24: Optional: trailing# maincomment will go stale.The point of pinning to a SHA is that it deliberately does not track
main. As soon asmaininresq-software/.githubadvances, this comment becomes inaccurate. Consider replacing it with the upstream tag (if there is one) or a date marker so future readers can tell when the pin was last refreshed:♻️ Proposed tweak
- uses: resq-software/.github/.github/workflows/security-scan.yml@23ce94eabddf963835624451e89baca7ac9db541 # main + uses: resq-software/.github/.github/workflows/security-scan.yml@23ce94eabddf963835624451e89baca7ac9db541 # pinned 2026-04-26Note that the same SHA is used unannotated at
ci.yml:41,:58— aligning the annotation style across the two files would also help (Dependabot can keep them in sync if labeled consistently).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/security.yml at line 24, The trailing comment "# main" after the pinned action reference (uses: resq-software/.github/.github/workflows/security-scan.yml@23ce94eabddf963835624451e89baca7ac9db541) is misleading because the SHA is immutable; replace that comment with a stable annotation such as the upstream tag name (if available) or a date/version marker indicating when the SHA was pinned, and update the other occurrences of the same SHA (the unannotated usages in ci.yml) to use the same annotation style so all pins are documented consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.github/workflows/security.yml:
- Line 24: The trailing comment "# main" after the pinned action reference
(uses:
resq-software/.github/.github/workflows/security-scan.yml@23ce94eabddf963835624451e89baca7ac9db541)
is misleading because the SHA is immutable; replace that comment with a stable
annotation such as the upstream tag name (if available) or a date/version marker
indicating when the SHA was pinned, and update the other occurrences of the same
SHA (the unannotated usages in ci.yml) to use the same annotation style so all
pins are documented consistently.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 94dd170c-c55f-45e9-9403-adf353bfbcc4
📒 Files selected for processing (2)
.github/workflows/ci.yml.github/workflows/security.yml
Summary
Closes the three actionable zizmor findings against
main:unpinned-uses(error)security.yml:24security-scan.yml@main→@23ce94eabddf963835624451e89baca7ac9db541(same SHA already used inci.ymlforrequired.yml+node-ci.yml)excessive-permissions(warn)ci.yml:27security-events: write+pull-requests: read; declare per-jobartipacked(warn)ci.yml:88persist-credentials: falsetoactions/checkoutinclient-budget(artifact upload no longer risks packing the GH token)Per-job permissions:
gates—contents: read+security-events: write+pull-requests: read(calls security-scan viarequired.yml)client—contents: readclient-budget—contents: readrequired—permissions: {}(pure aggregator onneeds.*.result)Deferred
Three
secrets-inheritwarnings (#14 / #16 / #25) on thesecrets: inheritlines of the reusable callers — fixing requires reading thesecrets:interface ofrequired.yml/node-ci.yml/security-scan.ymlto know what to keep. Will follow up.Test plan
gatesstream (provessecurity-events: writereached the right scope)🤖 Generated with Claude Code
Summary by CodeRabbit