security(build): upgrade release toolchain to Go 1.26.6

Advance local, release, and container build surfaces together so reachable standard-library advisories cannot re-enter shipped binaries. Pin the official amd64 builder manifest and govern the updated floor with installability and dev-runtime proofs.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-08-27 04:23:56 +01:00
parent 1dc5ee4942
commit 5859f49817
11 changed files with 30 additions and 10 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ RUN --mount=type=cache,id=pulse-npm-cache,target=/root/.npm \
# Build stage for Go backend
# Force amd64 platform - Go cross-compiles for all targets anyway,
# and this avoids slow QEMU emulation during multi-arch builds
FROM --platform=linux/amd64 golang:1.26.5-alpine@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS backend-builder
FROM --platform=linux/amd64 golang:1.26.6-alpine@sha256:1a9c10cf505a9e6b1e96ea77ebdbfe79a0f10380181faf88bc3b51d7e4315fae AS backend-builder
ARG BUILD_AGENT
ARG VERSION
+1 -1
View File
@@ -12,7 +12,7 @@ COPY SECURITY.md TERMS.md /app/
RUN --mount=type=cache,id=pulse-control-plane-npm-cache,target=/root/.npm \
npm run build
FROM --platform=$BUILDPLATFORM golang:1.26.5-alpine@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builder
FROM --platform=$BUILDPLATFORM golang:1.26.6-alpine@sha256:1a9c10cf505a9e6b1e96ea77ebdbfe79a0f10380181faf88bc3b51d7e4315fae AS builder
ARG VERSION=dev
ARG BUILD_TIME=unknown
ARG GIT_COMMIT=unknown
@@ -2372,6 +2372,15 @@ vulnerabilities in the current patch level, the canonical fix is to advance the
governed release toolchain and immutable Go builder digest together, not to
suppress the scanner or produce release artifacts with an older patched-over
runtime.
As of 2026-08-27, the governed release floor is Go `1.26.6`. It supersedes
`1.26.5`, whose standard library is reachable through seven vulnerable Pulse
call paths reported by `govulncheck`, including HTTP/TLS, URL parsing, SAML XML
decoding, HTML templating, and public-key parsing. Both source-built container
stages pin the Docker Official Images Linux amd64 manifest
`sha256:1a9c10cf505a9e6b1e96ea77ebdbfe79a0f10380181faf88bc3b51d7e4315fae`;
the checked-in toolchain files and release-script guards must reject an older
compiler so local, exact-candidate, provider control-plane, and container builds
cannot silently reintroduce the vulnerable runtime.
That same dev-runtime dependency-manifest boundary now also owns the maintained
Docker engine module floor. `go.mod`, `go.sum`, and
`internal/cloudcp/docker/manager.go` must route hosted runtime orchestration
+1 -1
View File
@@ -2,7 +2,7 @@ module github.com/rcourtman/pulse-go-rewrite
go 1.26.0
toolchain go1.26.5
toolchain go1.26.6
require (
github.com/IGLOU-EU/go-wildcard/v2 v2.1.1
+1 -1
View File
@@ -1 +1 @@
go1.26.5
go1.26.6
+1 -1
View File
@@ -44,7 +44,7 @@ case "${OUTPUT_ROOT}" in
;;
esac
required_go="go1.26.5"
required_go="go1.26.6"
current_go="$(go env GOVERSION 2>/dev/null || true)"
if [[ "${current_go}" != "${required_go}" ]]; then
echo "Error: Go toolchain must be ${required_go} (got ${current_go:-unknown})." >&2
+1 -1
View File
@@ -20,7 +20,7 @@ if [ -x /usr/local/go/bin/go ]; then
fi
# Release artifacts must be built with the vetted toolchain to match security-gate evidence.
required_go="go1.26.5"
required_go="go1.26.6"
current_go="$(go env GOVERSION 2>/dev/null || true)"
if [[ "${PULSE_SKIP_GO_VERSION_CHECK:-false}" != "true" ]]; then
if [[ "${current_go}" != "${required_go}" ]]; then
+1 -1
View File
@@ -3,7 +3,7 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VERSION_FILE="${SCRIPT_DIR}/.go-version"
DEFAULT_VERSION="go1.26.5"
DEFAULT_VERSION="go1.26.6"
TARGET_ROOT="/opt/toolchains/go"
DOWNLOAD_ROOT="https://dl.google.com/go"
GOPATH_DIR="/var/lib/pulse/go"
@@ -1175,7 +1175,7 @@ func TestDockerBuildUsesCanonicalReleaseLdflags(t *testing.T) {
dockerfile := string(dockerfileBytes)
dockerRequired := []string{
`FROM --platform=linux/amd64 node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS frontend-builder`,
`FROM --platform=linux/amd64 golang:1.26.5-alpine@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS backend-builder`,
`FROM --platform=linux/amd64 golang:1.26.6-alpine@sha256:1a9c10cf505a9e6b1e96ea77ebdbfe79a0f10380181faf88bc3b51d7e4315fae AS backend-builder`,
`FROM backend-builder AS release-assets-builder`,
`FROM alpine:3.20@sha256:d9e853e87e55526f6b2917df91a2115c36dd7c696a35be12163d44e6e2a4b6bc AS agent_runtime`,
`FROM alpine:3.20@sha256:d9e853e87e55526f6b2917df91a2115c36dd7c696a35be12163d44e6e2a4b6bc AS pulse-runtime-foundation`,
@@ -1219,7 +1219,7 @@ func TestDockerBuildUsesCanonicalReleaseLdflags(t *testing.T) {
t.Fatalf("hosted_runtime target must not depend on installer rendering or embedded agent artifacts:\n%s", hostedStage)
}
if strings.Contains(dockerfile, `FROM --platform=linux/amd64 node:20-alpine AS frontend-builder`) ||
strings.Contains(dockerfile, `FROM --platform=linux/amd64 golang:1.26.5-alpine AS backend-builder`) ||
strings.Contains(dockerfile, `FROM --platform=linux/amd64 golang:1.26.6-alpine AS backend-builder`) ||
strings.Contains(dockerfile, `FROM alpine:3.20 AS agent_runtime`) ||
strings.Contains(dockerfile, `FROM alpine:3.20 AS pulse-runtime-base`) {
t.Fatal("Dockerfile base images must be pinned by immutable @sha256 digests")
@@ -306,7 +306,7 @@ func TestProviderMSPControlPlaneDockerfileBuildsReleaseLicenseBinary(t *testing.
"FROM --platform=linux/amd64 node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS frontend-builder",
"npm ci",
"npm run build",
"FROM --platform=$BUILDPLATFORM golang:1.26.5-alpine@sha256:0178a641fbb4858c5f1b48e34bdaabe0350a330a1b1149aabd498d0699ff5fb2 AS builder",
"FROM --platform=$BUILDPLATFORM golang:1.26.6-alpine@sha256:1a9c10cf505a9e6b1e96ea77ebdbfe79a0f10380181faf88bc3b51d7e4315fae AS builder",
"FROM alpine:3.20@sha256:d9e853e87e55526f6b2917df91a2115c36dd7c696a35be12163d44e6e2a4b6bc",
"ARG PULSE_LICENSE_PUBLIC_KEY_SHA256",
"ARG TARGETOS",
+11
View File
@@ -334,6 +334,16 @@ test_go_module_security_dependency_floors() {
assert_contains "Go module floor keeps x/sys aligned with security module graph" "${output}" "golang.org/x/sys v0.47.0"
}
test_go_release_toolchain_floor() {
local module_toolchain installed_toolchain
module_toolchain="$(sed -n 's/^toolchain //p' "${ROOT_DIR}/go.mod")"
installed_toolchain="$(cd "${ROOT_DIR}" && go env GOVERSION)"
assert_contains "Go module uses the patched release toolchain" "${module_toolchain}" "go1.26.6"
assert_contains "dev toolchain installer uses the patched release toolchain" "$(<"${ROOT_DIR}/scripts/.go-version")" "go1.26.6"
assert_contains "active dev runtime resolves the patched release toolchain" "${installed_toolchain}" "go1.26.6"
}
test_backend_race_suite_keeps_hosted_runner_timeout_headroom() {
local output
output="$(sed -n '1,125p' "${MAKEFILE}")"
@@ -355,6 +365,7 @@ test_hot_dev_lab_agent_mode_enables_lan_and_guest_docker_inventory_defaults
test_hot_dev_remembers_explicit_lab_agent_mode_for_later_managed_starts
test_hot_dev_browser_urls_distinguish_bind_and_browser_hosts
test_go_module_security_dependency_floors
test_go_release_toolchain_floor
test_backend_race_suite_keeps_hosted_runner_timeout_headroom
if (( failures > 0 )); then