JWT Validation
How tokens are validated across the stack, and how to debug 401s.
Validation rules
- Signature: RS256, keys fetched from the identity provider's JWKS endpoint (cached, refreshed periodically).
issmust match the configured issuer exactly;audis checked when configured.exp/nbfenforced with bounded leeway (≤ 300 s).- Development stacks may run with JWT validation disabled (a synthetic user is injected) — never use that setting outside local development.
Debugging a 401
- Decode the token (jwt.io or
jq-based decode) — checkiss,aud,expfirst. - Issuer/JWKS topology: the browser gets the token from the public identity URL, while backends may fetch JWKS over an internal network. The configured issuer must match the URL in the token, while the JWKS URL points wherever the backend can reach. See Configuration.
- Check the service's JWKS connectivity:
docker exec <svc> wget -qO- http://keycloak:8080/realms/<realm>/protocol/openid-connect/certs | head -c 200
- Clock skew: compare
date -uinside the container with the token'siat. - On gateway-fronted services, distinguish the client token from the gateway's destination-bound workload token. A service-side
401can mean a wrong workload audience, unknown caller, expired token, or unauthorized subject asserter even when the external token was valid.
See also
- Auth Flow — external and workload identity contracts
- Flow: Authentication & Identity