Pin all GitHub Actions to commit SHAs#36971
Conversation
Pin all third-party GitHub Actions to their current commit SHAs for supply chain security. The tag is preserved as a comment for readability and update tracking. Co-Authored-By: Claude (Opus 4.6) <noreply@anthropic.com>
|
Why commit SHAs is more safe? |
You can move a tag but you cannot move a sha |
|
I don't think it is a right approach to hard code the commit IDs in workflow file. You can invent a wheel (or maybe there have been some wheels) to add a "workflow-lock.yaml" and store the branch/tag names & commit IDs in the lock file, and verify them. Manage them together. |
It protects from malicious tags. If such a tag is pushed to any branch on the action's repo it would compromise the action which can not happen with SHA pinning. Many repos are doing this, it's not exactly a new technique and recommended by GitHub. Even with SHA tags, actions can be compromised through their dependencies, nothing can be done about that if a action chooses to unpin their dependencies.
What's the difference from a SHA pin? |
Just like package.json and package-lock.json You can still write |
So just a indirection. Yes such a script can be written and there's probably tools on npm for this. BTW read up on attacks like https://socket.dev/blog/trivy-under-attack-again-github-actions-compromise, many open source repos are getting compromised via actions nowadays, it's a popular attack vector. |
If there is no such tool, at least, I think the AI prompt should be committed together. Otherwise, people won't know how to upgrade from Or, we maintain a "workflow-actions.yaml", and tell AI to use commit ID to update the workflow files Then AI will read workflow-actions.yaml and update all the workflow files. I think this approach is pretty simple and clear. |
|
Btw renovate can do this and keep comment for the tag, but I can't exactly set a custom bot up without access to secrets. There's a global github one and @techknowlogick mentioned working on setting it up but not sure where that ended up. Also to be clear since I looked at this for a long time. This is a theater in part. You're ensuring that the (broken package manager) will checkout the SHA for the action but there's nothing enforcing that the said action is immutable. There's no lock for the dependencies of the action so if anything that the said action uses gets compromised (be it another action, remote file it downloads or a JS package) that's going to run anyway despite the SHA pin. |
|
Yes, sha pinning with renovate will likely be the final solution. The format here is also exactly the one that renovate and other tools support. |
|
Renovate can be the final answer. And maybe it can also update something like The question is: how should renovate be used?
|
|
I would make renovate open a weekly or bi-weekly pr for maintenance updates with a possible fast-path for security updates. Definitly don't want 1 PR per update as that would be too noisy. |
Renovate usually holds the dependancies for a bit before making a PR if it can - it's configurable though. btw if by "The commit IDs can be locked (stay away from supply-chain attack)" you mean actions part then it's not really protecting against that. It only protects from the action itself being changed but not against it's dependencies. It's a mess. |
Yes that's "cooldown" and we have it configured for dependabot too: Lines 9 to 10 in c453d09 |
Yep, dependency's dependency is another topic. That's why modern package managers have their own recursion lock (go.sum, package-lock.json, etc) |
|
Yeah... don't tell github. They haven't figured that out yet :) |
Same approach as go-gitea#36971: pin every uses: ref to the full commit SHA with the version tag in a trailing comment. Adds the helpers:pinGitHubActionDigests preset so Renovate keeps future bumps in this format and converts any new tag-pinned actions automatically. DeterminateSystems/update-flake-lock previously tracked main; pinning to v28 matches what the action's release tagging promises and lets Renovate manage upgrades the same way as the others. Co-Authored-By: Claude (Opus 4.7) <noreply@anthropic.com>
|
Superseded by #37050, which includes these SHA pins (in be25801) plus the Renovate config to keep them maintained.
Comment by Claude Opus 4.7 |
Replaces Dependabot with Renovate. The new setup: - One PR per ecosystem (GitHub Actions, Go modules + Makefile go-tool pins, npm, Python via uv, Nix flake), opened weekly on Mondays with a 5-day release-age cooldown. Vulnerability PRs ship next-day via daily cron + Renovate's `vulnerabilityAlerts` schedule bypass. - All `uses:` action refs SHA-pinned with patch-level version comments (same format as #36971, which this supersedes); `helpers:pinGitHubActionDigests` keeps future bumps in that format. - `renovatebot/github-action` runtime image pinned via the upstream-recommended `RENOVATE_VERSION` env + magic comment + `customManagers:githubActionsVersions` preset, so Renovate keeps the pin updated. - Custom regex manager tracks the `*_PACKAGE ?= <import-path>@<version>` lines in `Makefile` (golangci-lint, swagger, actionlint, etc.) and groups them into the same Go PR via `matchDatasources: ["go"]`. - Post-upgrade tasks regenerate `assets/go-licenses.json` (`make tidy`) and the SVG sprite (`make svg`), gated by an env-level command allowlist. - Replaces the standalone `cron-flake-updater` workflow — Renovate's nix manager tracks `flake.nix` inputs and produces the same `flake.lock` bump PRs on the regular weekly schedule. - npm and gomod-replace pins live in `renovate.json5` only; `updates@17.16.3` reads them from there too, so the standalone `updates.config.ts` is gone and one source of truth covers both tools. Fixes: #33386 Signed-off-by: silverwind <me@silverwind.io> Signed-off-by: TheFox0x7 <thefox0x7@gmail.com> Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com> Co-authored-by: TheFox0x7 <thefox0x7@gmail.com> Co-authored-by: Nicolas <bircni@icloud.com> Co-authored-by: Giteabot <teabot@gitea.io>
Pin all third-party GitHub Actions to their current commit SHAs for supply chain security. The tag is preserved as a comment for readability and update tracking. All 20 unique actions across 12 workflow files have been pinned and verified via
git ls-remote.This PR was authored by Claude.