ci: pin every workflow action to a commit hash - #95
Open
MajorLift wants to merge 2 commits 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.
Pinning to a hash stops a tag moving underneath us, but Dependabot still opens the bump PR the moment the tag does move — which is precisely when a compromised release is freshest and least likely to have been caught. A seven-day default lets the ecosystem find it first; the pin holds the previous hash throughout. Raised by zizmor on this PR: insufficient cooldown in Dependabot updates.
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.
Overview
Pins every external GitHub Action reference to a commit hash — 16 references across 4 workflows — plus
test/workflows.test.mjsto keep them pinned and.github/dependabot.ymlto keep them current. No behavior change: each pin is the commit its tag resolved to.Motivation
Code scanning enforces a blanket hash policy, but only against changed files — on #47 it fired on the workflow being touched and left the sixteen already in the tree unflagged.
A tag is a moving pointer, repointable with no diff or review: the shape of the
tj-actions/changed-filescompromise.Showcase
These workflows publish releases; every hash was checked by hand against the action repo, not from a script.
node --test test/workflows.test.mjs— 3 pass; every pinned SHA's commit message matches its version comment.github/dependabot.ymlis the one part nothing above covers — that it keeps hash and comment in step is unverified until a tracked tag moves.