build(deps): upgrade lestrrat-go/jwx v2 → v4 + Go 1.26#114
Merged
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Contributor
There was a problem hiding this comment.
Code Review
This pull request upgrades the project to Go 1.26.0 and migrates the jwx library from version 2 to version 4. The migration involves updating numerous API calls to accommodate new return signatures for standard claims (e.g., Issuer, Subject, Audience) and replacing the removed jwk.Fetch utility with manual HTTP implementations. Feedback focuses on improving the idiomatic quality of the code by using type inference for jwk.Import calls and utilizing the package-level jwt.AsMap function for more efficient claim extraction.
4 tasks
746e399 to
689f3a8
Compare
3 tasks
saucam
approved these changes
May 5, 2026
3 tasks
Migrates the entire zeroid + pkg/authjwt jwx surface (211 call sites across 19 files) to jwx v4.0.1 and bumps the language target to Go 1.26. - jwx v2 is in maintenance only; v4 is the current upstream release. - v4's API (generic Import/Get accessors, struct error types, Token getters returning (value, present)) is a forcing function for the same idioms we already prefer in newer code. - Future work like #43 (use="JWT-SVID" on JWKS) needs a more flexible verifier path; v4 narrows the migration cost when that lands. - jwa.ES256 / RS256 / HS256 are now functions; every call site adds (). - jwk.FromRaw → jwk.Import[jwk.Key] (interface-typed import returns the matching concrete jwk.Key based on the raw key shape). - jwk.Fetch + jwk.WithHTTPClient removed (companion module). Replaced with manual http.Client GET + jwk.Parse, body-bounded to 1 MiB so a malicious or compromised JWKS endpoint can't exhaust process memory. - Token accessors (Subject, Issuer, Audience, JwtID, Expiration, IssuedAt) now return (value, present); call sites destructure. - Token.Get / Token.Iterate removed → jwt.Get[T] generic accessor + Token.Keys() iteration. - jws.Headers.Algorithm() / KeyID() / Type() return (value, present). - jwt.ErrTokenExpired() etc. removed → typed structs (jwt.TokenExpiredError{}, jwt.InvalidIssuerError{}, jwt.InvalidAudienceError{}) used with errors.Is. - Go directive: 1.25.8 → 1.26 in both go.mod files. - GO_VER bumped to 1.26.0 in pr-check, release, and sdk-integration workflows; GOEXPERIMENT=jsonv2 added at the workflow env level so every step inherits it (jwx v4 requires the encoding/json/v2 stack). - Dockerfile: golang:1.25.8-alpine3.22 → golang:1.26.0-alpine3.22 + ENV GOEXPERIMENT=jsonv2 on the build stage. - Makefile: export GOEXPERIMENT=jsonv2 so every target inherits it. The jwx v4 use="JWT-SVID" path was hoped to unblock issue #43, but the filter that v2 had in jwa.AlgorithmsForKey was relocated rather than removed — v4's jws/key_provider.go::keySetProvider.selectKey (lines 115–121) hardcodes the same check that rejects keys whose use is anything outside {"", "sig"}. Comment in internal/signing/jwks.go::addToKeySet now points at the new location. Unblocking #43 still needs either an upstream jwx PR or our verifier to swap WithKeySet for manual per-kid lookup; both are out of scope for this PR. - pkg/authjwt: full suite green (race, count=1). - tests/integration: full suite green against the testcontainers Postgres fixture (60+ integration tests, count=1). - go vet ./... clean on both modules. Builds on top of #113 (PR-Z0). Once #113 merges, rebase to drop the duplicate commit and this PR rebases cleanly onto main.
rsharath
added a commit
that referenced
this pull request
May 5, 2026
…efresh
Closes the Go-ecosystem Dependabot alerts that were addressable via go get,
plus a currency refresh on the directly-used libraries that drift the most.
## Security-flagged
- uptrace/bun + dialect/pgdialect + driver/pgdriver: v1.2.11 -> v1.2.18
Closes pgdriver SQL injection (GHSA tracked by Dependabot, MEDIUM).
- go-viper/mapstructure/v2: v2.2.1 -> v2.5.0
Closes "May Leak Sensitive Information in Logs When Processing Malformed
Data" (MEDIUM, indirect via koanf).
- testcontainers-go + modules/postgres: v0.41.0 -> v0.42.0
Brings in moby/sys/* + sirupsen/logrus + gopsutil patch versions.
## Currency
- danielgtaylor/huma/v2: v2.37.2 -> v2.37.3
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc: v1.42.0 -> v1.43.0
- go.opentelemetry.io/otel/exporters/otlp/otlptrace + .../otlptracegrpc: v1.35.0 -> v1.43.0
- go.opentelemetry.io/proto/otlp: v1.9.0 -> v1.10.0
- google.golang.org/grpc: v1.79.3 -> v1.80.0
- google.golang.org/genproto/googleapis/{api,rpc}: 0209 -> 0401 snapshot
## Not addressed (known limitation)
The HIGH-severity docker/docker AuthZ-plugin-bypass advisory (>=v29.3.1)
is unactionable via go get. Moby's v29.x line uses docker-v29.x.x prefix
tags which the Go module proxy does not expose under
github.com/docker/docker; v28.5.2+incompatible is the maximum installable
version on the module path. The CVE concerns docker daemon AuthZ plugins
which we don't run -- testcontainers-go uses only the docker client to
manage test fixtures. Dependabot will continue to flag this until either
Moby republishes the v29.x line with plain v29.x.x tags or testcontainers
moves to a different docker client surface.
## Scope
- Root go.mod / go.sum only. pkg/authjwt/go.mod unchanged.
- Rebased onto current main (which now includes #114, jwx v4 + Go 1.26).
- No code changes -- pure dependency manifest update.
## Test plan
- [x] go vet ./... (root + pkg/authjwt) -- clean
- [x] Full integration suite (testcontainers Postgres) -- green ~10s
6 tasks
rsharath
added a commit
that referenced
this pull request
May 5, 2026
…efresh (#115) * build(deps): bump pgdriver, mapstructure, testcontainers + currency refresh Closes the Go-ecosystem Dependabot alerts that were addressable via go get, plus a currency refresh on the directly-used libraries that drift the most. ## Security-flagged - uptrace/bun + dialect/pgdialect + driver/pgdriver: v1.2.11 -> v1.2.18 Closes pgdriver SQL injection (GHSA tracked by Dependabot, MEDIUM). - go-viper/mapstructure/v2: v2.2.1 -> v2.5.0 Closes "May Leak Sensitive Information in Logs When Processing Malformed Data" (MEDIUM, indirect via koanf). - testcontainers-go + modules/postgres: v0.41.0 -> v0.42.0 Brings in moby/sys/* + sirupsen/logrus + gopsutil patch versions. ## Currency - danielgtaylor/huma/v2: v2.37.2 -> v2.37.3 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc: v1.42.0 -> v1.43.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace + .../otlptracegrpc: v1.35.0 -> v1.43.0 - go.opentelemetry.io/proto/otlp: v1.9.0 -> v1.10.0 - google.golang.org/grpc: v1.79.3 -> v1.80.0 - google.golang.org/genproto/googleapis/{api,rpc}: 0209 -> 0401 snapshot ## Not addressed (known limitation) The HIGH-severity docker/docker AuthZ-plugin-bypass advisory (>=v29.3.1) is unactionable via go get. Moby's v29.x line uses docker-v29.x.x prefix tags which the Go module proxy does not expose under github.com/docker/docker; v28.5.2+incompatible is the maximum installable version on the module path. The CVE concerns docker daemon AuthZ plugins which we don't run -- testcontainers-go uses only the docker client to manage test fixtures. Dependabot will continue to flag this until either Moby republishes the v29.x line with plain v29.x.x tags or testcontainers moves to a different docker client surface. ## Scope - Root go.mod / go.sum only. pkg/authjwt/go.mod unchanged. - Rebased onto current main (which now includes #114, jwx v4 + Go 1.26). - No code changes -- pure dependency manifest update. ## Test plan - [x] go vet ./... (root + pkg/authjwt) -- clean - [x] Full integration suite (testcontainers Postgres) -- green ~10s * fix: replace deprecated bun.In with bun.List for IN clause bun v1.2.18 deprecated bun.In in favor of bun.List/bun.Tuple. Inside an existing 'IN (?)' template, bun.List produces identical SQL to bun.In (comma-separated values, no surrounding parens), so this is a 1:1 mechanical swap. Resolves staticcheck SA1019 in lint-check.
rsharath
added a commit
that referenced
this pull request
May 5, 2026
…npm advisories (#117) Closes the three npm-side Dependabot alerts on cli/package-lock.json: | Severity | Package | Before -> After | Advisory | | -------- | -------- | ------------------- | ------------------------------------------ | | MEDIUM | postcss | 8.5.8 -> 8.5.14 | XSS via Unescaped </style> (GHSA-qx2v-qp2m-jg93) | | MEDIUM | vite | 5.4.21 -> 6.4.2 | Dev-server response leak (GHSA-4w7w-66w2-5vf9) | | MEDIUM | esbuild | 0.21.5 -> 0.25.12 | Dev-server CORS bypass (GHSA-67mh-4wv8-2f99) | ## Approach - vitest direct: ^2 -> ^3. vitest@3 supports vite ^5/^6/^7; the override below pins it onto v6 transitively. Smaller migration than vitest@4 (which would force a major-major jump from v2). The test surface uses only describe/it/expect/beforeEach/vi.fn -- no v3 breaking changes exercised by this CLI's 101 tests. - npm `overrides`: - `vite: ^6.4.2` -- forces vitest@3's transitive vite up from v5 to v6 (clears the vite advisory and pulls esbuild 0.25.x as a side effect). - `postcss: ^8.5.10` -- forces both tsup's and vite's transitive postcss onto a fixed line (8.5.14 ends up resolved). Without the override, tsup pins postcss@8.5.8 indirectly via postcss-load-config. esbuild needs no explicit override -- vite@6.4.2 already pulls esbuild@0.25.12, well past the 0.24.2 advisory ceiling. ## Scope - `cli/package.json` + `cli/package-lock.json` only. - No src changes -- pure build-tool dependency update. - Independent of #114 (jwx v4) and #115 (Go-side deps); both are Go-only. ## Test plan - [x] `npm install` -- clean, 0 vulnerabilities. - [x] `npm test` -- 101/101 passing (~590ms). - [x] `npm run typecheck` -- clean. - [x] `npm run build` (tsup) -- ESM + d.ts artifacts produced. - [x] `npm run lint` (eslint) -- clean. - [x] `npm audit` -- 0 vulnerabilities found.
safayavatsal
added a commit
to safayavatsal/zeroid-highflame-ai
that referenced
this pull request
May 7, 2026
Resolve conflicts and migrate the new federation code to jwx v4 (per main PR highflame-ai#114, which upgraded the rest of the codebase). - config.go: keep both validation additions — wimse_domain (from main) runs before the external_issuers loop (this PR). - zeroid.yaml: keep both new top-level sections — attestation (from main) followed by the commented external_issuers example. - internal/service/oauth_external_idp.go: migrate from jwx/v2 to jwx/v4. Token.Issuer/IssuedAt are now (T, bool) tuples; AsMap dropped, use Claims() iter.Seq2. Replace jws.Parse-based alg gate with internal/jwtalg.Validate (also covers JWT-SVID alg allow-list) plus a small base64 header decoder for kid/alg lookup. - internal/service/external_issuer_registry_test.go: jwk.FromRaw → jwk.Import[jwk.Key]; jwa.ES256 → jwa.ES256().
11 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates the entire zeroid +
pkg/authjwtjwx surface fromlestrrat-go/jwxv2 → v4.0.1 and bumps the Go toolchain from 1.25.8 → 1.26 (withGOEXPERIMENT=jsonv2, which jwx v4 requires). Pure library-currency upgrade — does not change any wire behavior; published JWKS, issued tokens, and verification semantics are byte-identical to before.Why now
jwk.Import[T]/jwt.Get[T]accessors, structured error types (TokenExpiredError,InvalidIssuerError,InvalidAudienceError) usable witherrors.Is, tuple-returning standard accessors that surface "claim absent" without sentinels.Token.Claims() iter.Seq2[string, any]lets us drop theToken.Keys()+jwt.Get[any]loop in two spots.jwk.FromRaw,jwk.Fetch,jwk.WithHTTPClient,Token.Get,jwt.ErrTokenExpired()etc. are all gone.What this PR does NOT do
It is not a fix for #43 (
use="JWT-SVID"on the published JWKS). Theusefilter that blocked us in v2 (jwa.AlgorithmsForKey) was relocated in v4 tojws/key_provider.go::keySetProvider.selectKey:115-121— same hardcoded check that rejects keys whoseuseis anything outside{"", "sig"}. v4.0.1's release notes lean stricter onuseenforcement, not looser (e.g.#2059rejectsuse=encin jkuProvider).Closing #43 needs either:
jws.WithKeySetfor manual per-kidresolution +jws.WithKey(alg, key), orThe new comment in
internal/signing/jwks.go::addToKeySetpoints at the v4 location of the filter so whichever approach is picked has a clean starting point.Mechanical migration
jwa.ES256/RS256/HS256value →jwa.ES256()/RS256()/HS256()function calljwk.FromRaw(raw)→jwk.Import[jwk.Key](raw)(interface-typed import; dispatcher chooses concrete type from raw key's Go type)jwk.Fetch + jwk.WithHTTPClient(removed) → manualhttp.Client.Do+jwk.Parse(body), body-bounded to 1 MiB so a malicious or compromised JWKS endpoint can't exhaust process memoryToken.Subject() / Issuer() / Audience() / IssuedAt() / Expiration() / JwtID()→ all return(value, present); call sites destructure with, _when the bool isn't neededToken.Get(name) / Iterate(ctx)(removed) →jwt.Get[T](token, name)for typed access;Token.Claims() iter.Seq2[string, any]for full-claim iteration ininternal/attestation/oidc.goandpkg/authjwt/claims.gojws.Headers.Algorithm() / KeyID() / Type()→(value, present)tuplejwt.ErrTokenExpired() / ErrInvalidIssuer() / ErrInvalidAudience()(function sentinels) →jwt.TokenExpiredError{} / InvalidIssuerError{} / InvalidAudienceError{}typed structs, used witherrors.Isjwk.Set.Key(i) string→(jwk.Key, bool);key.KeyID() / KeyUsage()→(string, bool)All 60+ call sites verified against pkg.go.dev v4.0.1 docs.
Build infra
go.mod,pkg/authjwt/go.modgo 1.25.8→go 1.26;lestrrat-go/jwx/v2 v2.1.6→v4 v4.0.1Dockerfilegolang:1.25.8-alpine3.22→golang:1.26.0-alpine3.22;ENV GOEXPERIMENT=jsonv2on the build stageMakefileexport GOEXPERIMENT = jsonv2at the top so every recipe inherits it.github/workflows/pr-check.ymlGO_VER: "1.25.8"→"1.26.0"; new workflow-levelGOEXPERIMENT: "jsonv2";golangci-lintbumped fromv2.7.2→v2.11.4(older was built with Go 1.25 and couldn't load Go 1.26 modules).github/workflows/release.ymlGO_VER+GOEXPERIMENTupdates.github/workflows/sdk-integration.ymlGO_VER+GOEXPERIMENTupdatesFiles changed (26)
Dockerfile,Makefile,.github/workflows/{pr-check,release,sdk-integration}.yml,go.mod,go.sum,pkg/authjwt/go.{mod,sum}internal/service/{credential,proof}.go,internal/signing/jwks.gojwa.ES256()/RS256(),jwk.Import[jwk.Key], kid+typ JOSE headers preserved on both issuance paths (community #104 work in v4 syntax)internal/middleware/agent_auth.go,internal/service/{authcode,oauth,proof}.go,internal/handler/{proof,wellknown}.goSubject/Issuer/JwtID/Expiration/IssuedAt/Audience;jwt.Get[T]replacesToken.Getinternal/attestation/oidc.gohttp.Client.Do+jwk.Parse) replaces removedjwk.Fetch/WithHTTPClient;Token.Claims()iterator replacesToken.AsMappkg/authjwtclaims.go,jwks.go,verifier.go,verifier_test.gojwt.Get[T]accessors, structured error types,Token.Claims()iterator forCustomcollection, manual JWKS fetch with body bound, alg-confusion test assertions updated to track community PR #103'svalidateAlgerror path (ErrInvalidToken)tests/integration/{attestation_oidc_test.go,authorization_code_test.go,helpers_test.go,jwt_svid_aud_test.go}jwk.Import[jwk.Key],jwa.X()calls, tuple destructuring on accessorsTest plan
go vet ./...— clean (root +pkg/authjwt)golangci-lint run(v2.11.4, matching CI) — 0 issues on both modulespkg/authjwttest suite — green, ~1.2stests/integration(testcontainers Postgres) — green, ~9.7smake test— green, 60.2s, no race detector flagshighflame-regression-test— green on CIhighflame-docker-check(Docker build with Go 1.26 + jsonv2) — green on CIhighflame-sast-check,highflame-trivy-check, Socket Security — green on CI10/10 CI checks green.
Risk / compatibility
use="sig"; issued tokens have the same claims, header shape, and signature schemes; verification accepts the same input set as before. Anything reading our tokens or JWKS today continues to work identically.pkg/authjwt.Verifier,VerifierConfig,NewVerifier,Claimsstruct, error sentinels (ErrNoToken,ErrInvalidToken,ErrExpiredToken, …) all unchanged.GOEXPERIMENT=jsonv2requirement is the one operational change. Wired into Makefile, Dockerfile, and all CI workflows. Local devs will need it set on any directgo test/go buildinvocation; documenting in the next iteration ofCONTRIBUTING.mdis a small follow-up.mainas a single commit. An earlier iteration stacked on#113(which carried preliminarytyp:JWT+ algorithm-allowlist work), but#113was closed in favor of community PRs#103and#104which shipped equivalent fixes with broader file coverage. After those merged tomainon 2026-05-04, this branch was rebased directly ontomainto drop the now-redundant earlier commit.Review notes
Six Gemini review comments are on this PR — five claiming
jwk.Import[jwk.Key]won't compile (it does; verified againstpkg/mod/.../jwk/jwk.go:82and pkg.go.dev v4.0.1 docs) and one claimingjwt.AsMapis a v4 package-level function (it isn't;grep -rn AsMapof the v4.0.1 source returns zero matches; pkg.go.dev v4.0.1 jwt page contains no such symbol). Each is rebutted in-thread with the official docs reference.