Split out of #1829 so that the CI unblock (#1832, a 3-line workflow bump) could land immediately while main was red and every open PR was blocked behind it.
#1832 makes CI green. It does not fix the shipped artifact. Recording that gap here rather than letting a green pipeline imply the exposure is resolved.
What is still on go1.26.5
1. The production container image (the part that actually ships)
Dockerfile:18 — FROM --platform=$BUILDPLATFORM golang:1.26.5-alpine3.24@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builder
Dockerfile.dev:8 and Dockerfile.test:8 — same base image and digest
The binary we build and deploy is therefore compiled against the go1.26.5 standard library and contains all 7 advisories from #1829: GO-2026-6218 (net/url), GO-2026-6091 (html/template), GO-2026-6090 (crypto/tls), GO-2026-6089 and GO-2026-5026 (net/http), GO-2026-6088 (encoding/xml), GO-2026-5972 (encoding/asn1).
Measured per-module on go1.26.5 with govulncheck v1.1.4 (the CI-pinned version), before #1832: root module 7 vulnerabilities, pkg 5, providers/aws 5, providers/azure 6, providers/gcp 4, tests/e2e clean. On go1.26.6 all six report No vulnerabilities found.
2. The go directives
go.work:1, go.mod:3, pkg/go.mod:3, providers/{aws,azure,gcp}/go.mod:3 are all go 1.26.5 (tests/e2e/go.mod is go 1.25).
This matters for the three workflows that use go-version-file: go.mod rather than the GO_VERSION env var: database-migration.yml (three call sites), aws_sanity.yml, azure_sanity.yml. setup-go resolves the toolchain from the go directive there, so those jobs plausibly still install 1.26.5 even after #1832. Confirm this empirically before deciding whether the directive bump is required or merely tidy; GOTOOLCHAIN=auto only ever upgrades, never downgrades, so the interaction is worth measuring rather than reasoning about.
Constraints on the fix
- Do not drop the SHA256 digest pin to make the bump easy. It exists so that a registry tag mutation cannot poison the build (Docker Hub permits re-tagging). Resolve the real digest for the new tag via
docker buildx imagetools inspect golang:1.26.6-alpine3.24 or the Docker Hub tags API. Never guess or fabricate a digest.
- Confirm an
alpine3.24 variant exists for 1.26.6 before pinning that exact tag shape. 1.26.6 is the top of the 1.26 line; there is no 1.26.7 as of filing.
- No suppression anywhere: no ignore list, no
-scan narrowing, no continue-on-error.
Verification bar
- Rebuild the image and confirm the resulting binary reports clean, rather than inferring it from the base tag alone.
- Re-run the per-module govulncheck loop and capture exit codes explicitly into variables. An empty output with a nonzero exit is a failed run, not a clean one, and
${PIPESTATUS[0]} after a subshell can silently yield an empty value.
- Watch for collateral from the directive bump:
Lint Code uses golangci-lint pinned at v2.10.1 and is toolchain-sensitive, and gosec is pinned at v2.28.0. Reproduce both at those exact versions; a newer local golangci-lint has a different bundled ruleset and gives a false exit 0.
Split out of #1829 so that the CI unblock (#1832, a 3-line workflow bump) could land immediately while
mainwas red and every open PR was blocked behind it.#1832 makes CI green. It does not fix the shipped artifact. Recording that gap here rather than letting a green pipeline imply the exposure is resolved.
What is still on go1.26.5
1. The production container image (the part that actually ships)
Dockerfile:18—FROM --platform=$BUILDPLATFORM golang:1.26.5-alpine3.24@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builderDockerfile.dev:8andDockerfile.test:8— same base image and digestThe binary we build and deploy is therefore compiled against the go1.26.5 standard library and contains all 7 advisories from #1829: GO-2026-6218 (
net/url), GO-2026-6091 (html/template), GO-2026-6090 (crypto/tls), GO-2026-6089 and GO-2026-5026 (net/http), GO-2026-6088 (encoding/xml), GO-2026-5972 (encoding/asn1).Measured per-module on go1.26.5 with govulncheck v1.1.4 (the CI-pinned version), before #1832: root module 7 vulnerabilities,
pkg5,providers/aws5,providers/azure6,providers/gcp4,tests/e2eclean. On go1.26.6 all six reportNo vulnerabilities found.2. The
godirectivesgo.work:1,go.mod:3,pkg/go.mod:3,providers/{aws,azure,gcp}/go.mod:3are allgo 1.26.5(tests/e2e/go.modisgo 1.25).This matters for the three workflows that use
go-version-file: go.modrather than theGO_VERSIONenv var:database-migration.yml(three call sites),aws_sanity.yml,azure_sanity.yml.setup-goresolves the toolchain from thegodirective there, so those jobs plausibly still install 1.26.5 even after #1832. Confirm this empirically before deciding whether the directive bump is required or merely tidy;GOTOOLCHAIN=autoonly ever upgrades, never downgrades, so the interaction is worth measuring rather than reasoning about.Constraints on the fix
docker buildx imagetools inspect golang:1.26.6-alpine3.24or the Docker Hub tags API. Never guess or fabricate a digest.alpine3.24variant exists for 1.26.6 before pinning that exact tag shape.1.26.6is the top of the 1.26 line; there is no 1.26.7 as of filing.-scannarrowing, nocontinue-on-error.Verification bar
${PIPESTATUS[0]}after a subshell can silently yield an empty value.Lint Codeuses golangci-lint pinned at v2.10.1 and is toolchain-sensitive, andgosecis pinned at v2.28.0. Reproduce both at those exact versions; a newer local golangci-lint has a different bundled ruleset and gives a false exit 0.