companion-template-syn…
Pull newest GitHub Actions versions from companion repos back into `.companions/templates/`.…
<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->
> /plugin marketplace add lestrrat-go/jwx > /plugin install jwx-dev-v4@jwx-v4
How it fires
How this agent gets triggered: by you, by Claude, or both.
Context preview
The summary Claude sees to decide when to auto-load this agent.
<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->
<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->
All `*_gen.go` files are generated. NEVER edit directly.
All generators live in a unified binary at `internal/jwxcodegen/cmd/jwxcodegen/`, invoked via subcommand through `scripts/jwxcodegen.sh`.
| Generator | Subcommand | Input | Output | |-----------|------------|-------|--------| | `genoptions` | `generate-options` | `{pkg}/options.yaml` | `{pkg}/options_gen.go` | | `genjwt` | `generate-jwt` | `jwt/objects.yml` | `jwt/*_gen.go` | | `genheaders` | `generate-headers` | `jws/objects.yml` | `jws/headers_gen.go` | | `genheaders` | `generate-headers` | `jwe/objects.yml` | `jwe/headers_gen.go` | | `genjwk` | `generate-jwk` | `jwk/objects.yml` | `jwk/*_gen.go` | | `genjwa` | `generate-jwa` | `jwa/objects.yml` | `jwa/*_gen.go` | | `genreadfile` | `generate-readfile` | (none) | `{jwk,jws,jwe,jwt}/io_gen.go` — `ParseFS` + deprecated `ReadFile` |
make generate # All (includes options via `go generate .`) make generate-jwt # JWT objects only (NOT options) make generate-jws # JWS objects only (NOT options) make generate-jwe # JWE objects only (NOT options) make generate-jwk # JWK objects only (NOT options) make generate-jwa # JWA objects only (NOT options) go generate . # Options only (genoptions + genreadfile + stringer)
`make generate-<pkg>` runs `go generate ./<pkg>`, which triggers the per-package generator only. Options (`options.yaml` → `options_gen.go`) are regenerated by `go generate .` (root), which `make generate` runs first.
`jwt/parse_fast.go` accepts exactly one `WithKey` without suboptions, optionally with `WithValidate`. Multiple keys use the full `jws.Verify` path so every configured key remains eligible.
Defined in `{pkg}/options.yaml`, generated to `{pkg}/options_gen.go`.
YAML structure:
options:
- ident: Token # → WithToken()
interface: ParseOption # Option interface it implements
argument_type: Token # Go type of argument
comment: | # Godoc commentManual option functions in `{pkg}/options.go` supplement generated ones.
| What | Registration Function | Package | |------|----------------------|---------| | Custom algorithms | `jwa.Register{Type}()` | jwa | | Custom key parsers | `jwk.RegisterKeyParser()` | jwk | | Custom key importers | `jwk.RegisterKeyImporter()` | jwk | | Custom key exporters | `jwk.RegisterKeyExporter()` | jwk | | Custom JWK fields | `jwk.RegisterCustomField[T]()` / `jwk.RegisterCustomDecoder[T]()` | jwk | | Custom JWS fields | `jws.RegisterCustomField[T]()` / `jws.RegisterCustomDecoder[T]()` | jws | | Custom JWE fields | `jwe.RegisterCustomField[T]()` / `jwe.RegisterCustomDecoder[T]()` | jwe | | Custom JWT claims | `jwt.RegisterCustomField[T]()` / `jwt.RegisterCustomDecoder[T]()` | jwt | | Custom OIDC claims | `openid.RegisterCustomField[T]()` / `openid.RegisterCustomDecoder[T]()` | jwt/openid | | Custom signers | `jws.RegisterSigner()` | jws | | Custom verifiers | `jws.RegisterVerifier()` | jws |
All `Register*` functions **must return `error`**, even if the current implementation has no failure path. This reserves the ability to codify error modes (duplicate detection, identifier validation, freeze-point enforcement, etc.) in the future without another API break.
When adding a new `Register*` function or touching an existing one:
return in the name of "it can't fail today."
the companion-module rule below.
Companion modules under `github.com/jwx-go/*` register their algorithms from `init()`. The house style is:
func init() {
if err := jws.RegisterSigner(alg, mySigner{}); err != nil {
panic(fmt.Sprintf("jwx-go/<mod>: failed to register signer: %s", err))
}
}Rationale: `init()` runs once at import time. A registration failure means the extension is unusable, and every subsequent call that relies on it would fail in a confusing way far from the real cause. Crashing at import surfaces the problem immediately and loudly.
This is intentional and uniform across all companion modules — do not demote these to `log.Printf` + continue. Package godoc on companion modules should mention that importing the package can panic if jwx rejects the registration.
`jwe.Message` always serializes the required `ciphertext` member. Empty string is valid for empty AES-GCM plaintext; missing, null, or non-string ciphertext is rejected. IV and authentication tag must remain non-empty.
Uses `encoding/json/v2` exclusively (no build-tag switching between backends).
One Go-version build tag does live inside `internal/json`: the sentinel a custom unmarshaler returns to decline a value is `json/v2.SkipFunc` up to Go 1.26 and `errors.ErrUnsupported` from Go 1.27 on. `skipfunc_pre_go127.go` / `skipfunc_go127.go` bind it to `errSkipFunc` so the rest of the package does not have to care. This is a compatibility shim, not a backend switch — delete it once the module requires Go 1.27.
Internal `internal/json` package provides the abstraction. Custom field registry (`json.Registry`) enables type-safe deserialization of extension fields.
`internal/json.FieldProbe` backs the sealed JWS/JWK building-block `Header` APIs. It indexes top-level members in owned input, preserves duplicates in document order (first-wins lookup), and validates nested values without allocating a value tree. `internal/json.HasField` is the allocation-light streaming presence check used by `jwk.Parse` to distinguish JWK from JWKS. B
Go module implementing various JWx (JWA/JWE/JWK/JWS/JWT, otherwise known as JOSE) technologies. If you are using this module in your product or your company, please add your product and/or company name in the Wiki! It really helps keeping up our motivation.
Repo: lestrrat-go/jwx
Pull newest GitHub Actions versions from companion repos back into `.companions/templates/`.…
Extension modules under `github.com/jwx-go/*` (asmbase64, compsig, ed448, es256k, examples,…
<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->
<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->
<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->