Fetch the authorization server's JWKS endpoint (advertised in its OpenID discovery document) and cache the public keys; verify the token's signature using the key matching the kid header claim.
Validate the standard JWT claims: iss must match your expected issuer, exp must be in the future, and iat should be reasonably recent; reject tokens failing any of these.
Validate the aud claim: it must contain your resource server's identifier (API audience); reject tokens where your audience is absent — tokens intended for other services must not be accepted.
Validate the scope or scp claim to confirm the token grants the specific permission your endpoint requires; return 403 if required scopes are missing rather than 401.
Never accept an ID token as an API bearer token: ID tokens have the client application as their audience, not your API, and they do not carry API scopes; this is one of the most common OIDC integration mistakes.
Validate the azp claim only when you have authoritative knowledge that you issued the token to a specific client; in multi-client scenarios where you accept tokens from clients you do not control, azp validation is typically inappropriate.
Known gotchas
Accepting an ID token at an API endpoint exposes the full user profile to any attacker who can replay a leaked ID token, because ID tokens are audience-scoped to the client and accepted by any relying party that skips audience validation.
Caching JWKS responses is essential for performance, but you must implement a key refresh strategy (e.g., re-fetch on unknown kid) to support key rotation without downtime.
Clock skew between issuer and resource server can cause valid tokens to be rejected; implement a small tolerance (typically a few minutes) for exp and nbf validation.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp