Skip to content

ci(security): SHA-pin GitHub Actions in publish.yml (SEC-06) - #3

Merged
wisdommen merged 1 commit into
masterfrom
feature/sha-pin-publish-yml
Jun 11, 2026
Merged

ci(security): SHA-pin GitHub Actions in publish.yml (SEC-06)#3
wisdommen merged 1 commit into
masterfrom
feature/sha-pin-publish-yml

Conversation

@wisdommen

@wisdommen wisdommen commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

SHA-pin GitHub Actions in publish.yml (SEC-06)

This PR applies a uses:-SHA-value-only pin to the three GitHub Actions in .github/workflows/publish.yml — pasting the canonical SHA values for the actions already referenced at @v4. No version bump (still # v4), no trigger / if: / with: / env: / needs: / step-order change. Part of GSD phase 28 (batch-3 cohort, plan 28-04).

Ref-as-written Pinned SHA Comment
actions/checkout@v4 34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1)
actions/setup-java@v4 c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 (v4.8.0)
actions/setup-node@v4 49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 (v4.4.0)

Before → after pin lines

- uses: actions/checkout@v4
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5  # v4 (v4.3.1)
- uses: actions/setup-java@v4
+ uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9  # v4 (v4.8.0)
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020  # v4 (v4.4.0)

UltiSocial — C1–C6 no-release proof verdict (Archetype C, SEC-06)

Proof recorded in the 28-04 proof artifact (Task 1, proof-before-edit). All checks PASS for this module.

  • C1 — Diff is SHA-value-only. The diff changes only the SHA token on the three mapped uses: lines confirmed @v4 on origin/masterL22 actions/checkout@v4, L27 actions/setup-java@v4, L94 actions/setup-node@v4 — plus a trailing # v4 (vX.Y.Z) comment. No on:/trigger, no if:, no with:, no env:, no needs:, no step ordering or job logic changed. (Re-verified via git diff origin/master in Task 3 — exactly 3 changed lines.)
  • C2 — Trigger model. on: push: branches: [master] (with paths-ignore) + workflow_dispatch. Neither event is produced by the pin edit itself: a SHA-pin commit on a feature branch targeting master via PR does not trigger the push: branches: [master] path until merge, and at merge the existing-version guard (C5) intercepts before any publish step. No pull_request trigger.
  • C3 — Guard. Single job release-and-publish (permissions: contents: write). Step check (Check if release exists) runs if gh release view "v${VERSION}" ... EXISTS=true ... else EXISTS=false. Every subsequent publish step is gated if: steps.check.outputs.EXISTS == 'false'.
  • C4 — Diff-reachability = unreachable-to-publish. Because C1 holds, the trigger (C2) and the EXISTS guard (C3/C5) are byte-identical pre/post pin. The set of conditions under which any publish step runs is unchanged. The pin cannot alter pom.xml <version> nor the release state, so it cannot flip EXISTS.
  • C5 — Existing-version guard (EXISTS=true). Release v1.0.0 is published on UltiKits/UltiSocial (not draft, not prerelease); tag v1.0.0353a9ea4.... pom.xml project <version> matches the published v1.0.0 tag, so the workflow's existing-version guard resolves EXISTS=true and short-circuits every publish step. A SHA-only pin on a feature branch cannot flip EXISTS.
  • C6 — Verdict. PASS — config-only pin, unreachable-to-publish.

EXISTS=true evidence

  • master HEAD: 836ed96 (origin/master)
  • publish.yml present on master (EXISTS=true), sha256 36728f84...
  • Published release v1.0.0 (tag v1.0.0353a9ea4...), not draft / prerelease.
  • C1–C6: all PASS (config-only pin, unreachable-to-publish).
  • uses: refs on master: L22 actions/checkout@v4, L27 actions/setup-java@v4, L94 actions/setup-node@v4.

Reference: 28-04 proof artifact (batch-3 cohort), maintainer token approve 28-04-cohort-batch-3.


Must NOT be merged until the maintainer's per-PR token with proof PASS + CI confirming no release/tag/publish fired.

Summary by CodeRabbit

  • Chores
    • Updated GitHub Actions in CI/CD workflow to use pinned commit-SHAs instead of floating version tags for checkout, Java setup, and Node.js setup actions, while preserving all existing configurations and step names.

Pin actions/checkout, actions/setup-java, actions/setup-node to immutable
commit SHAs per 26-02 §2c. Config-only change; no-release proof recorded
in 28-04 (C1-C6 PASS, EXISTS=true).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR pins three GitHub Actions to specific commit SHAs in the publish workflow instead of using floating version tags: actions/checkout, actions/setup-java, and actions/setup-node. All step names, conditions, and configurations remain unchanged.

Changes

CI Workflow Security

Layer / File(s) Summary
GitHub Actions version pinning
.github/workflows/publish.yml
actions/checkout, actions/setup-java, and actions/setup-node are updated from floating v4 tags to pinned commit SHAs while preserving all step configurations (fetch-depth, JDK 8, Node 20).

Poem

🐰 The Actions now stand still and sure,
Pinned to commits, their fate secure,
No floating tags to drift astray,
The workflow's locked to stay today!

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 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 clearly and specifically describes the main change: SHA-pinning GitHub Actions in the publish.yml workflow file for security purposes.
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 feature/sha-pin-publish-yml

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 action is leaving the job auth token in git
config by default; in the workflow step that uses actions/checkout (the entry
referencing actions/checkout@34e1148...), add the input persist-credentials:
false to the step so credentials are not written to the repo git config; update
the checkout step where fetch-depth: 0 is set to include persist-credentials:
false to harden credential handling.
🪄 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: de13ad82-ef01-4493-9b2a-3f44c0fbc801

📥 Commits

Reviewing files that changed from the base of the PR and between 836ed96 and a852ed9.

📒 Files selected for processing (1)
  • .github/workflows/publish.yml

Comment on lines +22 to 24
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 (v4.3.1)
with:
fetch-depth: 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE=".github/workflows/publish.yml"
if [ ! -f "$FILE" ]; then
  echo "Missing $FILE" >&2
  exit 1
fi
echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,120p'
echo "== grep checkout =="
rg -n "uses:\s*actions/checkout|persist-credentials|GH_TOKEN|gh " "$FILE" || true

Repository: UltiKits/UltiSocial

Length of output: 166


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE=".github/workflows/publish.yml"
if [ ! -f "$FILE" ]; then
  echo "Missing $FILE" >&2
  exit 1
fi

echo "== File: $FILE (first 160 lines) =="
cat -n "$FILE" | sed -n '1,160p'

echo "== checkout-related lines =="
rg -n "actions/checkout|persist-credentials|fetch-depth|GH_TOKEN|gh " "$FILE" || true

echo "== git command usage around tokens =="
rg -n "(git (push|config|credential)|GH_TOKEN|GITHUB_TOKEN|persist-credentials)" "$FILE" || true

Repository: UltiKits/UltiSocial

Length of output: 4984


🌐 Web query:

actions/checkout v4 persist-credentials default value

💡 Result:

The default value for the persist-credentials input in actions/checkout v4 is true [1][2]. When set to true (the default), the action configures the authentication token or SSH key in the local git configuration, which allows subsequent steps in your workflow to execute authenticated git commands [3][4]. The token is automatically removed during the post-job cleanup phase [5][6]. You can set persist-credentials to false if you wish to opt out of this behavior [3][6].

Citations:


Harden actions/checkout credential handling by disabling credential persistence.

actions/checkout v4 defaults persist-credentials: true, which writes the auth token into the local git config for the job. This workflow doesn’t perform authenticated git operations (release actions use gh via GH_TOKEN), so disable persistence to reduce token exposure during subsequent build steps.

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.

Suggested change
- 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 action is
leaving the job auth token in git config by default; in the workflow step that
uses actions/checkout (the entry referencing actions/checkout@34e1148...), add
the input persist-credentials: false to the step so credentials are not written
to the repo git config; update the checkout step where fetch-depth: 0 is set to
include persist-credentials: false to harden credential handling.

Source: Linters/SAST tools

@wisdommen
wisdommen merged commit e6f8f0d into master Jun 11, 2026
7 checks passed
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