Skip to content

chore(ci): zizmor hardening — pin reusable, narrow permissions, drop persisted credentials#62

Merged
WomB0ComB0 merged 1 commit into
mainfrom
chore/zizmor-workflow-hardening
Apr 26, 2026
Merged

chore(ci): zizmor hardening — pin reusable, narrow permissions, drop persisted credentials#62
WomB0ComB0 merged 1 commit into
mainfrom
chore/zizmor-workflow-hardening

Conversation

@WomB0ComB0
Copy link
Copy Markdown
Member

@WomB0ComB0 WomB0ComB0 commented Apr 26, 2026

Summary

Closes the three actionable zizmor findings against main:

Alert Rule Where Fix
#13 unpinned-uses (error) security.yml:24 Pin security-scan.yml@main@23ce94eabddf963835624451e89baca7ac9db541 (same SHA already used in ci.yml for required.yml + node-ci.yml)
#15 excessive-permissions (warn) ci.yml:27 Drop workflow-level security-events: write + pull-requests: read; declare per-job
#22 artipacked (warn) ci.yml:88 Add persist-credentials: false to actions/checkout in client-budget (artifact upload no longer risks packing the GH token)

Per-job permissions:

  • gatescontents: read + security-events: write + pull-requests: read (calls security-scan via required.yml)
  • clientcontents: read
  • client-budgetcontents: read
  • requiredpermissions: {} (pure aggregator on needs.*.result)

Deferred

Three secrets-inherit warnings (#14 / #16 / #25) on the secrets: inherit lines of the reusable callers — fixing requires reading the secrets: interface of required.yml / node-ci.yml / security-scan.yml to know what to keep. Will follow up.

Test plan

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Updated CI/CD pipeline configuration with refined permission scopes across jobs
    • Modified checkout credentials behavior in build processes
    • Pinned security workflow to a specific commit version for consistency

…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>
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Note

Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 26, 2026

📝 Walkthrough

Walkthrough

The 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

Cohort / File(s) Summary
CI Workflow Permissions Refactoring
.github/workflows/ci.yml
Redistributes top-level permissions (contents: read only) to individual jobs; gates receives security-events: write and pull-requests: read, client and client-budget explicitly declare contents: read, and required aggregator set to permissions: {}. Additionally, client-budget checkout step changed to persist-credentials: false.
Security Workflow Pinning
.github/workflows/security.yml
scan job's reusable workflow reference pinned from main branch to specific commit SHA for deterministic security scanning execution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 A rabbit hops through workflows with care,
Permissions tightened everywhere,
Least privilege is the way,
Credentials locked away,
Security blooms—snip, snap, secure! ✨

🚥 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 summarizes the main changes: pinning a reusable workflow, narrowing GitHub token permissions, and removing persisted credentials from checkout steps.
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 chore/zizmor-workflow-hardening

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.

❤️ Share

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.github/workflows/security.yml (1)

24-24: Optional: trailing # main comment will go stale.

The point of pinning to a SHA is that it deliberately does not track main. As soon as main in resq-software/.github advances, 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-26

Note 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

📥 Commits

Reviewing files that changed from the base of the PR and between 50e805b and f403515.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • .github/workflows/security.yml

@WomB0ComB0 WomB0ComB0 merged commit 958cf25 into main Apr 26, 2026
37 checks passed
@WomB0ComB0 WomB0ComB0 deleted the chore/zizmor-workflow-hardening branch April 26, 2026 17:53
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.

1 participant