diff --git a/.github/workflows/toolchain-image.yml b/.github/workflows/toolchain-image.yml index b24938d58..c280ab440 100644 --- a/.github/workflows/toolchain-image.yml +++ b/.github/workflows/toolchain-image.yml @@ -314,10 +314,26 @@ jobs: # commit when the Dockerfile pin genuinely changes. With the deterministic # build above (same key => same digest) this essentially never fires unless a # tracked pin actually moved on the PR. + # + # Hard guards (2026-09-08 incident): this job pushes to + # `github.event.pull_request.head.ref`, so it must NEVER run when that head + # is a long-lived branch. The main -> development auto-propagation PR (#1307) + # has head ref `main`; its merge ref pulls development's gRPC bump into the + # key computation, and the resulting pin got committed straight to `main`. + # `github.actor` was not the bot on that event (propagation runs under a + # human/PAT identity), so the actor guard alone did not catch it — also + # check the PR author, and refuse any protected head ref outright. A genuine + # key move on `development` is handled by `open-bump-pr` (a reviewed bot PR), + # not by this in-place sync. if: >- github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'github-actions[bot]' && + github.event.pull_request.user.login != 'github-actions[bot]' && + github.event.pull_request.head.ref != 'main' && + github.event.pull_request.head.ref != 'development' && + github.event.pull_request.head.ref != 'nightly' && + github.event.pull_request.head.ref != 'feature/beta-release' && needs.build-toolchain.outputs.digest != '' runs-on: ubuntu-latest permissions: diff --git a/Dockerfile b/Dockerfile index 987d895e6..89f0d9469 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,8 +19,8 @@ ARG CHARON_TOOLCHAIN_IMAGE=ghcr.io/wikid82/charon-toolchain # NOT Renovate-tracked (a content-hash tag has no series to follow, N7) — the # toolchain-image.yml bot owns these two lines. DIGEST is the arch-independent # manifest-list (OCI index) digest, so one pin covers linux/amd64 + linux/arm64. -ARG CHARON_TOOLCHAIN_TAG=caddy-crowdsec-9eb9862f44b9e769 -ARG CHARON_TOOLCHAIN_DIGEST=sha256:b41e571d5951bbfc3daa3dccdca033ad9dee535a8e720ac7e3b0bce338f223b2 +ARG CHARON_TOOLCHAIN_TAG=caddy-crowdsec-1efe7f19fa52a512 +ARG CHARON_TOOLCHAIN_DIGEST=sha256:6575f4c6a9f76074870c64df9dd4c9ebee812342f37f52ae5ef8f511ba9f8f00 # Stage selector — default consumes the prebuilt toolchain image (no compile). # Fork PRs / bootstrap / offline builds pass