Appearance
Auth System
Authentication is handled by better-auth, a session-based auth library. There are no JWT tokens — authentication state lives in a server-side session tied to a cookie.
Session flow
- User clicks "Sign in with Google"
- Browser redirects to
/api/auth/signin/google - better-auth redirects to Google's OAuth consent screen
- Google redirects back to
/api/auth/callback/google - better-auth creates or updates a
User,Account, andSessionrecord in the database - A session cookie (
better-auth.session_token) is set on the browser - Every subsequent request sends the cookie automatically
Routes
better-auth mounts its routes under /api/auth/. Key endpoints:
| Endpoint | Description |
|---|---|
GET /api/auth/signin/google | Initiate Google OAuth flow |
GET /api/auth/callback/google | OAuth callback (handled by better-auth) |
POST /api/auth/signout | Invalidate the current session |
GET /api/auth/session | Return the current session and user |
Guards and decorators
AuthGuard (global)
Applied globally in AppModule. Validates the session cookie and attaches the User object to request.user. Returns 401 if no valid session exists.
@Public()
Marks a route as publicly accessible (bypasses AuthGuard):
typescript
import { Public } from '../auth/decorators'
@Public()
@Get('health')
health() { return 'ok' }@CurrentUser()
Injects the authenticated User object:
typescript
@Get('me')
getProfile(@CurrentUser() user: User) {
return user
}@TenantId()
Extracts tenantId from request.params.tenantId (set by TenantGuard):
typescript
@Get()
findAll(@TenantId() tenantId: string) { ... }@TenantUserId()
Injects the tenantUserId resolved by TenantGuard for the current user within the requested tenant.
API Key authentication
Requests can also authenticate with an API key in the Authorization header:
Authorization: Bearer tt_<key>The ApiKeyGuard (applied globally alongside AuthGuard) recognises this prefix, hashes the key, and looks it up in the api_keys table. If valid and not revoked/expired, it grants admin-level access to the key's tenant.
Database tables
better-auth manages these tables automatically (do not modify them manually):
users— Global user accountssessions— Active sessionsaccounts— OAuth provider links (Google)verifications— Email verification tokens