Skip to content

build: the toolchain floor moves to Go 1.27.1, and so does what it reports (ADR 0086) - #129

Merged
kfeofantov merged 1 commit into
mainfrom
build/go-1.27
Sep 18, 2026
Merged

kfeofantov merged 1 commit into
mainfrom
build/go-1.27

Conversation

@kfeofantov

Copy link
Copy Markdown
Contributor

Replaces #128. Dependabot proposed the same bump; this takes it deliberately, with the review a minor Go release needs.

Why the bot's PR could not merge

The guard from #127 caught it: go.mod said 1.26.7, the build image said 1.27.1. CI's setup-go reads go-version-file: go.mod, so make vulncheck would have been inspecting a standard library the released image does not contain — exactly what ADR 0038 §3 called one fact in two files.

What a minor release changes for this agent

This agent reports GODEBUG defaults out of other people's binaries (ADR 0050, ADR 0081), and a minor release is when that vocabulary moves. Measured on go1.27.1 against go1.26.7, it moved in both directions.

One name joins the allow-list. fips140ems — new in 1.27, backported to 1.26.6 — has no version-dependent default, so it reaches a binary only because someone wrote a //go:debug line. What that line turns off is in the toolchain's own doc/godebug.md: the enforcement of extended master secret in FIPS 140-3 mode. It passes both of ADR 0081's tests, including §1's point that a directive is a decision while a lagging default is only a lag. Measured, not assumed:

go 1.27 module + //go:debug fips140ems=0  →  DefaultGODEBUG=execerrdot=1,fips140ems=0

Four names stay although Go removed them. tls10server, tls3des, tlsrsakex, tlsunsafeekm are in 1.27's new Removed list — using an old value is now a build error. They stay on ours: the list describes binaries in a customer's cluster, which were built by every toolchain rather than by ours. An image built last year with Go 1.25 still carries tls10server=1, and that is still the fact worth reporting. A test pins this so a later tidy-up does not blind the agent to old builds.

Two arrivals stay off. tracebacklabels governs what a traceback prints. x509sslcertoverrideplatform applies only to Windows and Darwin, and its old value is the stricter one — its presence in a Linux container's build would mean nothing we could report honestly.

Two tools moved with the floor

golangci-lint v2.11.4 is built with Go 1.26 and refuses a module targeting 1.27 before reading its configuration — a hard stop, not a finding. The pin moves to v2.13.2, whose published binary is built with go1.27.0 (verified by go version -m on the release asset).

That version then reported something worth the slice on its own: ecdsa.PublicKey's X and Y have been deprecated since Go 1.26, and internal/nodeauth built every JWKS key by assigning them. It now assembles the uncompressed point and calls ecdsa.ParseUncompressedPublicKey, which rejects a point that is not on the curve. The comment that stood there — that an off-curve point cannot verify a signature anyway — was true and is no longer the argument: a JWKS entry that cannot be a key is refused where it is read.

Its other finding is a false one and only off Linux: where startCapture is a stub that always fails, err != nil is always true. CI lints the Linux build, where it is not.

Evidence

go test -race ./...                        # all packages
golangci-lint run (v2.13.2, GOOS=linux)    # 0 issues
make vulncheck                             # 0 reachable, 3 uncalled (ADR 0038 §2)
make chart-lint                            # three profiles
make image-scan                            # image binary is go1.27.1, -trimpath, 0 findings
TestGoInventoryEndToEnd                     # PASS 727s in kind — real projected tokens
                                            # through the JWKS path this PR touches

One thing found and not fixed here

make identity-e2e fails on main today, before this change. A control run of the same test against an image built from b495a1a fails identically, so it is not the toolchain. The cause is a race in the test rather than in the agent: waitDeploymentPod returns on Running, and the probe then reaches the controller through its Service, which has no endpoint until the pod is Ready — readiness means the informer caches synced (ADR 0069). Connections inside that window are refused. Worth its own PR, in the same family as #121.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KeZECJXTDHL6Nts95eKMJA

…ports (ADR 0086)

Dependabot's first Docker pull request proposed a minor Go release and the
guard held: go.mod and the build image disagreed, so CI's vulnerability gate
would have inspected a standard library the image does not contain
(ADR 0038 §3).

Moving both halves is two lines. What makes it a slice is that this agent
reports GODEBUG defaults out of other people's binaries, and a minor release is
when that vocabulary changes. Measured against go1.27.1:

- `fips140ems` is new, has no version-dependent default, and turns off the
  enforcement of extended master secret in FIPS 140-3 mode. It reaches a binary
  only because someone wrote the line, which is the class ADR 0081 §1 called
  the stronger signal. It joins the allow-list.
- Go 1.27 removed `tls10server`, `tls3des`, `tlsrsakex` and `tlsunsafeekm`.
  They stay: the binaries this reads were built by every toolchain, and an
  image built last year still carries them.
- `tracebacklabels` and `x509sslcertoverrideplatform` arrived and stay off the
  list; the ADR says why.

Two tools move with the floor. golangci-lint v2.11.4 is built with Go 1.26 and
refuses a module targeting 1.27 before reading its config, so the pin becomes
v2.13.2 — which then reports that `ecdsa.PublicKey`'s X and Y have been
deprecated since Go 1.26. internal/nodeauth now assembles the uncompressed
point and parses it, which also rejects a point that is not on the curve, so a
JWKS entry that cannot be a key is refused where it is read.

  go test -race ./... && golangci-lint run  # 0 issues, v2.13.2 on GOOS=linux
  make vulncheck                            # 0 reachable, 3 uncalled (ADR 0038 §2)
  make image-scan                           # binary is go1.27.1, 0 findings
  TestGoInventoryEndToEnd                   # PASS 727s in kind, real tokens

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeZECJXTDHL6Nts95eKMJA
@kfeofantov
kfeofantov merged commit 5b435d9 into main Sep 18, 2026
5 checks passed
@kfeofantov
kfeofantov deleted the build/go-1.27 branch September 18, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant