Skip to content

ci(security): pin GitHub Actions to full commit SHAs#35

Open
dmchaledev wants to merge 1 commit into
mainfrom
claude/magical-ptolemy-4h7bvh
Open

ci(security): pin GitHub Actions to full commit SHAs#35
dmchaledev wants to merge 1 commit into
mainfrom
claude/magical-ptolemy-4h7bvh

Conversation

@dmchaledev

Copy link
Copy Markdown
Contributor

Summary

Pin the third-party GitHub Actions used in all three workflows to immutable full commit SHAs (with the resolved version in a trailing comment) instead of the mutable @v4 major tag:

Action Before After
actions/checkout @v4 @34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
actions/setup-node @v4 @49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0

Touched: .github/workflows/ci.yml, .github/workflows/publish.yml, .github/workflows/auto-tag.yml. Six uses: references in total. No workflow logic changes.

Why

A @v4 tag is a mutable pointer — the action's maintainer (or anyone who compromises their account) can force-move it to point at arbitrary code, and every consumer picks that up on the next run with no diff to review. This is the classic CI supply-chain vector (e.g. the tj-actions/changed-files compromise).

That risk is most acute in publish.yml, which runs with permissions: id-token: write and injects NPM_PUBLISH_TOKEN. A moved tag on checkout or setup-node there could exfiltrate the npm token or publish a backdoored release under this package's own name. Pinning to a SHA guarantees every run executes exactly the code that was audited when the pin was set.

For a package that exists to track supply-chain integrity, hardening its own supply chain is appropriate dogfooding. It's also the OpenSSF Scorecard Pinned-Dependencies recommendation and GitHub's documented hardening guidance.

Not a duplicate / composes with #34

None of the open PRs pin actions to SHAs. #34 adds a Dependabot config but deliberately keeps the floating @v4 tags and relies on Dependabot to bump the major tag — which still leaves a mutable pointer between Dependabot runs. This change is complementary: Dependabot's github-actions ecosystem understands the @<sha> # <version> format and updates both the SHA and the comment, so pinning does not freeze the versions — it just makes each pin immutable until an update is reviewed and merged.

Verification

  • Each SHA was resolved from the upstream repo (git ls-remote --tags) — v4.3.1 for checkout, v4.4.0 for setup-node (latest v4.x at time of writing).
  • All three workflow files still parse as valid YAML.
  • The edited ci.yml runs on this PR, exercising the new checkout/setup-node pins directly.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QvQQy7fpkxLaR1idLHgX2e


Generated by Claude Code

Pin actions/checkout and actions/setup-node to immutable commit SHAs
(with the resolved version in a trailing comment) across all three
workflows instead of the mutable `@v4` major tag.

Mutable tags can be force-moved by a compromised or hijacked action
maintainer to point at malicious code. The publish workflow runs with
`id-token: write` and holds `NPM_PUBLISH_TOKEN`, so a moved tag there
could exfiltrate the npm token or publish a backdoored release under
this package's name. Pinning to a SHA makes every workflow run use
exactly the audited code. This is the OpenSSF Scorecard
"Pinned-Dependencies" recommendation and appropriate dogfooding for a
supply-chain security tool.

Dependabot's github-actions ecosystem understands the
`@<sha> # <version>` format and keeps the pins current, so this
composes with automated updates rather than freezing the versions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvQQy7fpkxLaR1idLHgX2e
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.

2 participants