Backend Authentication System
This document provides technical details about the DeployStack backend authentication system implementation. For user-facing authentication configuration, see Authentication Methods. For OAuth provider implementation details, see OAuth Provider Implementation and OAuth2 Server Implementation.
Architecture Overview
The backend authentication system is built on several key components:
- Lucia v3 - Core session management and authentication library
- Argon2 - Industry-standard password hashing
- Arctic - OAuth 2.0 client library for provider integration
- Database-backed sessions - SQLite/Turso storage for session persistence
- Dual authentication - Support for both cookie sessions and OAuth2 Bearer tokens
Authentication Flow Types
The backend supports multiple authentication flows to accommodate different client types and use cases:
1. Email/Password Authentication
Traditional username/password authentication with email verification:
- Registration (
/api/auth/email/register
) - Creates new user accounts - Login (
/api/auth/email/login
) - Authenticates existing users - Email Verification - Optional verification requirement based on global settings
- Password Reset - Secure token-based password recovery
2. OAuth Provider Authentication
Third-party authentication via OAuth providers (currently GitHub):
- Provider Login (
/api/auth/github/login
) - Initiates OAuth flow - OAuth Callback (
/api/auth/github/callback
) - Handles provider response - Account Linking - Automatically links OAuth accounts to existing users by email
- User Provisioning - Creates new users from OAuth profile data
3. OAuth2 Server Authentication
Bearer token authentication for programmatic API access:
- Authorization (
/api/oauth2/auth
) - OAuth2 authorization endpoint - Token Exchange (
/api/oauth2/token
) - Exchanges codes for access tokens - Bearer Authentication - API access using Authorization header
- Scope-based Permissions - Fine-grained access control
Core Components
Session Management
Sessions are managed through Lucia v3 with database persistence:
Session Storage
Sessions are stored in the authSession
table with the following structure:
- Session ID: 40-character cryptographically random identifier
- User ID: Foreign key reference to the authenticated user
- Expiration: 30-day lifetime from creation
- Cookie Attributes: httpOnly, secure (production), sameSite (lax)
Session Lifecycle
- Creation: Generated after successful authentication
- Validation: Checked on each request via
authHook
- Refresh: Sessions are not automatically extended
- Expiration: Expired sessions are deleted on validation attempt
- Logout: Explicit session deletion
Password Security
Passwords are secured using Argon2id with carefully chosen parameters:
Hashing Parameters
- Algorithm: Argon2id (resistant to side-channel and GPU attacks)
- Memory Cost: 19456 KB (19 MB)
- Time Cost: 2 iterations
- Parallelism: 1 thread
- Output Length: 32 bytes
- Salt: Unique per password, automatically generated
Password Verification
The verification process uses constant-time comparison to prevent timing attacks:
- Extract stored hash and salt from database
- Re-compute hash with provided password
- Compare hashes using constant-time algorithm
- Return authentication result
Authentication Hooks
The backend uses Fastify hooks for request-level authentication:
authHook (Global)
Runs on every request to establish authentication context:
- Reads session cookie if present
- Validates session against database
- Populates
request.user
andrequest.session
- Handles expired session cleanup
- Skips authentication if database not ready
requireAuthHook (Route-specific)
Enforces authentication on protected routes:
- Checks for valid user and session
- Returns 401 Unauthorized if not authenticated
- Used as preValidation hook on protected endpoints
User Registration Flow
Email Registration Process
- Validation: Input validation using Zod schemas
- Uniqueness Check: Verify username and email availability
- Password Hashing: Secure hash generation with Argon2
- User Creation: Database insertion with role assignment
- First User Logic: Automatic global_admin role for first user
- Email Verification: Send verification email (if enabled)
- Team Creation: Automatic default team creation
- Session Creation: Immediate login after registration
- Response: User data and success message
Role Assignment
- First User: Automatically assigned
global_admin
role - Subsequent Users: Assigned
global_user
role - OAuth Users: Always assigned
global_user
role - Email Verification: First user auto-verified, others depend on settings
Login Authentication Flow
Email Login Process
- Global Check: Verify login is enabled in settings
- User Lookup: Find user by email or username
- Password Verification: Argon2 hash comparison
- Email Verification Check: Ensure email is verified (if required)
- Session Creation: Generate new 30-day session
- Cookie Setting: Set httpOnly session cookie
- Response: User data and session established
Authentication State
After successful login, the following state is established:
- Session Cookie: Contains session ID
- Database Session: Active session record
- User Context: Available in
request.user
- Session Context: Available in
request.session
Email Verification System
Verification Requirements
- Controlled by:
global.send_mail
setting - First User: Always auto-verified for system access
- Email Users: Must verify before login (when enabled)
- OAuth Users: Auto-verified (provider emails trusted)
Verification Token Flow
- Token Generation: 32-character random token
- Token Storage: Hashed with Argon2 (same as passwords)
- Email Dispatch: Verification link sent via SMTP
- Token Validation: Constant-time comparison
- Account Activation: Email marked as verified
- Token Cleanup: Single-use, expires after 24 hours
Password Reset Flow
Reset Process
- Request Initiation: User provides email address
- Token Generation: Secure random reset token
- Token Storage: Hashed and stored with expiration
- Email Notification: Reset link sent to user
- Token Validation: Verify token and expiration
- Password Update: New password hashed and stored
- Token Invalidation: Used tokens are deleted
- Session Creation: Optional auto-login after reset
Security Measures
- Rate Limiting: Prevent brute force attempts
- Token Expiration: 1-hour validity window
- Single Use: Tokens invalidated after use
- User Notification: Email sent on password change
Dual Authentication Support
The backend supports both cookie-based and Bearer token authentication simultaneously:
Cookie Authentication
- Primary Use: Web application sessions
- Validation: Via
authHook
on every request - Storage: Server-side session with cookie identifier
- Lifetime: 30-day expiration
Bearer Token Authentication
- Primary Use: CLI and API access
- Validation: Via
oauthMiddleware
- Format: OAuth2 access tokens
- Lifetime: 1-hour access, 30-day refresh
Middleware Integration
Endpoints can accept either authentication method using requireAuthenticationAny()
:
- First checks for cookie session
- Falls back to Bearer token validation
- Populates same
request.user
interface - Maintains authentication type in context
Security Best Practices
Implementation Security
- Password Storage: Never store plaintext, always use Argon2
- Session Management: Cryptographically secure IDs, proper expiration
- Token Security: Constant-time comparisons, secure random generation
- HTTPS Enforcement: Secure cookies in production
- CSRF Protection: State parameters in OAuth, sameSite cookies
Validation and Sanitization
- Input Validation: All inputs validated with Zod schemas
- Email Normalization: Lowercase conversion before storage
- SQL Injection Prevention: Parameterized queries via Drizzle ORM
- XSS Prevention: httpOnly cookies, no client-side session access
Database Schema
The authentication system uses the following core tables:
authUser Table
Stores user account information:
- User identification (id, username, email)
- Authentication data (hashed_password, auth_type)
- Profile information (first_name, last_name)
- OAuth provider IDs (github_id)
- Account status (email_verified, role_id)
authSession Table
Manages active user sessions:
- Session identification (id)
- User association (user_id)
- Expiration tracking (expires_at)
Additional Tables
Supporting tables for full functionality:
- email_verification_tokens: Email verification tokens
- password_reset_tokens: Password reset tokens
- oauth_authorization_codes: OAuth2 authorization codes
- oauth_access_tokens: OAuth2 access tokens
- oauth_refresh_tokens: OAuth2 refresh tokens
API Reference
For a complete list of authentication API endpoints and their specifications, see the Backend API Documentation. The API documentation includes OpenAPI specifications with detailed request/response schemas for all authentication endpoints.
Related Documentation
- Security Policy - Security implementation details
- Database Schema - Complete database structure
- API Documentation - Full API reference
- OAuth Provider Implementation - Third-party OAuth login setup
- OAuth2 Server Implementation - OAuth2 server for API access
API Documentation Generation
Complete guide to generating OpenAPI specifications, Swagger documentation, and API testing tools for DeployStack Backend development.
Cloud Credentials Management
Comprehensive guide to implementing and managing cloud provider credentials in DeployStack backend with encryption, validation, and role-based access control.