From 007829b3e66304c6878d04863ba5205d19dff215 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Sun, 16 Aug 2026 23:46:44 +0200 Subject: [PATCH 1/4] sec(build): build the shipped image on go1.26.6 to clear the stdlib CVEs #1832 bumped GO_VERSION and the pre-commit go-version pin, which turned govulncheck green in CI, but the artifact we deploy was still compiled by the go1.26.5 builder stage, so all seven stdlib advisories remained in the binary we ship. Bump the golang base image in Dockerfile (the production builder), Dockerfile.dev and Dockerfile.test from 1.26.5-alpine3.24 to 1.26.6-alpine3.24, refreshing the SHA256 digest pin rather than dropping it. The digest was resolved from the registry v2 manifest endpoint and cross-checked against docker buildx imagetools inspect. Bump the go directives in go.work and the five module go.mod files. This is load-bearing rather than tidiness: aws_sanity.yml, azure_sanity.yml and database-migration.yml resolve their toolchain via go-version-file: go.mod, and an azure_sanity run from after #1832 merged logs "Successfully set up Go version 1.26.5". No module carries a toolchain directive, so setup-go reads the go directive directly. tests/e2e/go.mod stays at go 1.25: no workflow resolves a toolchain from it, GOTOOLCHAIN=auto only ever upgrades and never downgrades, and the module is test-only, stdlib-only, and not part of the shipped artifact. --- Dockerfile | 4 ++-- Dockerfile.dev | 4 ++-- Dockerfile.test | 2 +- go.mod | 2 +- go.work | 2 +- pkg/go.mod | 2 +- providers/aws/go.mod | 2 +- providers/azure/go.mod | 2 +- providers/gcp/go.mod | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6e398cef8..73d359b6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,10 +12,10 @@ ARG TARGETOS=linux # Build stage # Image pinned to a SHA256 digest for reproducible builds — a registry # tag mutation (Docker Hub allows re-tagging) cannot poison this build. -# To refresh: `docker buildx imagetools inspect golang:1.26.5-alpine3.24` +# To refresh: `docker buildx imagetools inspect golang:1.26.6-alpine3.24` # (or use the Docker Hub API tags endpoint) and update the digest below. # A Renovate / Dependabot config can automate this if desired. -FROM --platform=$BUILDPLATFORM golang:1.26.5-alpine3.24@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builder +FROM --platform=$BUILDPLATFORM golang:1.26.6-alpine3.24@sha256:3889b425f035be855a72fb4755265311293b6d414521f0a519d819df32222d83 AS builder # Re-declare args for use in this stage ARG TARGETARCH diff --git a/Dockerfile.dev b/Dockerfile.dev index ff3ccb8fb..5537bd61a 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,11 +1,11 @@ # Development Dockerfile with hot reload using Air # Image pinned to a SHA256 digest for reproducible builds; a registry # tag mutation (Docker Hub allows re-tagging) cannot poison this build. -# To refresh: `docker buildx imagetools inspect golang:1.26.5-alpine3.24` +# To refresh: `docker buildx imagetools inspect golang:1.26.6-alpine3.24` # (or use the Docker Hub API tags endpoint) and update the digest below. # A Renovate / Dependabot config can automate this if desired. # Keep this digest in sync with the builder stage in Dockerfile. -FROM golang:1.26.5-alpine3.24@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS development +FROM golang:1.26.6-alpine3.24@sha256:3889b425f035be855a72fb4755265311293b6d414521f0a519d819df32222d83 AS development # Install development tools and Air for hot reload RUN apk add --no-cache \ diff --git a/Dockerfile.test b/Dockerfile.test index a31d233d8..d7560d01f 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -5,7 +5,7 @@ # # Base image pinned by digest for the same supply-chain reasons as Dockerfile; # keep the digest in sync with the builder stage there. -FROM golang:1.26.5-alpine3.24@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 +FROM golang:1.26.6-alpine3.24@sha256:3889b425f035be855a72fb4755265311293b6d414521f0a519d819df32222d83 # Run the suite as a non-root user (trivy DS-0002). tests/e2e is a stdlib-only # module so no module downloads are needed; GOCACHE lives in the user's home, diff --git a/go.mod b/go.mod index 1d1e06f6d..9a22638fa 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/LeanerCloud/CUDly -go 1.26.5 +go 1.26.6 require ( github.com/aws/aws-sdk-go-v2 v1.41.5 diff --git a/go.work b/go.work index 689cc213c..3b2ce4f44 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.26.5 +go 1.26.6 use ( . diff --git a/pkg/go.mod b/pkg/go.mod index 9b8192c16..565aa5de6 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -1,6 +1,6 @@ module github.com/LeanerCloud/CUDly/pkg -go 1.26.5 +go 1.26.6 // This module contains shared types, provider interfaces, and the exchange package. // The exchange package has AWS SDK dependencies for RI exchange operations. diff --git a/providers/aws/go.mod b/providers/aws/go.mod index f7e3b04bd..f46aa7b46 100644 --- a/providers/aws/go.mod +++ b/providers/aws/go.mod @@ -1,6 +1,6 @@ module github.com/LeanerCloud/CUDly/providers/aws -go 1.26.5 +go 1.26.6 require ( github.com/LeanerCloud/CUDly/pkg v0.0.0 diff --git a/providers/azure/go.mod b/providers/azure/go.mod index d85f5d4b2..fb071a2c3 100644 --- a/providers/azure/go.mod +++ b/providers/azure/go.mod @@ -1,6 +1,6 @@ module github.com/LeanerCloud/CUDly/providers/azure -go 1.26.5 +go 1.26.6 require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 diff --git a/providers/gcp/go.mod b/providers/gcp/go.mod index 1de89c80e..f7580550d 100644 --- a/providers/gcp/go.mod +++ b/providers/gcp/go.mod @@ -1,6 +1,6 @@ module github.com/LeanerCloud/CUDly/providers/gcp -go 1.26.5 +go 1.26.6 require ( cloud.google.com/go/compute v1.54.0 From 1d44eed6a1daf7c9ec6e1bb64d51e06a3978f549 Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Mon, 17 Aug 2026 01:56:13 +0200 Subject: [PATCH 2/4] sec(build): compile golang-migrate from source so the image ships one toolchain The runtime image contains two Go binaries and the base-image bump only moved one of them. /usr/local/bin/migrate was an upstream prebuilt release tarball compiled on go1.25.4, so it still carried all seven stdlib advisories from issue #1833. That binary is not dormant. scripts/entrypoint.sh runs `migrate up` on every container start and DB_AUTO_MIGRATE defaults to true in this image, and the vulnerable symbols govulncheck reports include url.URL.Parse, url.URL.ResolveReference and tls.Conn.Handshake, which are the paths that parse the database URL and negotiate TLS to the database. Build it with `go install` on the stage's pinned toolchain, the same way `make install-tools` does. Bumping the pinned release was not an option: v4.19.1 is the latest upstream tag, and the fix for the 1.25 line is go1.25.13. `go install` refuses GOBIN when cross-compiling and writes to bin/$GOOS_$GOARCH/ instead, so both layouts are resolved and the final `mv` fails the build if neither produced a binary. curl is dropped from the builder stage because the download it served is gone. Verified on full images built from this branch, both target architectures: binary arch toolchain govulncheck -mode=binary /app/cudly arm64 go1.26.6 2 vulnerabilities from 2 modules /app/cudly amd64 go1.26.6 2 vulnerabilities from 2 modules /usr/local/bin/migrate arm64 go1.26.6 No vulnerabilities found. /usr/local/bin/migrate amd64 go1.26.6 No vulnerabilities found. Stdlib advisory count is 0 on all four, counted from `-format json` by module rather than by a text pattern. The previously shipped prebuilt binary measures "69 vulnerabilities from 12 modules and the Go standard library", 35 of them stdlib. The two remaining findings on /app/cudly are pre-existing and non-stdlib (GO-2026-5158, GO-2026-5932); this commit changes no dependency. `migrate -version` still reports v4.19.1 in the final image, and a real `migrate -path /app/migrations -database postgresql://... up` reaches the TCP connect step, confirming both the file source and the postgresql driver are registered under -tags postgres. --- Dockerfile | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 73d359b6d..6512386f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,25 +33,27 @@ ARG BUILD_DATE RUN apk add --no-cache \ git \ ca-certificates \ - postgresql-client \ - curl + postgresql-client # Set shell with pipefail for safer pipe operations SHELL ["/bin/ash", "-eo", "pipefail", "-c"] -# Install golang-migrate for database migrations (architecture-aware, checksum-verified) -RUN MIGRATE_ARCH=$([ "$TARGETARCH" = "arm64" ] && echo "arm64" || echo "amd64") && \ - if [ "$MIGRATE_ARCH" = "arm64" ]; then \ - MIGRATE_SHA256="2fea2455c0f3f07cc3f4b98471c951ad1a716059574b20b6416bd1e9058751c5"; \ - else \ - MIGRATE_SHA256="2ac648fbd1b127b69ab5a7b33cf96212178f71e22379fc50573630c6f4c7ce18"; \ - fi && \ - curl -Lo migrate.tar.gz "https://github.com/golang-migrate/migrate/releases/download/v4.19.1/migrate.linux-${MIGRATE_ARCH}.tar.gz" && \ - echo "${MIGRATE_SHA256} migrate.tar.gz" | sha256sum -c - && \ - tar xzf migrate.tar.gz && \ - mv migrate /usr/local/bin/migrate && \ - chmod +x /usr/local/bin/migrate && \ - rm migrate.tar.gz +# Build golang-migrate from source on this stage's pinned Go toolchain, the same +# way `make install-tools` does. Upstream's prebuilt release tarballs carry +# whatever toolchain upstream built them with (v4.19.1 ships go1.25.4), which is +# how issue #1833's stdlib CVEs reached the runtime image, where entrypoint.sh +# runs `migrate up` against the database on every container start. +# `go install` refuses GOBIN when cross-compiling and writes to +# bin/${GOOS}_${GOARCH}/ instead, so resolve both layouts; the final `mv` fails +# the build if neither produced a binary. +# Keep this version in step with MIGRATE_VERSION in the Makefile. +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ + go install -tags=postgres -ldflags="-s -w -X main.Version=v4.19.1" \ + github.com/golang-migrate/migrate/v4/cmd/migrate@v4.19.1 && \ + GOPATH_BIN="$(go env GOPATH)/bin" && \ + MIGRATE_BIN="${GOPATH_BIN}/${TARGETOS}_${TARGETARCH}/migrate" && \ + { [ -x "${MIGRATE_BIN}" ] || MIGRATE_BIN="${GOPATH_BIN}/migrate"; } && \ + mv "${MIGRATE_BIN}" /usr/local/bin/migrate WORKDIR /app From 5a31a7be0929e304c695ca20a9f8367a200f248e Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Mon, 17 Aug 2026 01:56:54 +0200 Subject: [PATCH 3/4] ci(pre-commit): resolve the Go toolchain from go.mod instead of a hardcoded pin pre-commit.yml was the last workflow carrying a literal `go-version`. aws_sanity, azure_sanity and database-migration already use `go-version-file: go.mod`, so this removes one of the independent places the Go version had to be bumped by hand. That arrangement is what produced issue #1833: #1832 bumped some of them and CI went green while the shipped artifact stayed on the old toolchain. The root go.mod `go` directive is 1.26.6, so the resolved version is unchanged by this commit. --- .github/workflows/pre-commit.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 9a64f2490..7744f9d37 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -32,7 +32,10 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 with: - go-version: "1.26.6" + # Read from go.mod rather than a hardcoded string, matching + # aws_sanity / azure_sanity / database-migration. One fewer place the + # Go version has to be bumped by hand (issue #1833). + go-version-file: go.mod - name: Set up Node.js uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 From 78ad1bba6c734af0e6ed89a67a3cf10981f857df Mon Sep 17 00:00:00 2001 From: Cristian Magherusan-Stanciu Date: Mon, 17 Aug 2026 01:57:10 +0200 Subject: [PATCH 4/4] docs: correct Go version floors to the 1.26.6 the modules actually require The documented prerequisites had drifted well below the `go` directive in go.mod: "Go 1.23 or later" in CONTRIBUTING.md and README.md, "Go 1.25+" in README.md, docs/DEPLOYMENT.md and docs/DEVELOPMENT.md. Most concretely, CONTRIBUTING.md hands contributors a copy-paste `go.work.local` template whose first line was `go 1.25.0`. A workspace `go` line below the modules' own 1.26.6 is rejected, so following that section verbatim no longer built. It now matches the committed go.work and says why it has to. Also corrects .github/workflows/README.md, which documented the `GO_VERSION` variable default as 1.25 when ci.yml sets 1.26.6. --- .github/workflows/README.md | 2 +- CONTRIBUTING.md | 6 ++++-- README.md | 4 ++-- docs/DEPLOYMENT.md | 2 +- docs/DEVELOPMENT.md | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index de0f34067..bf781e357 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -52,7 +52,7 @@ Runs comprehensive quality checks on every pull request and push to main branch. ### Required Variables -- `GO_VERSION` (default: 1.25) +- `GO_VERSION` (default: 1.26.6) ### Example diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d1833349..491072bbd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,7 +48,7 @@ By participating in this project, you agree to maintain a respectful and inclusi ### Prerequisites -- Go 1.23 or later +- Go 1.26.6 or later (the floor set by the `go` directive in `go.mod`) - AWS/Azure/GCP credentials for integration testing - Git @@ -88,7 +88,9 @@ from a copy of the committed `go.work` and append your active worktrees: ```go // go.work.local -- gitignored, developer-local -go 1.25.0 +// Keep this `go` line at or above the modules' own directive, otherwise the +// workspace is rejected. Copy it from the committed go.work. +go 1.26.6 use ( . diff --git a/README.md b/README.md index 49e52c195..187689000 100644 --- a/README.md +++ b/README.md @@ -598,7 +598,7 @@ runtimes. - Terraform >= 1.6.0 - Docker with buildx -- Go 1.25+ +- Go 1.26.6+ - Cloud CLI authenticated: `aws`, `gcloud`, or `az` #### Quick deploy (using the helper script) @@ -682,7 +682,7 @@ reload, and debugging workflows. ### Prerequisites -- Go 1.23 or later +- Go 1.26.6 or later - AWS/Azure/GCP credentials for integration testing ### Building diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 7c94913ef..764ab5c85 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -56,7 +56,7 @@ Terraform automatically handles: Docker image build/push (via build module), fro - Docker with buildx support - Terraform >= 1.6.0 -- Go 1.25+ +- Go 1.26.6+ - Cloud CLI configured: `aws`, `az`, or `gcloud` --- diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 5d6e9ae02..3dafeaa65 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -3,7 +3,7 @@ ## Prerequisites - Docker and Docker Compose -- Go 1.25+ +- Go 1.26.6+ - Node.js and npm (for frontend development) - Make (optional, for convenience commands)