diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 956c26b1a..69e9ecb8f 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.26.7@sha256:dc2521c2a906db43073b8b4d99f491b6341cf15610b6ebbab187c45153f9959e +FROM golang:1.26.8@sha256:9d2f36f06329b2a141b9db99ffa32765cf695ee57b813ca29e245e8670bcbfff # Set bash as default shell for features SHELL ["/bin/bash", "-c"] diff --git a/.devcontainer/README.md b/.devcontainer/README.md index a68edbfe0..a569db115 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -5,7 +5,7 @@ This dev container provides a complete, reproducible development environment for ## What's Included ### Development Tools -- **Go 1.26.7** - Backend development +- **Go 1.26.8** - Backend development - **Node.js 24** - Frontend development - **gopls v0.17.0** - Go language server - **Delve** - Go debugger @@ -225,7 +225,7 @@ Custom overrides: Create `.env.devcontainer` (gitignored) ## Resources - **VM Specs**: 8GB RAM, 30GB disk, 2 CPU cores -- **Base Image**: `golang:1.26.7` (Ubuntu-based) +- **Base Image**: `golang:1.26.8` (Debian-based) - **Caches**: ~2-3GB for Go modules and build artifacts ## Tips & Tricks @@ -247,7 +247,7 @@ MacBook (VS Code) dev-containers VM (Proxmox) ↓ Docker Dev Container - ├── Go 1.26.7 + tools + ├── Go 1.26.8 + tools ├── Node 24 + npm ├── Your code (/workspaces/pulse) ├── Hot reload watchers diff --git a/Dockerfile b/Dockerfile index 0f655fc3b..6b13b1598 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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.7-alpine@sha256:28d89ee9cc0ff9fec75c82ca201e6bf7fdf9a679d4b7b24dfa04f2bb766bb468 AS backend-builder +FROM --platform=linux/amd64 golang:1.26.8-alpine@sha256:ce864e7223ac17b1775e6fd0b4c0db580c2eb50e7953a427916379e4b92a1628 AS backend-builder ARG BUILD_AGENT ARG VERSION diff --git a/deploy/provider-msp/Dockerfile.control-plane b/deploy/provider-msp/Dockerfile.control-plane index 1d1066aa8..e8266365d 100644 --- a/deploy/provider-msp/Dockerfile.control-plane +++ b/deploy/provider-msp/Dockerfile.control-plane @@ -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.7-alpine@sha256:28d89ee9cc0ff9fec75c82ca201e6bf7fdf9a679d4b7b24dfa04f2bb766bb468 AS builder +FROM --platform=$BUILDPLATFORM golang:1.26.8-alpine@sha256:ce864e7223ac17b1775e6fd0b4c0db580c2eb50e7953a427916379e4b92a1628 AS builder ARG VERSION=dev ARG BUILD_TIME=unknown ARG GIT_COMMIT=unknown diff --git a/docs/release-control/v6/internal/subsystems/deployment-installability.md b/docs/release-control/v6/internal/subsystems/deployment-installability.md index 5aec02bd0..083521136 100644 --- a/docs/release-control/v6/internal/subsystems/deployment-installability.md +++ b/docs/release-control/v6/internal/subsystems/deployment-installability.md @@ -3204,15 +3204,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.7`. 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:28d89ee9cc0ff9fec75c82ca201e6bf7fdf9a679d4b7b24dfa04f2bb766bb468`; +As of 2026-09-04, the governed release floor is Go `1.26.8`, the current +supported `1.26` patch release. It retains the security corrections that made +`1.26.7` the previous floor and adds the upstream compiler, runtime, cgo, +`debug/elf`, and `os` fixes shipped in `1.26.8`. Source-built Alpine container +stages pin the Docker Official Images manifest list +`sha256:ce864e7223ac17b1775e6fd0b4c0db580c2eb50e7953a427916379e4b92a1628`; 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. +cannot silently reintroduce a superseded 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 diff --git a/go.mod b/go.mod index f54d314dd..1be695715 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/rcourtman/pulse-go-rewrite go 1.26.0 -toolchain go1.26.7 +toolchain go1.26.8 require ( github.com/IGLOU-EU/go-wildcard/v2 v2.1.1 diff --git a/scripts/.go-version b/scripts/.go-version index f88e743cd..69a767031 100644 --- a/scripts/.go-version +++ b/scripts/.go-version @@ -1 +1 @@ -go1.26.7 +go1.26.8 diff --git a/scripts/build-release-binaries.sh b/scripts/build-release-binaries.sh index a098198bb..6218b9808 100755 --- a/scripts/build-release-binaries.sh +++ b/scripts/build-release-binaries.sh @@ -44,7 +44,7 @@ case "${OUTPUT_ROOT}" in ;; esac -required_go="go1.26.7" +required_go="go1.26.8" 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 diff --git a/scripts/build-release.sh b/scripts/build-release.sh index dc5c97e21..e88c5bc0f 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -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.7" +required_go="go1.26.8" current_go="$(go env GOVERSION 2>/dev/null || true)" if [[ "${PULSE_SKIP_GO_VERSION_CHECK:-false}" != "true" ]]; then if [[ "${current_go}" != "${required_go}" ]]; then diff --git a/scripts/build-secure-runtime-qualification.sh b/scripts/build-secure-runtime-qualification.sh index 53e448d4b..7ce60a1bf 100755 --- a/scripts/build-secure-runtime-qualification.sh +++ b/scripts/build-secure-runtime-qualification.sh @@ -35,7 +35,7 @@ if [[ -z "${PULSE_UPDATE_SIGNING_PUBLIC_KEY:-}" ]]; then exit 3 fi -required_go="go1.26.7" +required_go="go1.26.8" go_version="$(go env GOVERSION 2>/dev/null || true)" if [[ "${go_version}" != "${required_go}" ]]; then echo "Error: Go toolchain must be ${required_go} (got ${go_version:-unknown})." >&2 diff --git a/scripts/install-go-toolchain.sh b/scripts/install-go-toolchain.sh index b80d77529..9d79bcec1 100755 --- a/scripts/install-go-toolchain.sh +++ b/scripts/install-go-toolchain.sh @@ -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.7" +DEFAULT_VERSION="go1.26.8" TARGET_ROOT="/opt/toolchains/go" DOWNLOAD_ROOT="https://dl.google.com/go" GOPATH_DIR="/var/lib/pulse/go" diff --git a/scripts/installtests/build_release_assets_test.go b/scripts/installtests/build_release_assets_test.go index 5ff1be820..41d8702af 100644 --- a/scripts/installtests/build_release_assets_test.go +++ b/scripts/installtests/build_release_assets_test.go @@ -1606,7 +1606,7 @@ func TestDockerBuildUsesCanonicalReleaseLdflags(t *testing.T) { dockerfile := string(dockerfileBytes) dockerRequired := []string{ `FROM --platform=linux/amd64 node:24-alpine@sha256:`, - `FROM --platform=linux/amd64 golang:1.26.7-alpine@sha256:`, + `FROM --platform=linux/amd64 golang:1.26.8-alpine@sha256:`, `FROM backend-builder AS release-assets-builder`, `AS agent_runtime`, `AS pulse-runtime-foundation`, @@ -1641,7 +1641,7 @@ func TestDockerBuildUsesCanonicalReleaseLdflags(t *testing.T) { } } assertDigestPinnedDockerStage(t, dockerfile, `FROM --platform=linux/amd64 node:24-alpine@sha256:`, ` AS frontend-builder`) - assertDigestPinnedDockerStage(t, dockerfile, `FROM --platform=linux/amd64 golang:1.26.7-alpine@sha256:`, ` AS backend-builder`) + assertDigestPinnedDockerStage(t, dockerfile, `FROM --platform=linux/amd64 golang:1.26.8-alpine@sha256:`, ` AS backend-builder`) assertDigestPinnedDockerStage(t, dockerfile, `FROM alpine:3.24@sha256:`, ` AS agent_runtime`) assertDigestPinnedDockerStage(t, dockerfile, `FROM alpine:3.24@sha256:`, ` AS pulse-runtime-foundation`) hostedStart := strings.Index(dockerfile, `FROM pulse-runtime-base AS hosted_runtime`) @@ -1654,7 +1654,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:24-alpine AS frontend-builder`) || - strings.Contains(dockerfile, `FROM --platform=linux/amd64 golang:1.26.7-alpine AS backend-builder`) || + strings.Contains(dockerfile, `FROM --platform=linux/amd64 golang:1.26.8-alpine AS backend-builder`) || strings.Contains(dockerfile, `FROM alpine:3.24 AS agent_runtime`) || strings.Contains(dockerfile, `FROM alpine:3.24 AS pulse-runtime-base`) { t.Fatal("Dockerfile base images must be pinned by immutable @sha256 digests") @@ -2829,7 +2829,10 @@ func TestReleaseAssetCommonRunsUpdateKeyThroughModulePath(t *testing.T) { t.Skip("go not installed") } - cmd := exec.Command("bash", "-lc", "source ./scripts/release_asset_common.sh; pulse_release_go_run_update_key") + // Keep the toolchain selected by the test runner. A login shell may source a + // developer's stale mise/asdf profile and replace setup-go's release + // toolchain while leaving its GOROOT behind. + cmd := exec.Command("bash", "-c", "source ./scripts/release_asset_common.sh; pulse_release_go_run_update_key") cmd.Dir = repoFile() output, err := cmd.CombinedOutput() if err == nil { @@ -2861,7 +2864,7 @@ func TestReleaseAssetCommonRejectsUnexpectedUpdateSigningPublicKey(t *testing.T) t.Fatalf("generate unexpected public key: %v", err) } - cmd := exec.Command("bash", "-lc", "source ./scripts/release_asset_common.sh; pulse_release_prepare_signing_state pulse-installer pulse-install") + cmd := exec.Command("bash", "-c", "source ./scripts/release_asset_common.sh; pulse_release_prepare_signing_state pulse-installer pulse-install") cmd.Dir = repoFile() cmd.Env = append(os.Environ(), "PULSE_UPDATE_SIGNING_KEY="+base64.StdEncoding.EncodeToString(privateKey), diff --git a/scripts/installtests/integration_container_test.go b/scripts/installtests/integration_container_test.go index 32188ce07..f51a8285c 100644 --- a/scripts/installtests/integration_container_test.go +++ b/scripts/installtests/integration_container_test.go @@ -13,7 +13,7 @@ func TestIntegrationContainersUseGovernedImmutableBases(t *testing.T) { t.Fatalf("read mock GitHub Dockerfile: %v", err) } dockerfile := string(dockerfileBytes) - assertDigestPinnedDockerStage(t, dockerfile, `FROM golang:1.26.7-alpine@sha256:`, ` AS builder`) + assertDigestPinnedDockerStage(t, dockerfile, `FROM golang:1.26.8-alpine@sha256:`, ` AS builder`) assertDigestPinnedDockerStage(t, dockerfile, `FROM alpine:3.24@sha256:`, ``) composeBytes, err := os.ReadFile(repoFile("tests", "integration", "docker-compose.test.yml")) diff --git a/scripts/installtests/provider_msp_deploy_test.go b/scripts/installtests/provider_msp_deploy_test.go index f3b23ed33..e53cace76 100644 --- a/scripts/installtests/provider_msp_deploy_test.go +++ b/scripts/installtests/provider_msp_deploy_test.go @@ -306,7 +306,7 @@ func TestProviderMSPControlPlaneDockerfileBuildsReleaseLicenseBinary(t *testing. "FROM --platform=linux/amd64 node:24-alpine@sha256:", "npm ci", "npm run build", - "FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine@sha256:", + "FROM --platform=$BUILDPLATFORM golang:1.26.8-alpine@sha256:", "FROM alpine:3.24@sha256:", "ARG PULSE_LICENSE_PUBLIC_KEY_SHA256", "ARG TARGETOS", @@ -333,7 +333,7 @@ func TestProviderMSPControlPlaneDockerfileBuildsReleaseLicenseBinary(t *testing. "CGO_ENABLED=0 go build -o /pulse-control-plane ./cmd/pulse-control-plane", ) assertDigestPinnedDockerStage(t, text, `FROM --platform=linux/amd64 node:24-alpine@sha256:`, ` AS frontend-builder`) - assertDigestPinnedDockerStage(t, text, `FROM --platform=$BUILDPLATFORM golang:1.26.7-alpine@sha256:`, ` AS builder`) + assertDigestPinnedDockerStage(t, text, `FROM --platform=$BUILDPLATFORM golang:1.26.8-alpine@sha256:`, ` AS builder`) assertDigestPinnedDockerStage(t, text, `FROM alpine:3.24@sha256:`, ` AS control-plane-runtime-foundation`) } diff --git a/scripts/tests/test-hot-dev-runtime.sh b/scripts/tests/test-hot-dev-runtime.sh index 3315b6d49..e262e61c1 100755 --- a/scripts/tests/test-hot-dev-runtime.sh +++ b/scripts/tests/test-hot-dev-runtime.sh @@ -364,9 +364,9 @@ test_go_release_toolchain_floor() { 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.7" - assert_contains "dev toolchain installer uses the patched release toolchain" "$(<"${ROOT_DIR}/scripts/.go-version")" "go1.26.7" - assert_contains "active dev runtime resolves the patched release toolchain" "${installed_toolchain}" "go1.26.7" + assert_contains "Go module uses the patched release toolchain" "${module_toolchain}" "go1.26.8" + assert_contains "dev toolchain installer uses the patched release toolchain" "$(<"${ROOT_DIR}/scripts/.go-version")" "go1.26.8" + assert_contains "active dev runtime resolves the patched release toolchain" "${installed_toolchain}" "go1.26.8" } test_backend_race_suite_keeps_hosted_runner_timeout_headroom() { diff --git a/tests/integration/mock-github-server/Dockerfile b/tests/integration/mock-github-server/Dockerfile index 7ccc97600..43b40b209 100644 --- a/tests/integration/mock-github-server/Dockerfile +++ b/tests/integration/mock-github-server/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.26.7-alpine@sha256:28d89ee9cc0ff9fec75c82ca201e6bf7fdf9a679d4b7b24dfa04f2bb766bb468 AS builder +FROM golang:1.26.8-alpine@sha256:ce864e7223ac17b1775e6fd0b4c0db580c2eb50e7953a427916379e4b92a1628 AS builder WORKDIR /build COPY go.mod ./