# ============================================================================= # Authelia + Caddy integration snippets # # Merge these blocks into your real Caddyfile (typically the one your # dockerized Caddy mounts from its own ~/docker/caddy/ folder). Reload Caddy # after editing: # docker compose -f ~/docker/caddy/docker-compose.yml exec caddy \ # caddy reload --config /etc/caddy/Caddyfile # # Requires: # - Caddy v2.5.1 or newer # - Caddy joined to the external `caddy_net` docker network so it can # resolve `authelia` by container name # # ----------------------------------------------------------------------------- # DECISION TREE: which sites go behind Authelia? # # 1. App has NO built-in auth (e.g. the Pi doorbell PTT page). # -> `import authelia` here AND add a rule in # authelia/configuration.yml access_control.rules. Use # two_factor for anything that controls hardware. # # 2. App has built-in auth AND supports trusted-header proxy auth # (Frigate 0.14+, Grafana, Gitea, Jellyfin, Portainer, ...). # -> `import authelia` here, add a rule in Authelia, AND switch # the app's own config to consume Remote-User from upstream # (disable its built-in login form). One login, 2FA, app # still owns its user/role mapping. See the cam.* example # and the README for Frigate specifics. # # 3. App has built-in auth and CAN'T switch (router admin pages, # odd legacy things). # -> Plain `reverse_proxy` block. NO `import authelia`, NO # Authelia rule. The traffic skips Authelia entirely. # ============================================================================= # ----------------------------------------------------------------------------- # Reusable forward_auth snippet for cases (1) and (2). Import into any site # block you want gated by Authelia. # ----------------------------------------------------------------------------- (authelia) { forward_auth authelia:9091 { uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Email Remote-Name } } # ----------------------------------------------------------------------------- # Caddy access logging -- fail2ban needs JSON access logs at a host path # both Caddy and fail2ban can see. Mount /var/log/caddy in BOTH compose # files (Caddy as rw, fail2ban as ro). The roll directives keep it bounded. # ----------------------------------------------------------------------------- (accesslog) { log { output file /var/log/caddy/access.log { roll_size 10MiB roll_keep 5 roll_keep_for 720h } format json } } # ============================================================================= # Site blocks # ============================================================================= # ----------------------------------------------------------------------------- # Authelia login portal -- always bypass in access_control.rules. # ----------------------------------------------------------------------------- auth.example.com { import accesslog reverse_proxy authelia:9091 } # ----------------------------------------------------------------------------- # CASE 1: app has NO built-in auth. # Pi doorbell PTT page -- Authelia is the only gate. two_factor in Authelia. # ----------------------------------------------------------------------------- doorbell.example.com { import accesslog import authelia handle_path /frigate/* { reverse_proxy 192.168.x.x:8971 { transport http { read_timeout 60s write_timeout 60s } } } handle { reverse_proxy 192.168.x.x:5555 } } # ----------------------------------------------------------------------------- # CASE 2: app supports trusted-header proxy auth. # Frigate UI -- Authelia gates access AND Frigate consumes Remote-User from # upstream so its own role mapping (admin/viewer) still works. To use this, # also edit frigate_config/config.yml: # # auth: # enabled: False # trusted_proxies: # - 172.18.0.0/16 # your caddy_net subnet, see README # proxy: # header_map: # user: remote-user # role: remote-groups # default_role: viewer # separator: '|' # # Optional but recommended when Caddy and Frigate are on different # # hosts/VLANs. Generate with `openssl rand -hex 32` and add the # # matching `header_up X-Proxy-Secret ` below. # # auth_secret: 'paste-32-byte-hex-here' # ----------------------------------------------------------------------------- cam.example.com { import accesslog import authelia reverse_proxy 192.168.x.x:8971 { transport http { read_timeout 60s write_timeout 60s } # Uncomment and match Frigate's auth_secret if you set one above. # header_up X-Proxy-Secret "paste-same-32-byte-hex-here" } } # ----------------------------------------------------------------------------- # CASE 3: app keeps its own auth (no Authelia involvement). # Example: a router admin page or a service that can't do proxy auth. # Do NOT add `import authelia` and do NOT add an access_control rule for it. # ----------------------------------------------------------------------------- # router.example.com { # import accesslog # reverse_proxy 192.168.1.1:443 { # transport http { # tls_insecure_skip_verify # } # } # }