fix(agent-image): SHA-pin the publish job's third-party actions (RIG-3651) - #37
rigel-mintaka wants to merge 1 commit into
Conversation
…3651) All five third-party actions in the agent-image publish job were pinned by mutable major tag. The job holds `packages: write` and the token that pushes the image every agent host in the fleet runs, so whoever controls those five tags can run code in it. A major tag is a moving pointer: `actions/checkout@v4` resolves to whatever its owner last pointed `v4` at, and nothing in this repo would notice the change. The fork's own convention already requires this. `fork-repo-conventions.md` mandates SHA-pinned third-party actions in three separate places, so the workflow was in standing violation of the record it was written against. Each pin is the commit the major tag resolved to today, annotated with the concrete release it corresponds to: actions/checkout v4 -> 11d5960a3267 (v4.4.0) docker/setup-qemu-action v3 -> c7c53464625b (v3.7.0) docker/setup-buildx-action v3 -> 8d2750c68a42 (v3.12.0) docker/login-action v3 -> c94ce9fb4685 (v3.7.0) docker/build-push-action v6 -> 10e90e3645ea (v6.19.2) No version change: every pin is the same code the workflow would have run before this commit. The trailing comments are the conventional version hint, but note that no bot currently reads them here: this fork carries upstream's `.github/renovate.json`, while our self-hosted Renovate is scoped to an explicit one-repo list (`repositories: ["RigelBuild/orion"]` in `ci/renovate/bot-config.json5`) rather than autodiscover, so it never sees this repo. Updating these pins is a manual step until the fork is onboarded. That is the cost of pinning, and it is the right trade for a job holding a registry-write token. Verified: the same regex that matches five mutable pins on the parent commit matches none here, so the zero is a real absence rather than a pattern that cannot match; the file still parses as YAML with its six steps intact; and each SHA resolves to a real commit in its upstream repository. Scoped to the action pinning only. The doc divergence this issue also tracks (tag trigger vs push-to-main) needs a decision on three options and is left untouched. Spec-impact: none. Co-authored-by: Matt Wilkinson <matt@rigel.build>
09b1838 to
c4a9041
Compare
|
Review loop all-clear: 0 high, 0 medium, 3 low (none gating). All five pins independently verified against the GitHub API — every SHA exists in the repo it is written under, every trailing version comment is truthful, and every pin is byte-identical to what its major tag resolves to today, so the "no version change" claim is literally true rather than merely plausible. CI is red, and it is not this diff. Stacking: based on Two things deliberately left out of this diff:
Worth knowing while reading: our self-hosted Renovate is scoped to an explicit |
This PR is part of a stack containing 2 PRs:
mainAll five third-party actions in the agent-image publish job were pinned by
mutable major tag. The job holds
packages: writeand the token that pushesthe image every agent host in the fleet runs, so whoever controls those five
tags can run code in it. A major tag is a moving pointer:
actions/checkout@v4resolves to whatever its owner last pointed
v4at, and nothing in this repowould notice the change.
The fork's own convention already requires this.
fork-repo-conventions.mdmandates SHA-pinned third-party actions in three separate places, so the
workflow was in standing violation of the record it was written against.
Each pin is the commit the major tag resolved to today, annotated with the
concrete release it corresponds to:
actions/checkout v4 -> 11d5960a3267 (v4.4.0)
docker/setup-qemu-action v3 -> c7c53464625b (v3.7.0)
docker/setup-buildx-action v3 -> 8d2750c68a42 (v3.12.0)
docker/login-action v3 -> c94ce9fb4685 (v3.7.0)
docker/build-push-action v6 -> 10e90e3645ea (v6.19.2)
No version change: every pin is the same code the workflow would have run
before this commit. Renovate can bump a SHA pin with the trailing comment as
its version hint, which a major tag denies it.
Verified: the same regex that matches five mutable pins on the parent commit
matches none here, so the zero is a real absence rather than a pattern that
cannot match; the file still parses as YAML with its six steps intact; and
each SHA resolves to a real commit in its upstream repository.
Scoped to the action pinning only. The doc divergence this issue also tracks
(tag trigger vs push-to-main) needs a decision on three options and is left
untouched.
Spec-impact: none.
Co-authored-by: Matt Wilkinson matt@rigel.build