JWT vs Session Tokens for Internal APIs
Why we use opaque session tokens at the gateway and JWT only for service-to-service calls.
Teams default to JWT for everything. We split the problem.
JWT Works When
- Stateless verification is required (many validators, no shared store)
- Claims are small and stable
- Revocation is rare or handled via short TTL + refresh
JWT Hurts When
- You need instant revocation (employee offboarding, key compromise)
- Tokens grow with embedded permissions (KB-sized headers)
- Clients leak tokens in logs (base64 is not encryption)
Our Split
| Client type | Token | Store |
|---|---|---|
| Mobile / web via gateway | Opaque session ID | Redis, 24h TTL |
| Service → service | JWT, 5m TTL | JWKS rotation weekly |
| Admin API | Opaque + MFA step-up | Redis, 1h TTL |
Revoking a session: delete one Redis key. Revoking a JWT before expiry: maintain a denylist — which is a session store with extra steps.
security , auth , jwt · .NET , Redis