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
| Module | Endpoint | Description |
|---|---|---|
| Chat | /api/agent/invoke | Agent mode |
| Sandbox | /api/sandbox/* | Sandbox operations |
| MCP | /api/mcp/* | MCP management |
| Skills | /api/skills/* | Skills management |
Do Not Require JWT Authentication
| Endpoint | Description |
|---|---|
/ | Root path |
/health | Health check |
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)
| Token Type | Validity | Purpose |
|---|---|---|
| accessToken (JWT) | 1 hour | Bearer token for each API call |
| refreshToken (opaque) | 30 days | Silently obtain a new accessToken |
- 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