# Authentik Setup Guide This guide walks you through configuring Authentik for OAuth 2.0 / OpenID Connect authentication with the Feuerwehr Dashboard. ## Table of Contents - [Prerequisites](#prerequisites) - [Authentik Installation](#authentik-installation) - [Creating the Application](#creating-the-application) - [Provider Configuration](#provider-configuration) - [Redirect URIs Setup](#redirect-uris-setup) - [Scopes Configuration](#scopes-configuration) - [Getting Client Credentials](#getting-client-credentials) - [Testing Authentication](#testing-authentication) - [Common Issues](#common-issues) - [Advanced Configuration](#advanced-configuration) ## Prerequisites Before you begin, you need: - An Authentik instance (self-hosted or cloud) - Admin access to Authentik - Your Feuerwehr Dashboard URL (e.g., `https://dashboard.yourdomain.com`) - Your backend API URL (e.g., `https://api.yourdomain.com`) ## Authentik Installation If you don't have Authentik yet, here's a quick setup guide. ### Option 1: Docker Compose (Recommended) Create `docker-compose.yml`: ```yaml version: "3.8" services: postgresql: image: postgres:16-alpine restart: unless-stopped volumes: - database:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: ${PG_PASS:?database password required} POSTGRES_USER: ${PG_USER:-authentik} POSTGRES_DB: ${PG_DB:-authentik} env_file: - .env redis: image: redis:alpine restart: unless-stopped server: image: ghcr.io/goauthentik/server:2024.2 restart: unless-stopped command: server environment: AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY} AUTHENTIK_POSTGRESQL__HOST: postgresql AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} AUTHENTIK_REDIS__HOST: redis ports: - "${AUTHENTIK_PORT_HTTP:-9000}:9000" - "${AUTHENTIK_PORT_HTTPS:-9443}:9443" depends_on: - postgresql - redis worker: image: ghcr.io/goauthentik/server:2024.2 restart: unless-stopped command: worker environment: AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY} AUTHENTIK_POSTGRESQL__HOST: postgresql AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} AUTHENTIK_REDIS__HOST: redis depends_on: - postgresql - redis volumes: database: driver: local ``` Create `.env`: ```bash PG_PASS= AUTHENTIK_SECRET_KEY= AUTHENTIK_PORT_HTTP=9000 AUTHENTIK_PORT_HTTPS=9443 ``` Start Authentik: ```bash docker-compose up -d ``` Access Authentik at `http://localhost:9000` and complete the initial setup wizard. ### Option 2: Kubernetes See [Authentik Kubernetes Documentation](https://goauthentik.io/docs/installation/kubernetes) for Helm charts. ## Creating the Application ### Step 1: Access Authentik Admin Interface 1. Log in to your Authentik instance 2. Navigate to **Admin Interface** (gear icon in top right) ### Step 2: Create Provider 1. In the admin panel, go to **Applications** → **Providers** 2. Click **Create** button 3. Select **OAuth2/OpenID Provider** Configure the provider: ``` Name: Feuerwehr Dashboard Provider Authorization Flow: default-provider-authorization-implicit-consent Protocol Settings: ``` **Client Type**: - Select: `Confidential` **Client ID**: - Auto-generated (you'll copy this later) - Or set custom: `feuerwehr-dashboard` **Client Secret**: - Auto-generated (you'll copy this later) **Redirect URIs**: ``` http://localhost:5173/auth/callback http://localhost/auth/callback https://dashboard.yourdomain.com/auth/callback ``` Add one URI per line. Include all environments (development, staging, production). **Signing Key**: - Select: `authentik Self-signed Certificate` (default) **Token Validity**: ``` Access token validity: 3600 (1 hour) Refresh token validity: 86400 (24 hours) ``` Click **Create** to save the provider. ### Step 3: Create Application 1. Go to **Applications** → **Applications** 2. Click **Create** button Configure the application: ``` Name: Feuerwehr Dashboard Slug: feuerwehr-dashboard Provider: Feuerwehr Dashboard Provider (select from dropdown) Launch URL: https://dashboard.yourdomain.com ``` **UI Settings** (optional): ``` Icon: (upload fire department logo) Publisher: Your Fire Department Name Description: Fire department operations dashboard ``` Click **Create** to save. ### Step 4: Configure Scopes 1. Go back to **Providers** → **Feuerwehr Dashboard Provider** 2. Scroll to **Advanced protocol settings** 3. Click **Edit** on **Scopes** Ensure the following scopes are selected: - [x] `openid` - Required for OpenID Connect - [x] `profile` - User profile information - [x] `email` - User email address Optional scopes: - [ ] `offline_access` - For refresh tokens (recommended) Click **Update**. ## Provider Configuration ### Step 5: Configure Advanced Settings Edit your provider and configure these advanced settings: **Token Settings**: ``` Include claims in ID token: Yes Access token validity: 3600 seconds (1 hour) Refresh token validity: 86400 seconds (24 hours) ``` **Subject Mode**: ``` Based on the User's hashed ID ``` This ensures consistent user IDs. **Signing Algorithm**: ``` RS256 (default) ``` ### Step 6: Configure Claims Ensure the following claims are mapped: Standard claims (should be automatic): - `sub` - Subject (user ID) - `email` - User email - `name` - Full name - `preferred_username` - Username - `given_name` - First name - `family_name` - Last name These are automatically included with the `profile` and `email` scopes. ## Redirect URIs Setup Your redirect URIs must match exactly between Authentik and your application. ### Development Environment ``` http://localhost:5173/auth/callback ``` This is the Vite dev server URL. ### Production Environment ``` https://dashboard.yourdomain.com/auth/callback ``` Replace `yourdomain.com` with your actual domain. ### Docker Local Testing ``` http://localhost/auth/callback http://localhost:80/auth/callback ``` For testing the production Docker build locally. ### Important Notes - URLs are **case-sensitive** - Must include protocol (`http://` or `https://`) - No trailing slashes - Port numbers must match if specified ## Scopes Configuration ### Required Scopes Your application requires these scopes: 1. **openid** - Identifies this as an OpenID Connect request 2. **profile** - Provides basic profile information 3. **email** - Provides user email address ### Requesting Scopes The dashboard automatically requests these scopes in the OAuth flow. Backend configuration (`backend/src/config/oauth.ts`): ```typescript scopes: ['openid', 'profile', 'email'] ``` Frontend login flow (`frontend/src/services/authService.ts`): ```typescript const scopes = 'openid profile email'; ``` ## Getting Client Credentials ### Step 7: Copy Client Credentials 1. Go to **Applications** → **Providers** 2. Click on **Feuerwehr Dashboard Provider** 3. Find the **Client ID** and **Client Secret** **Client ID**: Will look like `abc123def456...` or custom `feuerwehr-dashboard` **Client Secret**: Click the **eye icon** to reveal, then **copy button** ### Step 8: Get Provider URLs 1. In the provider details, find **OpenID Configuration URL**: ``` https://auth.yourdomain.com/application/o/feuerwehr-dashboard/.well-known/openid-configuration ``` 2. Important URLs from this configuration: - **Issuer**: `https://auth.yourdomain.com/application/o/feuerwehr-dashboard/` - **Authorization Endpoint**: Auto-discovered - **Token Endpoint**: Auto-discovered - **Userinfo Endpoint**: Auto-discovered ### Step 9: Configure Dashboard Update your Feuerwehr Dashboard `.env` file: ```bash # Authentik OAuth Configuration AUTHENTIK_CLIENT_ID= AUTHENTIK_CLIENT_SECRET= AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr-dashboard/ AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback # For development, use: # AUTHENTIK_ISSUER=http://localhost:9000/application/o/feuerwehr-dashboard/ # AUTHENTIK_REDIRECT_URI=http://localhost:5173/auth/callback ``` **Important**: The `AUTHENTIK_ISSUER` must end with a trailing slash `/`. ## Testing Authentication ### Step 10: Test the Flow 1. **Start your application**: ```bash # Development cd backend && npm run dev cd frontend && npm run dev # Or production make prod ``` 2. **Open the dashboard** in your browser: ``` Development: http://localhost:5173 Production: https://dashboard.yourdomain.com ``` 3. **Click "Login" button** 4. **You should be redirected to Authentik** login page 5. **Enter your Authentik credentials** 6. **Consent screen** (if enabled): - Review permissions - Click "Authorize" 7. **Redirect back to dashboard**: - Should show your dashboard - User profile should be loaded - Check browser console for any errors ### Step 11: Verify Token Exchange Check backend logs: ```bash make logs-prod # or cd backend && npm run dev ``` Look for: ``` [INFO] OAuth callback received [INFO] Token exchange successful [INFO] User authenticated: ``` ### Step 12: Test User Profile In the dashboard: 1. Navigate to Profile page 2. Verify your information is displayed: - Username - Email - Name ### Step 13: Test Logout 1. Click "Logout" button 2. Should redirect to login page 3. Verify session is cleared 4. Attempting to access dashboard should redirect to login ## Common Issues ### Issue 1: Redirect URI Mismatch **Error**: `redirect_uri_mismatch` or `invalid_redirect_uri` **Solution**: 1. Check the redirect URI in Authentik **exactly** matches your app 2. Include protocol (`http://` or `https://`) 3. Check for trailing slashes 4. Verify port numbers match ### Issue 2: Invalid Client Credentials **Error**: `invalid_client` **Solution**: 1. Verify `AUTHENTIK_CLIENT_ID` is correct 2. Verify `AUTHENTIK_CLIENT_SECRET` is correct (no extra spaces) 3. Check if client secret was regenerated in Authentik 4. Ensure client type is "Confidential" ### Issue 3: CORS Errors **Error**: CORS policy blocked request **Solution**: 1. Ensure `CORS_ORIGIN` in backend `.env` matches frontend URL 2. For development: `CORS_ORIGIN=http://localhost:5173` 3. For production: `CORS_ORIGIN=https://dashboard.yourdomain.com` 4. Restart backend after changing CORS settings ### Issue 4: Token Validation Failed **Error**: `Invalid token` or `Token signature verification failed` **Solution**: 1. Verify `AUTHENTIK_ISSUER` URL is correct 2. Ensure issuer URL ends with `/` 3. Check Authentik is accessible from backend server 4. Verify JWT signing key hasn't changed ### Issue 5: Scope Errors **Error**: `invalid_scope` or missing user data **Solution**: 1. Ensure `openid`, `profile`, `email` scopes are configured in Authentik 2. Check scopes are requested in login flow 3. Verify user has consented to scopes ### Issue 6: User Not Created in Database **Error**: Authentication works but user not found **Solution**: 1. Check backend logs for database errors 2. Verify database migrations ran 3. Check `users` table exists: ```bash docker exec -it feuerwehr_db_prod psql -U prod_user -d feuerwehr_prod -c "\dt" ``` 4. Manually run migrations if needed ### Issue 7: Token Refresh Fails **Error**: Refresh token invalid or expired **Solution**: 1. Check token validity settings in Authentik 2. Increase refresh token validity (e.g., 86400 seconds) 3. Verify `offline_access` scope is included 4. Clear browser cookies and re-authenticate ## Advanced Configuration ### Customizing Login Flow Create custom authentication flow in Authentik: 1. Go to **Flows & Stages** → **Flows** 2. Duplicate `default-provider-authorization-implicit-consent` 3. Add custom stages (MFA, email verification, etc.) 4. Update provider to use custom flow ### Adding Multi-Factor Authentication 1. Go to **Flows & Stages** → **Stages** 2. Create authenticator validation stage 3. Add to your authorization flow 4. Users will be prompted for MFA on login ### Branding Customize Authentik appearance: 1. Go to **System** → **Branding** 2. Upload logo 3. Set primary color to match fire department branding 4. Configure footer links ### User Management Add users to Authentik: 1. Go to **Directory** → **Users** 2. Click **Create** 3. Fill in user details 4. Set password 5. Assign to groups (if using RBAC) ### Group-Based Access Control Implement role-based access: 1. Create groups in **Directory** → **Groups** 2. Assign users to groups 3. In your app, read `groups` claim from token 4. Implement authorization based on groups Example groups: - `feuerwehr-admin` - Full access - `feuerwehr-operator` - Standard access - `feuerwehr-viewer` - Read-only access ## Testing Checklist After configuration, verify: - [ ] Login redirects to Authentik - [ ] Successful authentication redirects back - [ ] User profile loads correctly - [ ] Tokens are stored securely - [ ] Logout clears session - [ ] Token refresh works - [ ] Protected routes require authentication - [ ] Invalid tokens are rejected - [ ] CORS is properly configured - [ ] Works on all browsers (Chrome, Firefox, Safari) ## Configuration Reference ### Minimum Required Settings **Authentik Provider**: ``` Client Type: Confidential Client ID: Client Secret: Redirect URIs: https://dashboard.yourdomain.com/auth/callback Scopes: openid, profile, email Access Token Validity: 3600 Refresh Token Validity: 86400 ``` **Dashboard .env**: ```bash AUTHENTIK_CLIENT_ID= AUTHENTIK_CLIENT_SECRET= AUTHENTIK_ISSUER=https://auth.yourdomain.com/application/o/feuerwehr-dashboard/ AUTHENTIK_REDIRECT_URI=https://dashboard.yourdomain.com/auth/callback ``` ## Security Best Practices 1. **Use HTTPS in production** - Never use HTTP for OAuth flows 2. **Keep secrets secret** - Never commit credentials to Git 3. **Rotate secrets regularly** - Change client secrets periodically 4. **Use strong passwords** - For Authentik admin and users 5. **Enable MFA** - Require multi-factor authentication for admin users 6. **Monitor logs** - Watch for failed login attempts 7. **Limit token validity** - Use short-lived access tokens 8. **Validate redirect URIs** - Only allow known URLs ## Additional Resources - [Authentik Documentation](https://goauthentik.io/docs/) - [OAuth 2.0 Specification](https://oauth.net/2/) - [OpenID Connect](https://openid.net/connect/) - [Authentik Community Forum](https://github.com/goauthentik/authentik/discussions) ## Support If you encounter issues: 1. Check Authentik logs: `docker-compose logs -f server` 2. Check dashboard backend logs: `make logs-prod` 3. Review browser console for errors 4. Consult [Common Issues](#common-issues) section 5. Search Authentik GitHub issues 6. Create detailed issue report --- **Next Steps**: After completing Authentik setup, proceed to [DEPLOYMENT.md](DEPLOYMENT.md) for production deployment.