Repository navigation
GitHub Actions: SHA-pin first-party actions/* repo-wide, or document the floating-tag choice? (Pinned-Dependencies) #1022
Description
Policy question
The Scorecard Pinned-Dependencies probe does not exempt GitHub-owned actions. So actions/checkout@v6 (scorecard.yml:29), actions/upload-artifact@v7 (scorecard.yml:41) — and every other first-party @vN float across all workflows — count against Pinned-Dependencies (currently 4/10). SHA-pinning only the third-party deviations (the companion scorecard.yml issue) cannot push the GitHub-Actions sub-score to a perfect proportion while first-party floats remain.
But the drag is small. Per checks/evaluation/pinned_dependencies.go, GitHub-owned actions carry weight 2 versus third-party weight 8 (normalWeight = 10) — an unpinned first-party action reduces the score roughly ¼ as much as an unpinned third-party one. The third-party fixes remain the dominant lever; the first-party floats are a minor residual.
This is also a standing repo convention: first-party actions/* are tag-pinned to a floating major across all workflows, while third-party actions are SHA-pinned. .github/CLAUDE.md calls SHA-pinning "acceptable too and arguably preferred" but only mandates patch-level pins for actions lacking a floating major (scorecard-action #779, cosign-installer #938).
Decision needed — repo-wide, NOT per-file
Splitting the first-party policy per file — the way codeql-action is currently split between scorecard.yml and security.yml — is the anti-goal. Pick one and apply it everywhere:
- (a) Accept the floats as a documented editorial choice in
SECURITY-POSTURE.md, and accept the weight-2 Pinned-Dependencies ceiling. Rationale: first-partyactions/*from GitHub are lower-risk, the score impact is small, and floating majors reduce churn. - (b) SHA-pin first-party
actions/*repo-wide. Verified current SHAs (2026-06-07):actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3(v6.0.3 is an annotated tag; this is the dereferenced commit, which is the correct pin target)actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1- (…and the rest:
setup-go,setup-node,cache,download-artifact,create-github-app-token,dependency-review-action.)
Dependabot (github-actions ecosystem, already enabled weekly) sustains either choice and rewrites the # vX.Y.Z comment on each release.
Sequencing note
If (b): frame it as a follow-up to the third-party SHA-pin commit, not part of it. And note that if #928 (zizmor) lands, zizmor's blanket unpinned-uses hash-pin default would flag these first-party floats too — so (b) becomes effectively required to keep zizmor green, unless a documented per-namespace zizmor config exception is added instead.
Cross-refs
- Follows the scorecard.yml third-party SHA-pin issue.
- Relates to ci: add zizmor + actionlint static analysis for workflow files #928 (zizmor + actionlint).
Activity
isaacschepp commentedon Jun 8, 2026
Cross-ref: when the first-party
actions/*floating-vs-SHA decision lands here, the.github/CLAUDE.mdpinning section must be updated in the same pass. Its current H2 heading (.github/CLAUDE.md:3) mandates barevX.Y.Zfor third-party actions — the inverse of the repo's SHA-pin convention — and says nothing about the first-party@vNchoice this issue decides.Filed #1046 to rewrite that section into a three-tier convention (SHA-pin third-party with
# vX.Y.Zcomment / float first-partyactions/*pending this issue / patch-pin the no-floating-major exceptions #779, #938) and to point readers here for the first-party policy. #1046's proposed rewrite already references #1022 as the authority for case 2.isaacschepp commentedon Jun 8, 2026
2026 Dependabot-interplay note for the SHA-pin decision here.
Two non-obvious facts should inform the "SHA-pin first-party
actions/*vs. document the float" call, because together they remove the usual objection that SHA-pinning "freezes" updates:SHA-pinning does NOT stop Dependabot from updating the action. Since 2022-10-31, Dependabot bumps the pinned SHA and keeps the trailing
# vX.Y.Zcomment in sync. Souses: actions/checkout@<sha> # v6.1.0still receives version-update PRs — you keep auto-updates and gain immutability. This is exactly the OpenSSF Scorecard Pinned-Dependencies expectation (checks.md).But Dependabot only raises vulnerability alerts for semver-tag refs — never for SHA-pinned actions (GitHub "secure use" reference: "Dependabot only creates alerts for vulnerable actions that use semantic versioning and will not create alerts for actions pinned to SHA values."). So once pinned to SHA, a later CVE in that action will not trip a Dependabot alert — you rely on the routine version-update PR (carrying the fix via the
# vX.Y.Zcomment) instead. Layercooldown(dependabot: add native cooldown (min-release-age) to defend against worm-class supply-chain updates #929) on and that PR is also delayed past the worm-detection window, which is the desired behavior.Combined picture: #1022 (SHA-pin) and #929 (cooldown) are the two halves that close the floating-
actions/*exposure — pinning gives immutability against tag-retargeting (the tj-actions / CVE-2025-30066 pattern), cooldown gives the settling window. Neither alone is sufficient, and the repo currently has neither for first-partyactions/*(checkout@v6,setup-go@v6,setup-node@v6,upload-artifact@v7,download-artifact@v8,cache@v5,create-github-app-token@v3,dependency-review-action@v5). Worth reconciling the decision here with #1019 (the scorecard.yml SHA-pin subset) so the policy is applied uniformly rather than file-by-file.docs: Correct .github/CLAUDE.md guidance; freshen SUPPORT.md and OSPS…
noahbjohnson commentedon Sep 17, 2026
Status as of v0.0.0-beta.12: third-party actions are now pinned to release commit SHAs (#968, #1185).
Remaining: first-party
actions/*still use floating tags (e.g.actions/checkout@v7), and.github/CLAUDE.mdstill says "pending #1022". We still need to either SHA-pin them or document why floating tags are acceptable.isaacschepp commentedon Sep 18, 2026
Reversed the same day. This closed on option (a) — accept the floats, document the Scorecard ceiling — and the floats are now gone: #1263 / #1264 SHA-pin first-party
actions/*repo-wide, which is option (b) as originally framed here.The reasoning that changed: (a) rested on publisher trust, that GitHub publishes
actions/*and also operates the runners. But publisher trust isn't the question a pin answers. A pin asserts that the ref can't change under the workflow — and a floating major is a mutable ref whoever owns it. A re-pointed one runs with the workflow's permissions, which is the CVE-2025-30066 primitive regardless of namespace.The "small drag" arithmetic in the issue body (weight 2 vs 8) is still correct and was never the load-bearing argument in either direction; the score was the symptom, the mutable ref was the exposure.
The sequencing note here also anticipated this: zizmor's
unpinned-usesdefault would have flagged the first-party floats, making (b) "effectively required to keep #928 green, unless a documented per-namespace zizmor config exception is added instead." #928 no longer needs that exception.SECURITY-POSTURE.md§ Action pinning now states one namespace-blind rule instead of three tiers, and records the inverted tradeoff — SHA pins forgo Dependabot vulnerability alerts (semver-tag refs only) in exchange for immutability plus the weekly version-update PRs that actually carry the fix.sigstore/cosign-installer(#938) came off its exact patch tag at the same time, since that was a mutable ref too.Leaving this closed; #1263 is the record of the reversal.
ci: SHA-pin first-party actions/* repo-wide (reverses #1022) (#1264)
chore: Merge main into fix/osv-vulns-62