diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 519c482..5028616 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,9 +81,10 @@ jobs: # whatever the runner has that day (it shipped 1.26.8 into v3.8.2, which # still carried CVE-2026-78667, -78669 and -97031), so the scan could # pass on a toolchain that still shipped the advisories below. Every - # go-version in this repo is pinned to the same patch as the toolchain - # line in go.mod. Bump them together when govulncheck fails on the - # standard library -- that is the gate doing its job. + # go-version in this repo, and the builder image in Dockerfile, is + # pinned to the same patch as the toolchain line in go.mod. Bump them + # together when govulncheck fails on the standard library -- that is the + # gate doing its job. # Known-vulnerable dependencies, and the standard library this is built # against. Nothing in CI reported either before. - name: Run govulncheck diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2a8fe..d997c01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- **The Docker image is built by the same pinned Go toolchain as the release + binaries.** `Dockerfile` used a floating `golang:1.27-alpine`, so the binary + inside `ghcr.io/cboxdk/init` was built by a different Go version than the + release assets for the same tag — v3.8.3's image carried go1.27.3 where its + release binaries carried go1.26.10. Neither was vulnerable, but a version + whose two published artifacts are built by different toolchains cannot be + audited from the pin. The builder image is now `golang:1.26.10-alpine`, in + lockstep with the `toolchain` line in `go.mod` and every `go-version` in CI; + the comments in all three places name each other so a future bump cannot + miss one. + ## [3.8.3] - 2026-10-20 ### Security diff --git a/Dockerfile b/Dockerfile index e803759..9f11ceb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,14 @@ # Build stage -FROM golang:1.27-alpine AS builder +# +# Pinned to the same Go patch as the `toolchain` line in go.mod and every +# `go-version` in CI, so the binary inside the published image is built by the +# toolchain that was scanned -- the image is a supported way to get cbox-init +# (the release notes document copying the binary out of it), so it must not be +# built by a different toolchain than the release assets. A floating +# `golang:1.27-alpine` also drifts silently: that is how v3.8.2's release +# binaries ended up on 1.26.8 carrying CVE-2026-78667, -78669 and -97031. +# Bump in lockstep with go.mod and the workflows. +FROM golang:1.26.10-alpine AS builder WORKDIR /build diff --git a/go.mod b/go.mod index b8ded77..6d4588b 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,10 @@ go 1.26.0 // CVE-2026-78669 net/http2, CVE-2026-97031 crypto/tls), so a local build on an // older 1.26.x would fail `make check` where CI (which pins 1.26.10) passes. // Bump this in lockstep with the go-version in .github/workflows/ci.yml and -// .github/workflows/release.yml when the gate next fails on the standard -// library -- the published binaries record the toolchain that built them, so -// the pin is what keeps a release scannable and auditable. +// .github/workflows/release.yml, and the builder image in Dockerfile, when the +// gate next fails on the standard library -- the published binaries record the +// toolchain that built them, so the pin is what keeps a release scannable and +// auditable. toolchain go1.26.10 require (