- Pin AUTHELIA_VERSION=4.39.19 (current stable, released 2026-04-12) and FAIL2BAN_VERSION=1.1.0-r0 in .env.example + docker-compose.yml. - Reshape access_control.rules and the Caddyfile snippet around a three-case decision tree: no app auth (Authelia is the gate), app with proxy-auth support (switch FROM app login TO Authelia headers), and apps that keep their own login (skip Authelia entirely). - Document Frigate 0.14+ proxy auth specifically: auth.enabled: False, proxy.header_map (remote-user / remote-groups), trusted_proxies for the caddy_net subnet, optional X-Proxy-Secret for cross-VLAN trust. https://claude.ai/code/session_013XZ1vmgk78k2PEQ5DmJhF3
151 lines
5.2 KiB
YAML
151 lines
5.2 KiB
YAML
---
|
|
###############################################################################
|
|
# 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'
|