Hybrid Authentication Flow

Overview

The Authentication module handles JWT validation and user session verification using tokens issued by Better Auth (Bun monolith). It supports a Hybrid Auth Strategy to accommodate both web browsers and mobile applications:
  • Web Clients: Use secure HttpOnly cookies (better-auth.session_token), validated via HTTP fallback to Better Auth.
  • Mobile Clients: Use JWT Bearer tokens in the Authorization header, validated locally with signature verification.
Note: User identity verification (password checks, email validation) happens in Better Auth (Bun). The Go backend only validates tokens and manages application-level authorization (roles, org membership, active status). For more details on mobile implementation, see the Mobile Auth Guide.

Functional Requirements

1. Login (Handled by Better Auth in Bun)

  • Input: Email, Password (sent to Better Auth).
  • Business Rules:
    • Better Auth verifies email exists.
    • Better Auth verifies password matches stored hash (scrypt).
    • If valid, Better Auth generates session tokens and JWTs.
  • Output: JWT token, session cookie, user profile.
Note: The Go backend does NOT handle login. Clients authenticate with Better Auth (Bun), then use the returned tokens to access Go APIs.

2. JWT Token Validation (Handled by Go Middleware)

  • JWT Token:
    • Issued by Better Auth (Bun).
    • Contains AuthID, Email, OrganizationId, ExpirationTime.
    • Signed with BETTER_AUTH_SECRET (HS256).
    • Validated locally by Go middleware without network calls (cached).
  • Session Cookie (for web clients):
    • better-auth.session_token issued by Better Auth.
    • Validated via HTTP fallback to Better Auth if JWT validation fails.
    • Automatically refreshed by Better Auth.

3. Protected Routes (Middleware)

  • Input:
    • Path A (Web): better-auth.session_token cookie.
    • Path B (Mobile/Apps): Authorization: Bearer <token> header.
  • Business Rules:
    • Prioritize Authorization header if present.
    • Fallback to cookie validation.
    • Validate JWT signature and expiration locally (HS256 with BETTER_AUTH_SECRET).
    • Query Better Auth service if local JWT validation fails (for session tokens).
    • Query local users table to fetch user roles, organization, and active status.
    • Extract AuthID, Email, Roles, OrganizationId, and IsActive into request context.
    • Return 401 Unauthorized if token invalid or expired.
    • Return 403 Forbidden if user is inactive.
  • Caching:
    • Cache JWT validation result in Redis (keyed by token hash, expires at JWT expiration time).
    • Cache user status (roles, active status) in Redis with 5-minute TTL.
    • Invalidate user status cache on NATS user sync events (TODO).

Security Measures

  • Passwords: Handled exclusively by Better Auth (Bun), never sent to or stored in Go backend.
  • BETTER_AUTH_SECRET: Must be loaded from environment variables, never hardcoded. Used for JWT signature validation.
  • JWT Signature Algorithm: HS256 (HMAC SHA-256).
  • Password Hashing: Bun consolidation will use scrypt (Better Auth default).
  • Token Expiration: JWT tokens are short-lived; session tokens are automatically refreshed by Better Auth.
  • Cache Invalidation: User status cache should be invalidated immediately on NATS sync events to avoid serving stale role/status data.

API Endpoints

Note: Login, registration, and token refresh are handled by Better Auth (Bun). These endpoints are NOT in the Go backend. Better Auth (Bun) Endpoints:
  • POST /api/auth/sign-up/email - User registration
  • POST /api/auth/sign-in/email - User login
  • POST /api/auth/sign-out - User logout
  • POST /api/auth/refresh - Refresh session token
Go Backend Protected Resources:
  • All endpoints in /api/v1/* require valid JWT or session token
  • Middleware automatically validates token and populates request context with user info