JWT Tokens
tsdevstack uses JSON Web Tokens (JWT) for stateless authentication. Tokens are issued by the auth service and validated by Kong before requests reach your backend services.
Token types
Access tokens
Short-lived tokens used for API authentication:
- Lifetime: Configurable via
ACCESS_TOKEN_TTL - Usage: Sent in Authorization header
- Algorithm: RS256 (RSA signatures)
Refresh tokens
Longer-lived tokens used to obtain new access tokens:
- Lifetime: Configurable via
REFRESH_TOKEN_TTL - Format: Random 64-byte hex string (not a JWT)
- Storage: SHA-256 hashed before storing in database
- Usage: Exchanged for new access tokens via refresh endpoint
- Rotation: Each refresh issues a new token and invalidates the old one
- Fresh claims: A refresh reads the user from the database again, so changes to roles or confirmation status reach the access token at the next refresh (Roles)
Token validation flow
- Client sends request with
Authorization: Bearer <token> - Kong validates JWT signature against JWKS endpoint
- Kong extracts claims and passes user info to backend
- Backend AuthGuard verifies the Kong trust token, then makes user info available via
req.user
Note: JWT validation only happens for routes with @ApiBearerAuth(). See Two-layer authentication for how Kong and AuthGuard work together.
JWKS endpoint
The auth service exposes a JWKS (JSON Web Key Set) endpoint for public key discovery:
Note: Route prefixes use the short service name (e.g., /auth/) not the full package name.
This enables key rotation without service restarts - Kong fetches keys dynamically.
Configuration
JWT keys are managed through the secrets system. The framework generates RSA key pairs automatically.
To customize token expiry, add to .secrets.user.json:
OWASP alignment
The auth service template implements cryptographic best practices aligned with OWASP guidelines:
Key rotation
The framework supports seamless key rotation:
- Generate new keys and set as
JWT_*_CURRENT - Move old keys to
JWT_*_PREVIOUS - JWKS endpoint returns both keys
- Existing tokens remain valid until expiry