Skip to content
Security
Agent

internals

<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->

BOOST
From plugin
jwx
2.4k9 skills9 agents
Install
> /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.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->

Agent definition

internals.md

<!-- Agent-consumed file. Keep terse, unambiguous, machine-parseable. -->

Internals

Code Generation Pipeline

All `*_gen.go` files are generated. NEVER edit directly.

Generator → Output Mapping

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` |

Commands

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 Path

`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.

Functional Options Pattern

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 comment

Manual option functions in `{pkg}/options.go` supplement generated ones.

Key Registration/Extension Points

| 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 |

Register\* API convention (v4)

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:

  • Signature must be `func Register...(...) error`. Do not drop the

return in the name of "it can't fail today."

  • Unused error returns in callers must not be silently dropped — see

the companion-module rule below.

Companion modules: panic on Register\* failure

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 JSON Ciphertext

`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.

JSON Backend

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

Read more
Ships withjwx

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.

Get the whole plugin
Stats
2,440
Stars
197
Forks
Active
Maintenance
Go
Language
MIT
License
1d ago
Last commit
10y ago
Created
4h ago
Added

Repo: lestrrat-go/jwx

Other agents on jwx.