--- ############################################################################### # Authelia configuration # # - File-based user database (no LDAP) # - SQLite local storage (no Redis, no MySQL/Postgres) # - Filesystem notifier (writes "emails" to /config/notifications/...) # - Argon2id password hashing # - Per-domain access policies under access_control.rules # # Secrets are NOT in this file. They are loaded from files mounted at # /secrets via the AUTHELIA_*_FILE env vars in docker-compose.yml. # # After editing, validate before restarting: # docker compose run --rm authelia authelia validate-config --config /config/configuration.yml ############################################################################### theme: 'dark' server: address: 'tcp://0.0.0.0:9091' buffers: read: 8192 write: 8192 log: level: 'info' format: 'text' # fail2ban filter expects text format file_path: '/config/authelia.log' keep_stdout: true # also log to stdout for `docker logs` identity_validation: reset_password: jwt_lifespan: '5 minutes' jwt_algorithm: 'HS256' # jwt_secret loaded via AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE totp: disable: false issuer: 'example.com' # CHANGE: your root domain (shown in authenticator app) algorithm: 'sha1' digits: 6 period: 30 authentication_backend: password_change: disable: false password_reset: disable: false refresh_interval: '5 minutes' file: path: '/config/users_database.yml' password: algorithm: 'argon2' argon2: variant: 'argon2id' iterations: 3 memory: 65536 parallelism: 4 key_length: 32 salt_length: 16 # --------------------------------------------------------------------------- # Access control # # default_policy: deny means every domain that Caddy forwards here must # have an explicit allow rule. Caddy only forwards when a site block has # `import authelia`, so domains where you keep the app's own auth (no # `import authelia` in Caddy) bypass Authelia entirely and don't need # rules here. # # Policies: # bypass Authelia waves the request through (used for the portal) # one_factor password only # two_factor password + TOTP # # Decision tree for whether a site needs an Authelia rule at all: # # - App has NO built-in auth (doorbell PTT page) -> rule here + # `import authelia` in Caddy. Use two_factor for anything that # controls hardware in the house. # # - App has built-in auth but supports trusted-header proxy auth # (Frigate 0.14+, Grafana, Gitea, Jellyfin, ...) -> rule here + # `import authelia` in Caddy AND switch the app to proxy auth in # its own config. Single login (Authelia), 2FA, app keeps its own # user/role mapping driven from Authelia headers. # # - App has built-in auth and CAN'T switch (router admin, legacy # things) -> NO rule here, NO `import authelia` in Caddy. The # traffic skips Authelia entirely; the app handles its own login. # --------------------------------------------------------------------------- access_control: default_policy: 'deny' rules: # The Authelia portal itself is always bypass. - domain: 'auth.example.com' # CHANGE policy: 'bypass' # ----- Apps with NO built-in auth: Authelia is the only gate ----- # The Pi doorbell PTT page has no app-level auth, so Authelia is it. # 2FA is appropriate -- this URL controls a speaker in your house. # - domain: 'doorbell.example.com' # policy: 'two_factor' # ----- Apps that switched FROM their own auth TO Authelia ----- # Frigate 0.14+ supports trusted-header proxy auth. To use this: # 1. In frigate_config/config.yml, set `auth.enabled: False` # and add a `proxy:` block with `header_map.user: remote-user` # and `header_map.role: remote-groups` (see README). # 2. `import authelia` in the cam.* Caddy block. # 3. Add the rule below. # - domain: 'cam.example.com' # policy: 'two_factor' # ----- Apps that KEEP their own auth ----- # Don't add a rule and don't `import authelia` in their Caddy block. # Example: a router admin page on `router.example.com` -- no rule # appears here, the request never reaches Authelia. session: # secret loaded via AUTHELIA_SESSION_SECRET_FILE cookies: - name: 'authelia_session' domain: 'example.com' # CHANGE: your root domain authelia_url: 'https://auth.example.com' # CHANGE default_redirection_url: 'https://example.com' # CHANGE expiration: '1 hour' inactivity: '5 minutes' remember_me: '1 month' same_site: 'lax' # In-app rate limiting. First line of defense; fail2ban is the second. regulation: max_retries: 3 find_time: '2 minutes' ban_time: '5 minutes' storage: # encryption_key loaded via AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE local: path: '/config/db.sqlite3' # Filesystem notifier -- password reset / new device emails get written to # a file you can `tail -f`. Swap to `smtp:` when you wire up a real # transactional sender. notifier: disable_startup_check: false filesystem: filename: '/config/notifications/notification.txt'