|
1 | 1 | --- |
2 | | -title: Authentication System |
3 | | -description: Complete guide to implementing user authentication in DeployStack Backend. |
| 2 | +title: Backend Authentication System |
| 3 | +description: Technical documentation for the DeployStack backend authentication implementation, including session management, password hashing, and authentication flows. |
4 | 4 | --- |
5 | 5 |
|
6 | | -# DeployStack Authentication System |
| 6 | +# Backend Authentication System |
| 7 | + |
| 8 | +This document provides technical details about the DeployStack backend authentication system implementation. For user-facing authentication configuration, see [Authentication Methods](/auth). For OAuth provider implementation details, see [OAuth Provider Implementation](/development/backend/oauth-providers) and [OAuth2 Server Implementation](/development/backend/oauth2-server). |
| 9 | + |
| 10 | +## Architecture Overview |
| 11 | + |
| 12 | +The backend authentication system is built on several key components: |
| 13 | + |
| 14 | +- **[Lucia v3](https://lucia-auth.com/)** - Core session management and authentication library |
| 15 | +- **[Argon2](https://github.com/napi-rs/node-rs)** - Industry-standard password hashing |
| 16 | +- **[Arctic](https://arctic.js.org/)** - OAuth 2.0 client library for provider integration |
| 17 | +- **Database-backed sessions** - SQLite/Turso storage for session persistence |
| 18 | +- **Dual authentication** - Support for both cookie sessions and OAuth2 Bearer tokens |
| 19 | + |
| 20 | +## Authentication Flow Types |
| 21 | + |
| 22 | +The backend supports multiple authentication flows to accommodate different client types and use cases: |
| 23 | + |
| 24 | +### 1. Email/Password Authentication |
| 25 | + |
| 26 | +Traditional username/password authentication with email verification: |
| 27 | + |
| 28 | +- **Registration** (`/api/auth/email/register`) - Creates new user accounts |
| 29 | +- **Login** (`/api/auth/email/login`) - Authenticates existing users |
| 30 | +- **Email Verification** - Optional verification requirement based on global settings |
| 31 | +- **Password Reset** - Secure token-based password recovery |
| 32 | + |
| 33 | +### 2. OAuth Provider Authentication |
| 34 | + |
| 35 | +Third-party authentication via OAuth providers (currently GitHub): |
| 36 | + |
| 37 | +- **Provider Login** (`/api/auth/github/login`) - Initiates OAuth flow |
| 38 | +- **OAuth Callback** (`/api/auth/github/callback`) - Handles provider response |
| 39 | +- **Account Linking** - Automatically links OAuth accounts to existing users by email |
| 40 | +- **User Provisioning** - Creates new users from OAuth profile data |
| 41 | + |
| 42 | +### 3. OAuth2 Server Authentication |
| 43 | + |
| 44 | +Bearer token authentication for programmatic API access: |
| 45 | + |
| 46 | +- **Authorization** (`/api/oauth2/auth`) - OAuth2 authorization endpoint |
| 47 | +- **Token Exchange** (`/api/oauth2/token`) - Exchanges codes for access tokens |
| 48 | +- **Bearer Authentication** - API access using Authorization header |
| 49 | +- **Scope-based Permissions** - Fine-grained access control |
| 50 | + |
| 51 | +## Core Components |
| 52 | + |
| 53 | +### Session Management |
| 54 | + |
| 55 | +Sessions are managed through Lucia v3 with database persistence: |
| 56 | + |
| 57 | +#### Session Storage |
| 58 | + |
| 59 | +Sessions are stored in the `authSession` table with the following structure: |
| 60 | +- **Session ID**: 40-character cryptographically random identifier |
| 61 | +- **User ID**: Foreign key reference to the authenticated user |
| 62 | +- **Expiration**: 30-day lifetime from creation |
| 63 | +- **Cookie Attributes**: httpOnly, secure (production), sameSite (lax) |
| 64 | + |
| 65 | +#### Session Lifecycle |
| 66 | + |
| 67 | +1. **Creation**: Generated after successful authentication |
| 68 | +2. **Validation**: Checked on each request via `authHook` |
| 69 | +3. **Refresh**: Sessions are not automatically extended |
| 70 | +4. **Expiration**: Expired sessions are deleted on validation attempt |
| 71 | +5. **Logout**: Explicit session deletion |
| 72 | + |
| 73 | +### Password Security |
| 74 | + |
| 75 | +Passwords are secured using Argon2id with carefully chosen parameters: |
| 76 | + |
| 77 | +#### Hashing Parameters |
| 78 | +- **Algorithm**: Argon2id (resistant to side-channel and GPU attacks) |
| 79 | +- **Memory Cost**: 19456 KB (19 MB) |
| 80 | +- **Time Cost**: 2 iterations |
| 81 | +- **Parallelism**: 1 thread |
| 82 | +- **Output Length**: 32 bytes |
| 83 | +- **Salt**: Unique per password, automatically generated |
| 84 | + |
| 85 | +#### Password Verification |
| 86 | + |
| 87 | +The verification process uses constant-time comparison to prevent timing attacks: |
| 88 | +1. Extract stored hash and salt from database |
| 89 | +2. Re-compute hash with provided password |
| 90 | +3. Compare hashes using constant-time algorithm |
| 91 | +4. Return authentication result |
| 92 | + |
| 93 | +### Authentication Hooks |
| 94 | + |
| 95 | +The backend uses Fastify hooks for request-level authentication: |
| 96 | + |
| 97 | +#### authHook (Global) |
| 98 | + |
| 99 | +Runs on every request to establish authentication context: |
| 100 | +- Reads session cookie if present |
| 101 | +- Validates session against database |
| 102 | +- Populates `request.user` and `request.session` |
| 103 | +- Handles expired session cleanup |
| 104 | +- Skips authentication if database not ready |
| 105 | + |
| 106 | +#### requireAuthHook (Route-specific) |
| 107 | + |
| 108 | +Enforces authentication on protected routes: |
| 109 | +- Checks for valid user and session |
| 110 | +- Returns 401 Unauthorized if not authenticated |
| 111 | +- Used as preValidation hook on protected endpoints |
| 112 | + |
| 113 | +## User Registration Flow |
| 114 | + |
| 115 | +### Email Registration Process |
| 116 | + |
| 117 | +1. **Validation**: Input validation using Zod schemas |
| 118 | +2. **Uniqueness Check**: Verify username and email availability |
| 119 | +3. **Password Hashing**: Secure hash generation with Argon2 |
| 120 | +4. **User Creation**: Database insertion with role assignment |
| 121 | +5. **First User Logic**: Automatic global_admin role for first user |
| 122 | +6. **Email Verification**: Send verification email (if enabled) |
| 123 | +7. **Team Creation**: Automatic default team creation |
| 124 | +8. **Session Creation**: Immediate login after registration |
| 125 | +9. **Response**: User data and success message |
| 126 | + |
| 127 | +### Role Assignment |
| 128 | + |
| 129 | +- **First User**: Automatically assigned `global_admin` role |
| 130 | +- **Subsequent Users**: Assigned `global_user` role |
| 131 | +- **OAuth Users**: Always assigned `global_user` role |
| 132 | +- **Email Verification**: First user auto-verified, others depend on settings |
| 133 | + |
| 134 | +## Login Authentication Flow |
| 135 | + |
| 136 | +### Email Login Process |
| 137 | + |
| 138 | +1. **Global Check**: Verify login is enabled in settings |
| 139 | +2. **User Lookup**: Find user by email or username |
| 140 | +3. **Password Verification**: Argon2 hash comparison |
| 141 | +4. **Email Verification Check**: Ensure email is verified (if required) |
| 142 | +5. **Session Creation**: Generate new 30-day session |
| 143 | +6. **Cookie Setting**: Set httpOnly session cookie |
| 144 | +7. **Response**: User data and session established |
| 145 | + |
| 146 | +### Authentication State |
| 147 | + |
| 148 | +After successful login, the following state is established: |
| 149 | +- **Session Cookie**: Contains session ID |
| 150 | +- **Database Session**: Active session record |
| 151 | +- **User Context**: Available in `request.user` |
| 152 | +- **Session Context**: Available in `request.session` |
| 153 | + |
| 154 | +## Email Verification System |
| 155 | + |
| 156 | +### Verification Requirements |
| 157 | + |
| 158 | +- **Controlled by**: `global.send_mail` setting |
| 159 | +- **First User**: Always auto-verified for system access |
| 160 | +- **Email Users**: Must verify before login (when enabled) |
| 161 | +- **OAuth Users**: Auto-verified (provider emails trusted) |
| 162 | + |
| 163 | +### Verification Token Flow |
| 164 | + |
| 165 | +1. **Token Generation**: 32-character random token |
| 166 | +2. **Token Storage**: Hashed with Argon2 (same as passwords) |
| 167 | +3. **Email Dispatch**: Verification link sent via SMTP |
| 168 | +4. **Token Validation**: Constant-time comparison |
| 169 | +5. **Account Activation**: Email marked as verified |
| 170 | +6. **Token Cleanup**: Single-use, expires after 24 hours |
| 171 | + |
| 172 | +## Password Reset Flow |
| 173 | + |
| 174 | +### Reset Process |
| 175 | + |
| 176 | +1. **Request Initiation**: User provides email address |
| 177 | +2. **Token Generation**: Secure random reset token |
| 178 | +3. **Token Storage**: Hashed and stored with expiration |
| 179 | +4. **Email Notification**: Reset link sent to user |
| 180 | +5. **Token Validation**: Verify token and expiration |
| 181 | +6. **Password Update**: New password hashed and stored |
| 182 | +7. **Token Invalidation**: Used tokens are deleted |
| 183 | +8. **Session Creation**: Optional auto-login after reset |
| 184 | + |
| 185 | +### Security Measures |
| 186 | + |
| 187 | +- **Rate Limiting**: Prevent brute force attempts |
| 188 | +- **Token Expiration**: 1-hour validity window |
| 189 | +- **Single Use**: Tokens invalidated after use |
| 190 | +- **User Notification**: Email sent on password change |
| 191 | + |
| 192 | +## Dual Authentication Support |
| 193 | + |
| 194 | +The backend supports both cookie-based and Bearer token authentication simultaneously: |
| 195 | + |
| 196 | +### Cookie Authentication |
| 197 | + |
| 198 | +- **Primary Use**: Web application sessions |
| 199 | +- **Validation**: Via `authHook` on every request |
| 200 | +- **Storage**: Server-side session with cookie identifier |
| 201 | +- **Lifetime**: 30-day expiration |
| 202 | + |
| 203 | +### Bearer Token Authentication |
| 204 | + |
| 205 | +- **Primary Use**: CLI and API access |
| 206 | +- **Validation**: Via `oauthMiddleware` |
| 207 | +- **Format**: OAuth2 access tokens |
| 208 | +- **Lifetime**: 1-hour access, 30-day refresh |
| 209 | + |
| 210 | +### Middleware Integration |
| 211 | + |
| 212 | +Endpoints can accept either authentication method using `requireAuthenticationAny()`: |
| 213 | +- First checks for cookie session |
| 214 | +- Falls back to Bearer token validation |
| 215 | +- Populates same `request.user` interface |
| 216 | +- Maintains authentication type in context |
| 217 | + |
| 218 | +## Security Best Practices |
| 219 | + |
| 220 | +### Implementation Security |
| 221 | + |
| 222 | +1. **Password Storage**: Never store plaintext, always use Argon2 |
| 223 | +2. **Session Management**: Cryptographically secure IDs, proper expiration |
| 224 | +3. **Token Security**: Constant-time comparisons, secure random generation |
| 225 | +4. **HTTPS Enforcement**: Secure cookies in production |
| 226 | +5. **CSRF Protection**: State parameters in OAuth, sameSite cookies |
| 227 | + |
| 228 | +### Validation and Sanitization |
| 229 | + |
| 230 | +- **Input Validation**: All inputs validated with Zod schemas |
| 231 | +- **Email Normalization**: Lowercase conversion before storage |
| 232 | +- **SQL Injection Prevention**: Parameterized queries via Drizzle ORM |
| 233 | +- **XSS Prevention**: httpOnly cookies, no client-side session access |
| 234 | + |
| 235 | +## Database Schema |
| 236 | + |
| 237 | +The authentication system uses the following core tables: |
| 238 | + |
| 239 | +### authUser Table |
| 240 | + |
| 241 | +Stores user account information: |
| 242 | +- User identification (id, username, email) |
| 243 | +- Authentication data (hashed_password, auth_type) |
| 244 | +- Profile information (first_name, last_name) |
| 245 | +- OAuth provider IDs (github_id) |
| 246 | +- Account status (email_verified, role_id) |
| 247 | + |
| 248 | +### authSession Table |
| 249 | + |
| 250 | +Manages active user sessions: |
| 251 | +- Session identification (id) |
| 252 | +- User association (user_id) |
| 253 | +- Expiration tracking (expires_at) |
| 254 | + |
| 255 | +### Additional Tables |
| 256 | + |
| 257 | +Supporting tables for full functionality: |
| 258 | +- **email_verification_tokens**: Email verification tokens |
| 259 | +- **password_reset_tokens**: Password reset tokens |
| 260 | +- **oauth_authorization_codes**: OAuth2 authorization codes |
| 261 | +- **oauth_access_tokens**: OAuth2 access tokens |
| 262 | +- **oauth_refresh_tokens**: OAuth2 refresh tokens |
| 263 | + |
| 264 | +## API Reference |
| 265 | + |
| 266 | +For a complete list of authentication API endpoints and their specifications, see the [Backend API Documentation](/development/backend/api). The API documentation includes OpenAPI specifications with detailed request/response schemas for all authentication endpoints. |
| 267 | + |
| 268 | +## Related Documentation |
| 269 | + |
| 270 | +- [Security Policy](/development/backend/security) - Security implementation details |
| 271 | +- [Database Schema](/development/backend/database) - Complete database structure |
| 272 | +- [API Documentation](/development/backend/api) - Full API reference |
| 273 | +- [OAuth Provider Implementation](/development/backend/oauth-providers) - Third-party OAuth login setup |
| 274 | +- [OAuth2 Server Implementation](/development/backend/oauth2-server) - OAuth2 server for API access |
0 commit comments