DEV Community

Cover image for Deploying Authelia Open-Source Authentication and Authorization Gateway on Ubuntu 24.04
Sanskriti Harmukh for Vultr

Posted on with Aashish Chaurasiya • Originally published at docs.vultr.com

Deploying Authelia Open-Source Authentication and Authorization Gateway on Ubuntu 24.04

Authelia is an open-source authentication and authorization gateway that adds SSO, two-factor authentication, and policy-based access control in front of web applications, integrating natively with reverse proxies through forward-auth. This guide deploys Authelia using Docker Compose with Traefik handling automatic HTTPS, file-backed users, TOTP 2FA, and a sample whoami app protected by forward-auth. By the end, you'll have Authelia gating multiple subdomains with SSO and 2FA over HTTPS.


Set Up the Directory Structure

1. Create the project directory structure:

$ mkdir -p ~/authelia/{config,secrets,logs}
$ cd ~/authelia
Enter fullscreen mode Exit fullscreen mode

2. Create the environment file:

$ nano .env
Enter fullscreen mode Exit fullscreen mode
DOMAIN=example.com
LETSENCRYPT_EMAIL=admin@example.com
Enter fullscreen mode Exit fullscreen mode

DNS A records for auth.${DOMAIN}, app.${DOMAIN}, and traefik.${DOMAIN} must point at the server.


Generate Authelia Secrets

1. Own the secrets directory:

$ sudo chown 8000:8000 ./secrets
$ sudo chmod 0700 ./secrets
Enter fullscreen mode Exit fullscreen mode

2. Generate session, storage, and JWT secrets in one shot:

$ docker run --rm -u 8000:8000 -v ./secrets:/secrets docker.io/authelia/authelia:4.39 \
    sh -c "cd /secrets && authelia crypto rand --length 64 session_secret.txt storage_encryption_key.txt jwt_secret.txt"
Enter fullscreen mode Exit fullscreen mode

Write the Authelia Configuration

1. Create the configuration file:

$ nano config/configuration.yml
Enter fullscreen mode Exit fullscreen mode
server:
  address: 'tcp4://:9091'

log:
  level: 'info'
  file_path: '/var/log/authelia/authelia.log'
  keep_stdout: true

identity_validation:
  elevated_session:
    require_second_factor: true
  reset_password:
    jwt_lifespan: '5 minutes'
    jwt_secret: {{ secret "/secrets/jwt_secret.txt" | mindent 0 "|" | msquote }}

totp:
  disable: false
  issuer: 'example.com'
  period: 30
  skew: 1

authentication_backend:
  file:
    path: '/config/users.yml'
    password:
      algorithm: 'argon2'
      argon2:
        variant: 'argon2id'
        iterations: 3
        memory: 65535
        parallelism: 4
        key_length: 32
        salt_length: 16

access_control:
  default_policy: 'deny'
  rules:
    - domain: 'app.example.com'
      policy: 'two_factor'
    - domain: 'traefik.example.com'
      policy: 'one_factor'

session:
  name: 'authelia_session'
  secret: {{ secret "/secrets/session_secret.txt" | mindent 0 "|" | msquote }}
  cookies:
    - domain: 'example.com'
      authelia_url: 'https://auth.example.com'

regulation:
  max_retries: 4
  find_time: 120
  ban_time: 300

storage:
  encryption_key: {{ secret "/secrets/storage_encryption_key.txt" | mindent 0 "|" | msquote }}
  local:
    path: '/config/db.sqlite3'

notifier:
  disable_startup_check: false
  filesystem:
    filename: '/config/notification.txt'
Enter fullscreen mode Exit fullscreen mode

2. Generate an argon2 hash for the first user's password:

$ docker run --rm authelia/authelia:4.39 authelia crypto hash generate argon2 --password 'your-secure-password'
Enter fullscreen mode Exit fullscreen mode

3. Create the user database with that hash:

$ nano config/users.yml
Enter fullscreen mode Exit fullscreen mode
users:
  authuser:
    displayname: 'Auth User'
    password: '$argon2id$v=19$m=65536,t=3,p=4$BpLnfgDsc2WD8F2q$Zis.ixdg9s/UOJYrs56b5QEZFiZECu0qZVNsIYxBaNJ7ucIL.nlxVCT5tqh8KHG8X4tlwCFm5r6NTOZZ5qRFN/'
    email: 'authuser@example.com'
    groups:
      - 'admin'
Enter fullscreen mode Exit fullscreen mode

Deploy with Docker Compose

1. Create the Docker Compose manifest:

$ nano docker-compose.yaml
Enter fullscreen mode Exit fullscreen mode
services:
  traefik:
    image: traefik:v3.6
    container_name: traefik
    depends_on:
      - authelia
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.email=${LETSENCRYPT_EMAIL}"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.${DOMAIN}`)"
      - "traefik.http.routers.dashboard.entrypoints=websecure"
      - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
      - "traefik.http.routers.dashboard.service=api@internal"
      - "traefik.http.routers.dashboard.middlewares=authelia@docker"
    restart: unless-stopped

  authelia:
    image: authelia/authelia:4.39
    container_name: authelia
    volumes:
      - "./secrets:/secrets:ro"
      - "./config:/config"
      - "./logs:/var/log/authelia"
    environment:
      TZ: "UTC"
      X_AUTHELIA_CONFIG_FILTERS: "template"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.authelia.rule=Host(`auth.${DOMAIN}`)"
      - "traefik.http.routers.authelia.entrypoints=websecure"
      - "traefik.http.routers.authelia.tls.certresolver=letsencrypt"
      - "traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth"
      - "traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true"
      - "traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email"
    restart: unless-stopped

  whoami:
    image: traefik/whoami
    container_name: whoami
    depends_on:
      - authelia
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`app.${DOMAIN}`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
      - "traefik.http.routers.whoami.middlewares=authelia@docker"
    restart: unless-stopped
Enter fullscreen mode Exit fullscreen mode

2. Start the services:

$ docker compose up -d
Enter fullscreen mode Exit fullscreen mode

3. Verify the services are running:

$ docker compose ps
$ docker compose logs
Enter fullscreen mode Exit fullscreen mode

Register TOTP and Test SSO

1. Open the login portal:

Navigate to https://auth.example.com and sign in as authuser.

2. Register a TOTP device:

Click Register device and capture the verification code from the filesystem notifier:

$ docker compose exec authelia cat /config/notification.txt
Enter fullscreen mode Exit fullscreen mode

Scan the QR code with an authenticator app and enter the 6-digit code.

3. Visit a protected app:

Open https://app.example.com — the request redirects through Authelia for password + TOTP, then the whoami container returns the injected identity headers.

4. Confirm SSO:

Open https://traefik.example.com from the same browser — no re-authentication required.


Next Steps

Authelia is gating multiple subdomains with SSO and 2FA. From here you can:

  • Protect more apps by adding traefik.http.routers.<svc>.middlewares=authelia@docker and a matching access_control rule
  • Switch the authentication backend to LDAP or OpenID Connect 1.0
  • Configure SMTP under notifier to deliver verification codes by email

For the full guide with additional tips, visit the original article on Vultr Docs.

Top comments (1)

Collapse
 
voltagegpu profile image
VoltageGPU

I've used Authelia in a few internal projects to secure microservices without overcomplicating the setup. One thing I found helpful was integrating it with existing LDAP setups for smoother user management. If you're working on Ubuntu 24.04, make sure to test the latest Authelia version with systemd socket activation for better performance.