Files
dashboard/AUTHENTIK_SETUP.md
Matthias Hochmeister f09748f4a1 inital
2026-02-23 17:08:58 +01:00

15 KiB

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

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.

Create docker-compose.yml:

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:

PG_PASS=<secure-database-password>
AUTHENTIK_SECRET_KEY=<generate-with-openssl-rand-base64-32>
AUTHENTIK_PORT_HTTP=9000
AUTHENTIK_PORT_HTTPS=9443

Start Authentik:

docker-compose up -d

Access Authentik at http://localhost:9000 and complete the initial setup wizard.

Option 2: Kubernetes

See Authentik Kubernetes Documentation 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 ApplicationsProviders
  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 ApplicationsApplications
  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 ProvidersFeuerwehr Dashboard Provider
  2. Scroll to Advanced protocol settings
  3. Click Edit on Scopes

Ensure the following scopes are selected:

  • openid - Required for OpenID Connect
  • profile - User profile information
  • 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):

scopes: ['openid', 'profile', 'email']

Frontend login flow (frontend/src/services/authService.ts):

const scopes = 'openid profile email';

Getting Client Credentials

Step 7: Copy Client Credentials

  1. Go to ApplicationsProviders
  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:

# Authentik OAuth Configuration
AUTHENTIK_CLIENT_ID=<your-client-id>
AUTHENTIK_CLIENT_SECRET=<your-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:

    # 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:

make logs-prod
# or
cd backend && npm run dev

Look for:

[INFO] OAuth callback received
[INFO] Token exchange successful
[INFO] User authenticated: <username>

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:
    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 & StagesFlows
  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 & StagesStages
  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 SystemBranding
  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 DirectoryUsers
  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 DirectoryGroups
  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: <auto-generated>
Client Secret: <auto-generated>
Redirect URIs: https://dashboard.yourdomain.com/auth/callback
Scopes: openid, profile, email
Access Token Validity: 3600
Refresh Token Validity: 86400

Dashboard .env:

AUTHENTIK_CLIENT_ID=<from-authentik>
AUTHENTIK_CLIENT_SECRET=<from-authentik>
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

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 section
  5. Search Authentik GitHub issues
  6. Create detailed issue report

Next Steps: After completing Authentik setup, proceed to DEPLOYMENT.md for production deployment.