From 2feec4b193b2674990d5caf30247abf4bd19dab1 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Tue, 14 Jul 2026 12:10:41 +0200 Subject: [PATCH] fix(ci): pin base image digests, verify tool checksums, pin claude-code version Addresses #209. All four ci/images/*/Containerfile FROM lines were tag-pinned only (alpine:3.21, node:22-alpine), letting the base silently change between builds. Pin each to its current manifest-list digest. ci/images/k8s/Containerfile downloaded talosctl, kubectl, and velero via curl with no integrity check, and installed flux via `curl | bash` (itself an unpinned, unverified fetch-and-execute). Replace the flux install with a pinned-version tarball download verified against its published sha256 checksum, same as talosctl/kubectl/velero now are. kubectl's version was also resolved dynamically from dl.k8s.io's stable.txt at build time instead of being pinned; add KUBECTL_VERSION. ci/images/tofu/Containerfile's tofu.zip download gets the same sha256 verification. ci/images/claude/Containerfile's CLAUDE_CODE_VERSION defaulted to `latest` and was never overridden by build-ci-images.yml, so the image holding repo/issue-write tokens floated to whatever npm resolved at build time. Pin it to the current release (2.1.209). Checksums and digests verified against the respective registries/release APIs at fix time (2026-07-14). Co-Authored-By: Claude Bot --- ci/images/ansible/Containerfile | 2 +- ci/images/claude/Containerfile | 4 ++-- ci/images/k8s/Containerfile | 27 ++++++++++++++++++++------- ci/images/tofu/Containerfile | 3 ++- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ci/images/ansible/Containerfile b/ci/images/ansible/Containerfile index 50ae61ea..decacc72 100644 --- a/ci/images/ansible/Containerfile +++ b/ci/images/ansible/Containerfile @@ -1,4 +1,4 @@ -FROM alpine:3.21 +FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d RUN apk add --no-cache \ ansible \ diff --git a/ci/images/claude/Containerfile b/ci/images/claude/Containerfile index 036353b9..0b2edcb2 100644 --- a/ci/images/claude/Containerfile +++ b/ci/images/claude/Containerfile @@ -1,6 +1,6 @@ -FROM node:22-alpine +FROM node:22-alpine@sha256:16e22a550f3863206a3f701448c45f7912c6896a62de43add43bb9c86130c3e2 -ARG CLAUDE_CODE_VERSION=latest +ARG CLAUDE_CODE_VERSION=2.1.209 RUN apk add --no-cache \ bash \ diff --git a/ci/images/k8s/Containerfile b/ci/images/k8s/Containerfile index dde774a2..c646bf0e 100644 --- a/ci/images/k8s/Containerfile +++ b/ci/images/k8s/Containerfile @@ -1,7 +1,9 @@ -FROM alpine:3.21 +FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d ARG TALOS_VERSION=v1.12.6 ARG VELERO_VERSION=v1.16.0 +ARG KUBECTL_VERSION=v1.36.2 +ARG FLUX_VERSION=2.9.2 RUN apk add --no-cache \ aws-cli \ @@ -16,16 +18,27 @@ RUN apk add --no-cache \ RUN curl -sfL -o /usr/local/bin/talosctl \ "https://github.com/siderolabs/talos/releases/download/${TALOS_VERSION}/talosctl-linux-amd64" \ + && echo "4c41a3b10b075292e64b182283d558e9d8e935f43239de1ed4e4b14359593efb /usr/local/bin/talosctl" | sha256sum -c - \ && chmod +x /usr/local/bin/talosctl -RUN KUBECTL_VERSION="$(curl -sfL https://dl.k8s.io/release/stable.txt)" \ - && curl -sfL -o /usr/local/bin/kubectl \ +RUN curl -sfL -o /usr/local/bin/kubectl \ "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" \ + && curl -sfL -o /tmp/kubectl.sha256 \ + "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl.sha256" \ + && echo "$(cat /tmp/kubectl.sha256) /usr/local/bin/kubectl" | sha256sum -c - \ + && rm -f /tmp/kubectl.sha256 \ && chmod +x /usr/local/bin/kubectl -RUN curl -sfL https://fluxcd.io/install.sh | bash +RUN curl -sfL -o /tmp/flux.tar.gz \ + "https://github.com/fluxcd/flux2/releases/download/v${FLUX_VERSION}/flux_${FLUX_VERSION}_linux_amd64.tar.gz" \ + && echo "4092b367fd060097976fb7261601f79420ecf7266328417dfd8dfee27de0e6a3 /tmp/flux.tar.gz" | sha256sum -c - \ + && tar -xzf /tmp/flux.tar.gz -C /usr/local/bin flux \ + && chmod +x /usr/local/bin/flux \ + && rm -f /tmp/flux.tar.gz -RUN curl -sfL "https://github.com/vmware-tanzu/velero/releases/download/${VELERO_VERSION}/velero-${VELERO_VERSION}-linux-amd64.tar.gz" \ - | tar -xz -C /tmp \ +RUN curl -sfL -o /tmp/velero.tar.gz \ + "https://github.com/velero-io/velero/releases/download/${VELERO_VERSION}/velero-${VELERO_VERSION}-linux-amd64.tar.gz" \ + && echo "b228154536d377cd6ddc271f5d6a622f1167d911ae555dd7382181d0840f6d05 /tmp/velero.tar.gz" | sha256sum -c - \ + && tar -xz -C /tmp -f /tmp/velero.tar.gz \ && install "/tmp/velero-${VELERO_VERSION}-linux-amd64/velero" /usr/local/bin/velero \ - && rm -rf "/tmp/velero-${VELERO_VERSION}-linux-amd64" + && rm -rf "/tmp/velero-${VELERO_VERSION}-linux-amd64" /tmp/velero.tar.gz diff --git a/ci/images/tofu/Containerfile b/ci/images/tofu/Containerfile index 622df363..4cfbafe0 100644 --- a/ci/images/tofu/Containerfile +++ b/ci/images/tofu/Containerfile @@ -1,4 +1,4 @@ -FROM alpine:3.21 +FROM alpine:3.21@sha256:48b0309ca019d89d40f670aa1bc06e426dc0931948452e8491e3d65087abc07d ARG TOFU_VERSION=1.11.0 @@ -19,6 +19,7 @@ RUN apk add --no-cache \ RUN curl -sfL -o /tmp/tofu.zip \ "https://github.com/opentofu/opentofu/releases/download/v${TOFU_VERSION}/tofu_${TOFU_VERSION}_linux_amd64.zip" \ + && echo "c425c2080e3f204a1fe094356777535a34c4bc9fdbca4eccb74cdd25c1ae8a94 /tmp/tofu.zip" | sha256sum -c - \ && unzip -q /tmp/tofu.zip -d /tmp/tofu \ && install /tmp/tofu/tofu /usr/local/bin/tofu \ && rm -rf /tmp/tofu /tmp/tofu.zip -- 2.54.0