JWT Service Authentication
Overview
Zeus uses a dual-layer authentication architecture:- User Authentication: Better Auth (Session-based) — See Web Authentication
- Service Authentication: JWT + JWKS (Stateless)
Authentication Architecture
Why Dual-Layer Authentication
Problem with user auth only:How JWT Works
Token Acquisition Flow
- User logs in → Better Auth creates Session
- Call
/api/auth/token→ Better Auth issues JWT - Web API uses JWT → calls ai-backend
- ai-backend verifies JWT → validates signature via JWKS
Token Structure
JWKS Verification Flow
- Extract Token: Extract from
Authorization: Bearer <token>header - Fetch JWKS: Get public key from
/api/auth/jwks(with caching) - Find Key: Look up corresponding public key using
kidfrom Token Header - Verify Signature: Use public key to verify Token has not been tampered with
- Check Expiration: Verify Token has not expired
- Return User Info: Extract
userId,email,name
Protected APIs
Require JWT Authentication
Do Not Require JWT Authentication
Security Best Practices
1. Asymmetric Encryption
Uses EdDSA (Ed25519):- Backend does not need shared secrets
- Private key exists only on the Web side
- Supports key rotation
2. Key Rotation
- Rotation period: 30 days
- Old keys retained: 30 days
3. Token Validity (Dual Token System)
Desktop/iOS/Android native clients use a dual-token mechanism:
- accessToken is automatically refreshed 5 minutes before expiry
- If refresh fails (refreshToken expired), the user is automatically logged out
- refreshToken is stored as SHA-256 hash in the database
Token Refresh Flow
Refresh Token Security
- Hash storage: Database stores only SHA-256 hashes; even if leaked, raw tokens cannot be used
- Cascade deletion: All refresh tokens are automatically cleaned up when a user is deleted
- Bulk revocation: All refresh tokens can be revoked by user ID
4. JWKS Caching
- Cache duration: 1 hour
- Auto-refreshes during key rotation
5. Transport Security
- Production must use HTTPS
- Token is only transmitted in HTTP Header
- Never pass Token in URLs