<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->
Module: `github.com/lestrrat-go/jwx/v4` — flat layout, no physical `v3/` directory.
Format detection and process-global settings (JSON decoder + base64 backend).
- **GuessFormat(payload []byte) FormatKind** — heuristic detection of JWE/JWS/JWK/JWKS/JWT
- **Settings(options ...GlobalOption)** — configure global settings (JSON, base64)
- **WithUseNumber(v bool) GlobalOption** — decode JSON numbers as `json.Number` instead of `float64`
- **WithBase64Encoder(v Base64Encoder) GlobalOption** — replace the process-global base64 encoder (default: `encoding/base64.RawURLEncoding`)
- **WithBase64Decoder(v Base64Decoder) GlobalOption** — replace the process-global base64 decoder (default: variant-detecting decoder)
- Key types: `FormatKind` (InvalidFormat, UnknownFormat, JWE, JWS, JWK, JWKS, JWT), `GlobalOption`, `Base64Encoder` (alias of `internal/base64.Encoder`), `Base64Decoder` (alias of `internal/base64.Decoder`)
- Files: `jwx.go`, `format.go`, `options.go`, `base64.go`
Algorithm identifiers per RFC 7518. Registry pattern with thread-safe lookup.
- Algorithm types: `SignatureAlgorithm`, `KeyEncryptionAlgorithm`, `ContentEncryptionAlgorithm`, `EllipticCurveAlgorithm`, `KeyType`, `CompressionAlgorithm`
- **KeyAlgorithmFrom(v any) (KeyAlgorithm, error)** — convert string/typed algorithm to union interface
- Per-type API: `New{Type}()`, `Lookup{Type}(name) (T, bool)`, `Register{Type}()`, `Unregister{Type}()`, `{Type}s() []T`
`Register{Type}()` is process-global; attempts to replace builtin identifiers such as `RS256` return an error.
- Constructor functions: `ES256()`, `RS256()`, `A128GCM()`, `P256()`, `Ed25519()`, etc.
- **MLDSA44()**, **MLDSA65()**, **MLDSA87()** — ML-DSA signature algorithms (FIPS 204). Go 1.27 and later only; `jwa/signature_go127_gen.go` is `//go:build go1.27` because `crypto/mldsa` lands in Go 1.27. Generated from the three `build_constraint: go1.27` entries in `objects.yml`, and registered as builtins from that file's `init()`.
- Files: `jwa.go` + generated `*_gen.go` (including `signature_go127_gen.go`, go1.27)
- Imports: internal/tokens
JSON Web Keys per RFC 7517. Key representation, parsing, import/export, caching.
- **Settings(options ...GlobalOption)** — configure global jwk behavior (`WithStrictKeyUsage`, RSA validation floors)
- **Parse(src []byte, ...ParseOption) (Set, error)** / **ParseKey(data []byte, ...ParseOption) (Key, error)** / **ParseKeyAs[T Key](data []byte, ...ParseOption) (T, error)** — parse JWK/JWKS; `ParseKeyAs` returns [`KeyTypeMismatchError`] on generic-type mismatch
- **Fetcher** — transport-neutral interface implemented by companion modules such as
`github.com/jwx-go/jwkfetch/v4`
- **Import[T Key](raw any) (T, error)** / **Export[T any](key Key) (T, error)** / **ExportAll[T any](set Set) ([]T, error)** — convert between Go crypto types and JWK (generic). `ExportAll` exports every key in a `Set`, preserving order; `T = any` handles heterogeneous sets.
- **PublicKeyOf(v any) (Key, error)** / **PublicSetOf(v Set, ...PublicSetOption) (Set, error)** — extract public keys. `PublicSetOf` rejects sets containing symmetric (oct) keys by default (pass `WithAllowSymmetric(true)` for legacy pass-through) and rejects sets containing `UnsupportedKey` placeholders (pass `WithOmitUnsupportedKeys(true)` to drop them).
- **AssignKeyID(key Key, ...AssignKeyIDOption) error** — compute and set kid via thumbprint
- PEM output moved to `jwkbb.EncodePEM(keys ...any)`; unwrap via `jwk.Export[any]` / `jwk.ExportAll[any]` first
- Global options: `WithStrictKeyUsage(bool)`, `WithMinRSAModulusBits(int)`, `WithMinRSAPublicExponent(int)`, `WithMaxKeys(int)` (also accepted as a per-call `ParseOption`; caps `"keys"` array + PEM block count at 1000 by default), `WithStrictKeySetParsing(bool)` (also a per-call `ParseOption`; when true a `"keys"` entry that fails to parse fails the whole set — default false retains it as an `UnsupportedKey` placeholder per RFC 7517 §5; an explicit per-call option beats the global setting, so per-call `WithIgnoreParseError(true)` selects drop mode under a global strict unless the same call passes an explicit strict true)
- HTTP JWK Set retrieval + caching moved to `github.com/jwx-go/jwkfetch` — see [Extension Modules](../../docs/10-extensions.md)
- Key interfaces: `Key`, `Set`, `RSAPublicKey`, `RSAPrivateKey`, `ECDSAPublicKey`, `ECDSAPrivateKey`, `OKPPublicKey`, `OKPPrivateKey`, `SymmetricKey`, `AKPPublicKey`, `AKPPrivateKey` (post-quantum, used by mldsa/mlkem extensions), `UnsupportedKey` (placeholder for an unparseable JWK Set entry; embeds `Key`, adds `Reason() error`, sealed by an unexported marker method so only this package's placeholder implements it; only `kid`/`kty`/`alg` accessible best-effort, other accessors report absent; crypto ops error, `Validate()` failure satisfies `IsKeyValidationError`, `MarshalJSON` re-emits the original entry JSON; check with `IsUnsupportedKey(Key) bool`)
- **Set.All()** / **Set.Fields()** — snapshot iterators; take a shallow copy when each iteration starts and release the set lock before yielding. Set mutation during iteration is allowed; key objects and field values are not cloned. NEVER use inside jwx; see AGENTS.md "Internal Loops".
- Extension: `RegisterCustomField[T]()`, `RegisterCustomDecoder[T]()`, `RegisterKeyParser()`, `RegisterKeyImporter()`, `RegisterKeyExporter()`
- Error sentinels: `ImportError()`, `ParseError()`, `ContinueError()`
- Files: `jwk.go`, `set.go`, `parser.go`, `convert.go`, `fetcher.go`, `interface.go`, `errors.go`, `x509.go`,
`filter.go`, `rsa.go`, `ecdsa.go`, `okp.go`, `symmetric.go`, `akp.go`, `mldsa.go` (go1.27; `crypto/mldsa` importers/exporters for AKP keys), `unsupported.go`, `accessors.go`, `io.go`
- Sub-packages: `jwk/ecdsa` — elliptic curve registration (`RegisterCurve(alg, curve, PointValidator)`, `CurveFromAlgorithm`, `AlgorithmFromCurve`,