ci(security): SHA-pin GitHub Actions in publish.yml (SEC-06) - #3
Conversation
📝 WalkthroughWalkthroughThe publish workflow is updated to pin GitHub Actions setup steps to specific commit SHAs instead of version tags. ChangesWorkflow Action Pinning
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 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.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/publish.yml:
- Around line 22-24: The checkout step currently uses actions/checkout and
leaves the workflow token persisted; update the checkout step (the
actions/checkout@... usage) to include persist-credentials: false to prevent the
workflow token from being written to local git config and reduce token exposure
in downstream steps/artifacts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1833848c-c7de-4100-b337-9819be19a0f5
📒 Files selected for processing (1)
.github/workflows/publish.yml
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1) | ||
| with: | ||
| fetch-depth: 0 |
There was a problem hiding this comment.
Disable credential persistence in checkout step.
actions/checkout persists the workflow token in local git config by default. Set persist-credentials: false to reduce token exposure risk in downstream steps/artifacts.
Suggested patch
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1)
with:
fetch-depth: 0
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1) | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1) | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 22-24: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/publish.yml around lines 22 - 24, The checkout step
currently uses actions/checkout and leaves the workflow token persisted; update
the checkout step (the actions/checkout@... usage) to include
persist-credentials: false to prevent the workflow token from being written to
local git config and reduce token exposure in downstream steps/artifacts.
Source: Linters/SAST tools
Summary
SHA-pins the three
actions/*@v4GitHub Actions references in.github/workflows/publish.ymlto immutable commit SHAs. This is auses:-SHA-value-only change — no version bump (v4 stays v4), and noon:/trigger,if:,with:,env:,needs:, or job-logic change.Mapped pins (26-02 §2c):
actions/checkout@v4→actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1)actions/setup-java@v4→actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 (v4.8.0)actions/setup-node@v4→actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 (v4.4.0)No-release proof (C1–C6, Archetype C) — UltiRecipe
uses:lines re-confirmed@v4onorigin/masterthis plan — L22actions/checkout@v4, L27actions/setup-java@v4, L94actions/setup-node@v4— plus an optional trailing# v4 (vX.Y.Z)comment, pasting the 26-02 §2c pin strings verbatim. It MUST add/remove/modify noon:/trigger, noif:, nowith:, noenv:, noneeds:, and no step ordering or job logic. (Re-verified againstgit diff origin/masterin Task 3, gated behind the Task 2 token.)on: push: branches: [master](withpaths-ignorefor**.md,.gitignore,LICENSE) +workflow_dispatch(optionalversioninput). Neither event is produced by the pin edit itself: a SHA-pin commit on a feature branch targetingmastervia PR does not trigger thepush: branches: [master]path until merge, and at merge the existing-version guard (C5) intercepts before any publish step. Nopull_requesttrigger (26-01 §0). UltiRecipe'spublish.ymlis byte-identical to UltiMenu's (shared sha256), so the trigger block is the same.release-and-publish(contents: write). Stepcheck(Check if release exists, ~L48–58) runsgh release view "v${VERSION}"→EXISTS=true|false. Every subsequent publish step (Generate changelog,Set project version,Build,Create GitHub Release,Set up Node.js,Install UltiKits CLI,Publish to UltiCloud) is gatedif: steps.check.outputs.EXISTS == 'false'.EXISTSguard (C3/C5) are byte-identical pre/post pin. The set of conditions under which any publish step runs is therefore unchanged. The pin cannot alterpom.xml<version>nor the release state, so it cannot flipEXISTS.${VERSION}=1.0.0(fromgit show origin/master:pom.xml<version>, read-only — no Maven build).gh release view "v1.0.0" --repo UltiKits/UltiRecipe→ exit0; payload{"createdAt":"2026-02-15T00:51:56Z","isDraft":false,"isPrerelease":false,"name":"v1.0.0","tagName":"v1.0.0"}.EXISTS=true— releasev1.0.0is published (not draft, not prerelease). TheEXISTS=truebranch short-circuits every publish step unconditionally; a SHA-only pin on a feature branch cannot flipEXISTS.PASS — config-only pin, unreachable-to-publish. Master base ref5ce6163e89bf7ad43d59079d543b083b21f3c2e1;publish.ymlmaster sha25636728f8498b903237d1fdb3ee4d84c5e8f0cd6c3e6a3254f0a743d70f0d85998(pre == post).Merge boundary
Do NOT merge until the maintainer supplies the per-PR merge token (
approve 28-01-merge) with the proof recorded PASS and CI confirming no release/tag/publish fired.publish.ymltriggers onpush: branches: [master]+workflow_dispatch— neither fires on this feature-branch PR; the existing-version guard short-circuits at merge anyway.Summary by CodeRabbit