Pin all workflow actions to commit SHAs#703
Conversation
Pin every third-party action reference in the repo's real workflow
files to an immutable commit SHA, with the human-readable version in
a trailing comment. This follows the GitHub Actions security hardening
guidance — once pinned by SHA, a compromised upstream tag cannot
silently change what our workflows run, and Dependabot treats the
trailing `# v...` comment as part of the reference so it will bump
both the SHA and the comment when a new release lands.
Covers every workflow under .github/workflows/ that was previously
referencing a floating tag:
- actions/checkout@v6.0.2
-> @de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
(check_approved_limit, pelican-action-test x2, update_actions,
linting, remove_expired, update_dummy, codeql-analysis,
verify_dependabot_action, pytest, stash-action-test x3)
- actions/setup-python@v6
-> @a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
(linting)
- github/codeql-action/{init,autobuild,analyze}@v4
-> @c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
(codeql-analysis)
dummy.yml is intentionally untouched. It is generated from
/actions.yml by gateway/gateway.py and carries its own pinning
convention, regenerated via update_dummy.yml — manual edits there
would be clobbered on the next regeneration.
Dependabot already covers these updates via the existing
`package-ecosystem: "github-actions"` entry in .github/dependabot.yml,
which lists "/" in its `directories` (that covers everything under
.github/workflows/). No config change is required for Dependabot to
start proposing version bumps for the newly-pinned references.
Generated-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
raboof
left a comment
There was a problem hiding this comment.
I'm not sure I agree this is "almost 0 overhead", as it'll create PRs for every patch version bump of these GHA actions, which need to be approved and merged, but generally I'm OK with the change. I do expect your help in reviewing and merging those PRs :)
|
While I agree in spirit, I think pinning the CodeQL action is counter-productive: the purpose of the action is to discover bugs or bad practices in code and new rules are added in new releases. It is probably better to keep this “pinned” to |
Sure - we'd keep updating it based on dependabot PRs, so we'd get the new rules with those new releases, right? |
|
I am certain we will update it, but with the amount of additional review work we received, we probably have to choose our battles. Personally I find using |
I agree. |
I guess it's the same case as Trivy - it was also a security scanner that has been hacked. And of course we can assume that GH has much more protection on their actions (especially CodeQL), but I think we would be a bit safer if we had hash and some cooldown. Hacking CodeQL action woudl be extremely lucrative target in general, so I think just for that sake of that very low-probability issue, it's worth to keep (some) cooldown. Also see the cooldown discussion in #683 - I think it is a bit more nuanced discussion. But yes - security is never 0/1, it's a matter of what kind of scenarios we want to protect against and risk willing to accept. |
Summary
Pin every third-party action reference in the repo's real workflow files to
an immutable commit SHA, with the human-readable version in a trailing
comment. This follows the GitHub Actions security-hardening guidance: once
a workflow is pinned by SHA, a compromised upstream tag cannot silently
change what our workflows run, and Dependabot treats the trailing
# v…comment as part of the reference so it will bump both the SHA and the
comment when a new release lands.
What changed
actions/checkout@v6.0.2@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2actions/setup-python@v6@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0github/codeql-action/{init,autobuild,analyze}@v4@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.110 workflow files touched, 17 line swaps — no workflow logic changed.
Scope / what is intentionally NOT touched
.github/workflows/dummy.ymlis generated from/actions.ymlbygateway/gateway.pyand regenerated via.github/workflows/update_dummy.yml.It has its own pinning convention and any manual edits there would be
clobbered on the next regeneration.
gateway/test_out_dummy.ymland the othergateway/*.ymlfixturesare test data for the gateway generator, not real workflows.
pelican/README.md) stilluse floating tags because they are teaching material for end users, not
production workflows.
stash/{save,restore}/action.yml,allowlist-check/action.yml,pelican/action.yml) contain nouses:references to third-party actions — they are pure
shell: bashrunsteps.
Dependabot coverage
No dependabot.yml change is required. The existing
package-ecosystem: "github-actions"entry already lists/in itsdirectorieslist, which covers every workflow file under.github/workflows/. Dependabot will start proposing version bumps forthe newly-pinned references on its next scheduled run (currently a daily
cron,
15 13 * * *), and it will update both the SHA and the# v…version comment in place.
Test plan
any real workflow file — only the two
docker://…@sha256:…imagedigests in the
dummy.ymlfixture, which are already pinned theDocker way.
gh api repos/<owner>/<repo>/git/refs/tags/<tag>and cross-checked against
gh api repos/<owner>/<repo>/tagstoconfirm the tag → SHA mapping and pick the right human-readable
version for the trailing comment.
proposes a bump against one of the newly-pinned references (the
test is "did the next bump arrive with both SHA and comment
updated" — nothing action-required here, just observation).
🤖 Generated with Claude Code