nuts-foundation / nuts-foundation/nuts-node

Migrate from lestrrat-go/jwx/v2 (EOL) to v3

Open
#4,383 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dependencies
Dominant language
Go
Stars
28
Forks
23
Avg merge
1d 10h
Merged PRs (30d)
76

Description

As of v2.1.7, github.com/lestrrat-go/jwx/v2 is marked deprecated by the maintainers via Go module deprecation — the v2 series is no longer maintained. See the v2.1.7 release notes. No further bug or security fixes will land on v2.

jwx is a core JWT/JWS/JWK/crypto dependency, so staying on an unmaintained version is a security-relevant liability.

Target: v3 (not v4, for now)

We evaluated jumping straight to v4 (latest major, v4.1.0) but chose v3 (v3.1.1) as the immediate target.

Why not v4 yet — GOEXPERIMENT=jsonv2:

  • v4 hard-depends on the standard library encoding/json/v2 package (15 import sites in v4). Its MIGRATION.md lists GOEXPERIMENT=jsonv2 as a required build prerequisite.
  • In Go 1.26 (our current toolchain: go 1.26.3, Docker golang:1.26.4), json/v2 is still gated behind that experiment flag. Shipping v4 would mean setting GOEXPERIMENT=jsonv2 in the Dockerfile builder, every CI workflow, and local dev — i.e. an experimental Go feature baked into the production build of a crypto/auth-sensitive node. Not acceptable right now.
  • v4 is also two major versions away (v2 -> v3 -> v4); each hop has its own breaking changes.

Why v3 is the right step:

  • Gets us off the EOL v2 now (the actual security goal).
  • Single major-version hop, no experimental build flag, no companion-module split.
  • v3 is actively maintained (v3.1.1, not deprecated).

Revisit v4 later once json/v2 graduates out of GOEXPERIMENT (expected in a near-future Go release). At that point v3 -> v4 is largely mechanical via the jwxmigrate tool. Tracked as a follow-up.

v2 -> v3 breaking changes to handle

  • jwa.RS256 (and all algorithm constants) become function calls jwa.RS256().
  • xxx.Get(name) signature changes to Get(name, &dst) error.
  • Convenience accessors (e.g. token.Subject()) now return (T, bool) instead of T.
  • Error renames (ErrXXX() -> XXXError()); errors are now matchable via errors.Is.
  • JWS iterators removed.
  • Only known algorithm names parse by default (register others via jwa.RegisterXXX).

Scope

  • 84 Go files import github.com/lestrrat-go/jwx/v2, concentrated in crypto/ and auth/api/iam/.
  • jwx/v3 is already present as an indirect dependency in go.mod.

Work

  • Migrate imports v2 -> v3 across crypto/, auth/, test/, etc.
  • Rewrite jwa constants to function-call form and adapt Get/accessor call sites.
  • Drop the jwx/v2 requirement from go.mod once no direct importers remain.
  • Regenerate mocks / generated code as needed.
  • Full test + e2e run.
  • Land on master, andv6.2

Follow-up

  • Migrate v3 -> v4 once encoding/json/v2 is no longer behind GOEXPERIMENT.

Target branches

Apply the migration on:

  • v5.4
  • v6.2
  • master

Assisted by AI

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the migration state across crypto/, auth/, test/, and go.mod, then inspect the v5.4, v6.2, and master branches. Run the full test and end-to-end suite described in the issue to verify the completed migration. Done means the v3 migration is landed on all three target branches and the v2 requirement is removed.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
authentication, security
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.