Skip to content

fix(agent-image): SHA-pin the publish job's third-party actions (RIG-3651) - #37

Open
rigel-mintaka wants to merge 1 commit into
forge/rig-2217-publish-on-mainfrom
forge/rig-3651-sha-pin-actions
Open

rigel-mintaka wants to merge 1 commit into
forge/rig-2217-publish-on-mainfrom
forge/rig-3651-sha-pin-actions

Conversation

@rigel-mintaka

@rigel-mintaka rigel-mintaka commented Sep 17, 2026

Copy link
Copy Markdown

This PR is part of a stack containing 2 PRs:

  1. main
  2. ci(agent-image): publish on push to main, version from flake.nix (RIG-2217) #36
  3. "fix(agent-image): SHA-pin the publish job's third-party actions (RIG-3651)" (this PR)

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. 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

@linear-code

linear-code Bot commented Sep 17, 2026

Copy link
Copy Markdown

RIG-3651

…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>
@rigel-mintaka
rigel-mintaka force-pushed the forge/rig-3651-sha-pin-actions branch from 09b1838 to c4a9041 Compare September 17, 2026 02:32
@rigel-mintaka
rigel-mintaka marked this pull request as ready for review September 17, 2026 02:43
@rigel-mintaka

Copy link
Copy Markdown
Author

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. securityscan fails on backend and docs with three Go dependency CVEs. The CVE set on this pipeline (175) is identical to the set on #36's pipeline (163) — CVE-2026-56855, CVE-2026-78662, CVE-2026-84445, with an empty set-difference in both directions. This diff touches five uses: lines in one workflow and no go.mod/go.sum, so it cannot have introduced them. Standing red tracked as RIG-2476 (upstream dep drift). Every other workflow on the pipeline is green.

Stacking: based on forge/rig-2217-publish-on-main (#36), not main, because the workflow file only exists on that branch. Per the queue's linear-stack rule the tip is #37 — bases are #36main, #37forge/rig-2217-publish-on-main.

Two things deliberately left out of this diff:

  • The doc divergence RIG-3651 also tracks (tag-trigger vs push-to-main in fork-repo-conventions.md and docs/guides/fork-repos/README.md) needs your call between three options, so it is parked on the issue rather than guessed at here.
  • Renovate automerge is on for github-actions in the inherited upstream preset (automerge: true, automergeMajor: false), which would let a future digest bump into this packages: write job land unread. Pre-existing config, filed as RIG-3860 rather than widened into this PR.

Worth knowing while reading: our self-hosted Renovate is scoped to an explicit repositories: ["RigelBuild/orion"] list, not autodiscover, so it never sees this fork and these pins are manually maintained for now. That is in the commit message.

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