Skip to content

GitHub Actions: SHA-pin first-party actions/* repo-wide, or document the floating-tag choice? (Pinned-Dependencies) #1022

Description

@isaacschepp

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-party actions/* 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

Activity

  1. added
    github_actionsPull requests that update GitHub Actions code
    toolingInfrastructure, workflow, and developer tools
    needs-triageIssue intake couldn't classify the Area — maintainer triage required
    on Jun 7, 2026
  2. isaacschepp commented on Jun 8, 2026

    @isaacschepp
    CollaboratorAuthor

    Cross-ref: when the first-party actions/* floating-vs-SHA decision lands here, the .github/CLAUDE.md pinning section must be updated in the same pass. Its current H2 heading (.github/CLAUDE.md:3) mandates bare vX.Y.Z for third-party actions — the inverse of the repo's SHA-pin convention — and says nothing about the first-party @vN choice this issue decides.

    Filed #1046 to rewrite that section into a three-tier convention (SHA-pin third-party with # vX.Y.Z comment / float first-party actions/* 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.

  3. isaacschepp commented on Jun 8, 2026

    @isaacschepp
    CollaboratorAuthor

    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:

    1. 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.Z comment in sync. So uses: actions/checkout@<sha> # v6.1.0 still receives version-update PRs — you keep auto-updates and gain immutability. This is exactly the OpenSSF Scorecard Pinned-Dependencies expectation (checks.md).

    2. 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.Z comment) instead. Layer cooldown (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-party actions/* (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.

  4. removed
    needs-triageIssue intake couldn't classify the Area — maintainer triage required
    on Aug 23, 2026
  5. noahbjohnson commented on Sep 17, 2026

    @noahbjohnson
    Member

    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.md still says "pending #1022". We still need to either SHA-pin them or document why floating tags are acceptable.

  6. added this to the v0.0.0-beta.13 milestone on Sep 17, 2026
  7. isaacschepp commented on Sep 18, 2026

    @isaacschepp
    CollaboratorAuthor

    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-uses default 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    github_actionsPull requests that update GitHub Actions codetoolingInfrastructure, workflow, and developer tools

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions