Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,17 @@ jobs:

- run: npm ci

# Trusted publishing requires npm >= 11.5.1. Node 24's bundled npm
# may be older. Print version so we know what we're running with;
# if too old we'll upgrade in a follow-up step.
- name: Print npm version
run: npm --version

# Ensure npm is recent enough for trusted publishing. --force avoids
# the `Cannot find module 'promise-retry'` bug from in-place upgrade.
- name: Ensure npm >= 11.5.1
run: npm install -g --force npm@latest && npm --version
# Decode the GitHub OIDC token to verify the claims that will be sent
# to npmjs.com. If the trusted publisher config on npm doesn't match
# exactly (repo, workflow filename, environment), the auth will fail.
- name: Verify OIDC claims sent to npm
run: |
TOKEN=$(curl -sSf -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=npm:registry.npmjs.org")
JWT=$(echo "$TOKEN" | jq -r .value)
PAYLOAD=$(echo "$JWT" | cut -d. -f2 | tr '_-' '/+' | base64 -d 2>/dev/null || true)
echo "OIDC claims being sent to npm:"
echo "$PAYLOAD" | jq '{repository, workflow, workflow_ref, ref, environment, sub, aud}' || echo "$PAYLOAD"

- name: Detect version change
id: check
Expand All @@ -111,7 +112,10 @@ jobs:

- name: Publish to npm
if: steps.check.outputs.changed == 'true'
run: npm publish --provenance --access public
uses: JS-DevTools/npm-publish@v3
with:
provenance: true
access: public
Comment on lines +115 to +118

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 | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/release.yml | sed -n '100,130p'

Repository: charfeng1/opencode-ralph-loop

Length of output: 1659


🏁 Script executed:

cat -n .github/workflows/release.yml | sed -n '1,150p'

Repository: charfeng1/opencode-ralph-loop

Length of output: 6172


🌐 Web query:

GitHub actions security hardening pin action full commit SHA third-party

💡 Result:

Pinning GitHub Actions to a full-length commit SHA is a critical security best practice for supply chain hardening [1][2][3]. Because version tags (e.g., @v4) and branch references (e.g., @main) are mutable, they can be updated or force-pushed by an action maintainer—or a malicious actor who compromises the maintainer's account—to point to different, potentially malicious code at any time [4][5][6]. Why Pinning to a Full Commit SHA is Necessary: - Immutability: A full-length (40-character) commit SHA uniquely identifies a specific state of a repository [5][7]. Once pinned, the code executed by your workflow cannot be altered, ensuring consistency and reproducibility [7][6]. - Mitigation of Supply Chain Attacks: If an action's repository is compromised, pinning prevents your workflows from automatically pulling in injected malicious code [7][2]. An attacker would need to generate a SHA-1 collision to replace the pinned code, which is computationally infeasible [5][2]. - Organizational Policy: GitHub allows administrators to enforce full commit SHA pinning at the organization or repository level [1][2]. When enabled, workflows referencing actions by mutable tags will fail, forcing compliance across the dependency tree [1]. Best Practices for Implementation: - Use Full SHAs: Always use the full 40-character SHA, not a shortened version [5]. - Verify Sources: Ensure the SHA originates from the official action repository, not a fork [5][2]. - Maintainability: To manage updates, use automated dependency management tools like Dependabot or Renovate [1][5][6]. You can include the version tag as a comment in your workflow file to make it easier to track which version the SHA corresponds to (e.g., uses: actions/checkout@a12b34... # v4.1.1) [8][5][6]. - Audit Dependencies: Pinning is one layer of defense; you should also audit the source code of third-party actions and limit their use to trusted publishers [2][3][9]. Note: While pinning is essential, it should be part of a broader security strategy that includes limiting token permissions, using OIDC for secrets, and auditing workflow configurations [10][3][11].

Citations:


Pin this third-party action to a full commit SHA.

The JS-DevTools/npm-publish@v3 action is currently referenced by a mutable version tag. GitHub's security guidance recommends pinning third-party actions to full-length commit SHAs for supply chain hardening, especially in jobs with elevated permissions like this one (which has contents: write and id-token: write). Version tags can be force-pushed or compromised; only full commit SHAs are immutable and cannot be altered retroactively. Consider using a tool like Dependabot to manage updates.

🤖 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/release.yml around lines 115 - 118, Replace the mutable
tag reference to the third-party action used in the workflow (the uses entry
"JS-DevTools/npm-publish@v3") with a full commit SHA to pin the action; update
the uses value to "JS-DevTools/npm-publish@<full-commit-sha>" (obtain the SHA
from the action repo), commit that change, and consider adding a note to track
updates via Dependabot or similar so future upgrades are managed safely.


- name: Tag and create GitHub release
if: steps.check.outputs.changed == 'true'
Expand Down
Loading