The jwt package implements JWS compact serialization (RFC 7515) and JWT claims (RFC 7519) with stdlib-only cryptography — no third-party JOSE dependency. A Verifier is bound to a fixed algorithm allowlist and key material at construction time, so algorithm-confusion attacks (e.g. handing an HS256 token to an RSA verifier) are rejected before any cryptographic operation runs.

Import

Signing

Build a per-algorithm SigningKey, then wrap it in a Signer with an optional key ID (written into the kid header on encode; pass "" to omit it):
Each family also has 384/512 variants: NewHS384/NewHS512, NewRS384/NewRS512, NewES384/NewES512 (P-384/P-521 keys respectively).

Encoding a token

Encode signs a MapClaims set. EncodeRegistered is the ergonomic form: it merges typed RegisteredClaims with any extra custom claims and signs the result.
For full control over the claim set, call Encode(signer, claims) directly with a jwt.MapClaims.

Verification

Build a VerifyingKey for the algorithm, then a Verifier. For a single static key, NewVerifierKey is the shortcut:
For RSA/ECDSA, build the verifying key from the public key:
Decode verifies the signature and (if a Validator is given) the registered claims, returning claims only on full success:
For multiple keys (e.g. key rotation), use NewVerifier with an explicit algorithm allowlist and a KeySelector that resolves a key by kid:

Validation options

Validator checks exp/nbf/iat (with clock skew), plus optional issuer/audience requirements — separate from the Verifier, which only checks the signature:
Defaults: system clock, 60s leeway, exp required, issuer/audience unchecked, iat not validated. WithRequireExpiry(false) and WithValidateIAT(true) are also available; see the package for the full list.

JWKS

For verifying tokens signed by an external IdP, JWKSClient fetches a JWK Set from an operator-configured URL, caches it, and implements KeySelector directly — plug it straight into NewVerifier:
NewJWKSClient fetches the given URL directly — it does not perform OIDC discovery, so pass the JWKS URL itself, not the issuer’s discovery document. The client refreshes on TTL expiry and on a kid miss, throttled by a minimum refresh interval so a burst of unknown-kid requests collapses to one outbound fetch. Options: WithHTTPClient, WithCacheTTL, WithMinRefreshInterval, WithMaxResponseBytes, and AllowInsecureURL(true) (for http:// test fixtures only — the URL must be https:// otherwise). Call jwks.Refresh(ctx) to force an immediate fetch bypassing the throttle.

Supported algorithms

RSA-PSS (PS256/PS384/PS512) is not implemented.

Algorithm confusion protection

A Verifier is built from an explicit algorithm allowlist; a token whose alg header is not in that allowlist — or is "none" — is rejected before any cryptographic operation runs (ErrAlgMismatch / ErrUnsupportedAlg). A key/algorithm mismatch at construction is also an error, not a panic:

Error sentinels

Decode/Validate return one of these wrapped sentinels; match with errors.Is:

MapClaims

Decode already returns typed RegisteredClaims (rc.Subject, rc.ExpiresAt, …) alongside the raw MapClaims for custom fields:
MapClaims also exposes GetString, Audience(), and Registered() (re-derives RegisteredClaims from the map).

Use with authn.BearerTokenProvider

Wire a verified bearer token into authn.Manager alongside password/API-key providers via web/resource’s BearerTokenAuthenticator:

Use with web/resource server

See resource server for the RequireBearer middleware that reads the Authorization: Bearer ... header and authenticates via JWT (or opaque-token introspection).