ci: pin every workflow action to a commit hash - #95
Open
MajorLift wants to merge 1 commit into
Open
Conversation
Code scanning enforces a blanket hash policy, but only against changed files — so it fires on a workflow someone edits and stays silent on the sixteen references already here. Every action in this repo floats on a tag. A tag is a moving pointer. Whoever controls the action repo can repoint `@v3` at new code, and every workflow picks it up on the next run with no diff and no review. That is the shape of the tj-actions/changed-files compromise. A hash cannot move. All sixteen references across four workflows are pinned, each carrying its version in a trailing comment so the file stays readable. Every hash was resolved from its tag and verified against the action repo: the commit each one points at has that version as its message. Two things keep it that way. `test/workflows.test.mjs` fails on any external `uses:` that is not a 40-character hash, or any hash without a version comment — both verified to fire. And a Dependabot config, because pinning without it just freezes actions at whatever they were, security fixes included; Dependabot opens a PR when the tracked tag moves.
| # fixes included. Dependabot is what makes pinning safe rather than merely static: | ||
| # it opens a PR when the tag a pin tracks moves, keeping the trailing version | ||
| # comment and the hash in step. | ||
| - package-ecosystem: github-actions |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Code scanning enforces a blanket hash policy, but only against changed files. It fires on a workflow someone edits and stays silent on the sixteen references already here — which is how every action in this repo came to float on a tag while the policy was nominally in force. Surfaced while addressing review on #47, where the check flagged the one workflow being touched.
A tag is a moving pointer. Whoever controls the action repo can repoint
@v3at new code, and every workflow picks it up on the next run with no diff and no review. That is the shape of thetj-actions/changed-filescompromise. A hash cannot move.What changed
All 16 references across 4 workflows pinned, each carrying its version in a trailing comment so the file stays readable:
action-checkout-and-setup0543b592…action-npm-publish18df4214…action-security-code-scannerbecb2429…action-publish-releasef01f1be1…action-is-release3cd51b98…action-create-release-pr15b416cc…Every hash was resolved from its tag and verified against the action repo — the commit each points at carries that version as its message. This touches release automation, so a wrong hash would break publishing rather than fail loudly.
What keeps it that way
test/workflows.test.mjsfails on any externaluses:that is not a 40-character hash, and on any hash without a version comment. Both verified to fire against an injected regression; a third test asserts at least one external reference exists, so the first two cannot pass vacuously on an empty set..github/dependabot.yml— new. Pinning without it just freezes actions at whatever they were when someone typed them, security fixes included. Dependabot opens a PR when the tracked tag moves, keeping hash and comment in step. Weekly,cicommit prefix.Test plan
node --test test/workflows.test.mjs— 3 passuses:remains — local./.github/workflows/*references are correctly ignoredNotes
CHANGELOG.mdentry — that file tracks consumer-facing@metamask/skillschanges.