Skip to content

chore(ci): pin every action to a commit SHA - #794

Open
rustytrees wants to merge 1 commit into
indaco:mainfrom
rustytrees:chore/pin-actions-to-shas
Open

chore(ci): pin every action to a commit SHA#794
rustytrees wants to merge 1 commit into
indaco:mainfrom
rustytrees:chore/pin-actions-to-shas

Conversation

@rustytrees

Copy link
Copy Markdown

Last slice of #789, and the only one that isn't a code change.

The release workflow's own permissions are already done properly — permissions: {} at the top of the file, per-job grants, id-token: write only on the job that needs it for cosign. But every uses: resolved through a mutable ref, and dtolnay/rust-toolchain@stable is a branch, which moves by design.

That is the weak edge of the signing story rather than a bug. A compromised third-party action runs inside the job that produces the artifact, before cosign signs it, so the signature comes out perfectly valid over malicious output. The README's claim that "a leaked GitHub token is not enough to ship a malicious binary" is true of the token, and pinning is what makes it true of the toolchain around it.

All 31 refs across the six workflows now name a commit SHA, with the previous tag kept as a trailing comment so Dependabot still recognises them (actions/checkout@3d3c42e… # v7) and the intended version stays readable at a glance.

SHAs were resolved from each action's published tag at the time of writing:

action ref sha
actions/checkout v7 3d3c42e5aac5ba805825da76410c181273ba90b1
actions/download-artifact v8 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c
actions/setup-go v6 924ae3a1cded613372ab5595356fb5720e22ba16
actions/upload-artifact v7 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
codecov/codecov-action v7 fb8b3582c8e4def4969c97caa2f19720cb33a72f
dtolnay/rust-toolchain stable 4cda84d5c5c54efe2404f9d843567869ab1699d4
goreleaser/goreleaser-action v7 f06c13b6b1a9625abc9e6e439d9c05a8f2190e94
mlugg/setup-zig v2 d1434d08867e3ee9daa34448df10607b98908d29
peter-evans/create-pull-request v8 5f6978faf089d4d20b00c7766989d076bb2fc7f1
sigstore/cosign-installer v4.1.2 6f9f17788090df1f26f669e9d70d6ae9567deba6
taiki-e/install-action v2 18b1216eba7f8039b0f8d131d5473787f0edce68

Worth re-resolving these yourself before merging rather than taking my word for them — that's a one-line gh api repos/<action>/commits/<tag> --jq .sha each.

I verified mechanically that only uses: lines changed: line counts are identical per file, and indentation and list markers are preserved. Nothing else in any workflow was touched, so there is no behaviour change to test for — CI passing on this PR is the check.

The release job's own permissions are already minimal — `permissions: {}` at
the top, `id-token: write` only where cosign needs it — but every `uses:`
resolved through a mutable tag, and two of them (`dtolnay/rust-toolchain@stable`,
plus the `@vN` majors) move under the repo's feet by design.

That is the weak edge of the signing story. A compromised third-party action
runs *inside* the job that produces the artifact, before cosign signs it, so
the signature comes out valid over malicious output. The README's claim that
"a leaked GitHub token is not enough to ship a malicious binary" is true of
the token and not yet true of the toolchain around it.

All 31 refs across the six workflows now name a commit SHA with the previous
tag kept as a trailing comment, so Dependabot still recognises them and the
intended version stays readable. Only `uses:` lines changed; indentation,
list markers, and line counts are identical.

SHAs resolved from each action's published tag at the time of writing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant