JWT security best practices for issuers
Most JWT guidance targets verifiers. Issuers make decisions that matter just as much: key strength, lifetimes, audiences and what goes into the payload. These practices follow RFC 8725.
Keys
- Generate HMAC secrets randomly with at least as many bits as the hash (256 for HS256). Never use passwords or words.
- Use RSA keys of 2048 bits or more, or EC keys on the curve that matches the algorithm (P-256 for ES256).
- Keep private keys in a KMS/HSM or secrets manager; never in source code, container images or front-end bundles.
- Use one key per purpose and environment; give each a unique kid and rotate on a schedule.
- Don't issue unsigned (alg none) tokens except in tightly controlled, explicit cases.
Claims
- Always set
iss,audandexpso verifiers have something to check. - Keep lifetimes short and use refresh tokens for long sessions.
- Never put secrets or sensitive personal data in the payload — it is encoded, not encrypted.
- Use
jtifor single-use tokens and track consumption server-side. - Encode very large numeric IDs as strings; JavaScript can't represent integers above 2⁵³ exactly.
Explicit typing
If one issuer produces different kinds of JWT (access tokens, ID tokens, logout tokens), set a distinct typ such as at+jwt and have verifiers check it (RFC 8725 §3.11). This stops one token type from being accepted in place of another.
Operations
- Publish public keys in a JWKS before signing with them; keep retired keys until their tokens expire.
- Don't log issued tokens; log the jti.
- Test verifiers with expired, wrong-audience, tampered and unsigned tokens.
Produce a full set of should-reject tokens for your API test suite in one click.
Generate negative testsRelated: HS256 secrets · RS256 keys