configuration.yml uses Go-template substitution like
`{{ env "DOMAIN" }}` for the cookie domain, authelia_url, etc.
That substitution doesn't run by default; Authelia reads the
braces literally, fails URL parsing with `invalid character "{"
in host name`, and `domain` validation rejects the hostname for
having no period.
Setting X_AUTHELIA_CONFIG_FILTERS=template enables Authelia's
Go-template filter so the substitution runs at config load.
The env var is inherited by `docker compose run --rm authelia`,
so validate-config picks it up too.
https://claude.ai/code/session_013XZ1vmgk78k2PEQ5DmJhF3
Each of the four cases in access_control.rules now carries an inline,
clearly-labeled "ALSO PASTE INTO CADDYFILE" block above the
uncommentable Authelia rule, so the user editing configuration.yml
sees both halves of the gate in one place. Case 2a additionally shows
the matching frigate_config/config.yml edit; case 4 has no Authelia
rule but still shows the Caddy block to make the absence explicit.
Caddy blocks use {env.DOMAIN}, Authelia rules use {{ env "DOMAIN" }} --
matching what's already in caddy/snippets.caddyfile and the
configuration.yml header.
https://claude.ai/code/session_013XZ1vmgk78k2PEQ5DmJhF3
The bootstrap and add-user docs passed --password 'plaintext' on the
docker compose run command line, leaking the plaintext into shell
history (~/.bash_history, ~/.zsh_history) and the process list
(ps aux). Switched all three call sites to the interactive form
(no --password flag), which makes Authelia prompt for the password
and a confirmation without echoing.
Affected:
- README.md "Create your first user" step
- README.md "Add a user" section
- authelia/users_database.yml.example header comment
https://claude.ai/code/session_013XZ1vmgk78k2PEQ5DmJhF3
- First-run setup: replace one big bash comment block with numbered
sub-sections, each step getting its own prose explanation and separate
code block(s) so individual commands can be copied without selecting
around surrounding lines
- Step 4: add explicit table showing what happens when each side of the
Caddy/Authelia gate is missing; add policy comparison table
- Frigate section: move subnet discovery command out of YAML comment
into its own code block; separate restart commands into own blocks
- Troubleshooting "access denied": show the exact rule YAML to add
and the restart command, each in their own block
- Troubleshooting "Caddy can't resolve authelia": show full compose
YAML snippet rather than describing it in prose
- SMTP section: separate each action into its own code block
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
default_policy: deny means no rule = 403 even for logged-in users.
Step 4 now explains the two-sided requirement: Caddy controls what
traffic reaches Authelia; the rule controls what Authelia does with it.
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
Native clients (mobile, TV, desktop) DO route through Caddy via FQDN,
but cannot complete Authelia's browser-redirect login flow -- they get a
302 to auth.DOMAIN and fail. `import authelia` breaks all native clients.
Correct setup is Case 4: Caddy terminates TLS, import accesslog for
fail2ban, NO import authelia. Plex/Emby token auth handles access control.
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
- snippets.caddyfile: rename Case 2 → 2a (proxy headers); add Case 2b
(OIDC) sub-section explaining the token exchange flow, with blocks for
Audiobookshelf, Jellyfin, Immich, Mealie, Portainer
- snippets.caddyfile: add Case 1 blocks for Prometheus, Alertmanager,
Gatus, WatchYourLAN, NUT web UI
- snippets.caddyfile: add Case 3 blocks for qBittorrent, Plex (with
client-bypass caveat), Emby, Gotify, ntfy, wg-easy (with WireGuard
UDP caveat), Umami, phpIPAM, Checkmk, Snipe-IT, Zammad, Lubelog,
UniFi, MeshCentral
- README: add OIDC plain-language explanation (what it is, how it differs
from proxy-header auth, what setup it requires)
- README: expand service table to 30+ entries grouped by case; add ⚠
caveats for Plex/Emby (clients bypass Caddy)
- README: fix Case 1 header (remove phpIPAM, which has its own auth →
Case 3); fix stale `caddy/Caddyfile` reference → snippets.caddyfile
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
caddy/:
- Rename Caddyfile to snippets.caddyfile -- these are per-service snippets
to add to an existing Caddyfile, not a replacement for one
- Add per-service example blocks for Homer/Heimdall, Dozzle, Frigate,
Grafana, Gitea, Nextcloud, Paperless-ngx, Miniflux, BookStack, Immich,
Uptime Kuma, Portainer, Mealie, Home Assistant, Vaultwarden, Syncthing
with required per-app config notes inline (DotheEvo style)
- All site blocks use {env.DOMAIN}; only IPs need editing
README.md:
- Add "Should you use Authelia?" section that honestly answers when it
improves on password-manager + per-service credentials/TOTP, and when
it's marginal (single user, all services already have native TOTP)
- Expand service compatibility table from 9 to 17 entries with case
classification (1/2/3/4) and notes for each
- Fix Wire Caddy section to reference snippets.caddyfile
- Fix repo layout tree
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
Previously every example.com had to be found and replaced manually.
Now a single DOMAIN=yourdomain.com in .env propagates everywhere:
- .env.example: add DOMAIN=example.com with explanation
- docker-compose.yml: pass DOMAIN into authelia container environment
- authelia/configuration.yml: use {{ env "DOMAIN" }} in totp.issuer,
access_control.rules, and all four session.cookies[] fields
(Authelia 4.38+ Go template substitution)
- caddy/Caddyfile: use {env.DOMAIN} in all site block addresses
(Caddy native env substitution); update header comment explaining
how to set DOMAIN for system vs dockerized Caddy
- README.md: update step 3 to explain DOMAIN is the only change needed;
update step 4 to say just uncomment the right rule; update Caddy
wiring section with DOMAIN env var instructions for both Caddy modes
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
\$EDITOR is blank by default on many systems -- running it without setting
it fails silently. Added a section before the git/gh instructions that
explains what it is, how to check if it's set, how to set it for a session
or permanently in .bashrc/.zshrc, and common editor options including
VS Code with --wait.
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
Covers Debian/Ubuntu apt install for git, adding GitHub's official
apt repository (Linux tap equivalent) to install gh CLI, gh auth login
flow, and using gh repo clone as the step-0 clone command so credentials
are handled automatically.
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
First-run was missing the git clone command entirely.
Uses the `authelia` branch name since that's the long-term home
for this stack (separate from the `main` Frigate branch).
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
Keeps this as a standalone authelia+fail2ban stack (no Frigate services).
Changes:
- docker-compose.yml: fail2ban depends_on authelia with service_healthy
condition so authelia.log exists before fail2ban tries to bind-mount it;
add inline note about pre-creating the log file
- authelia/configuration.yml: expand access_control comment block to cover
all 4 cases (added Case 3: app keeps own auth + Authelia as 2FA gate,
and Case 4: app handles auth alone); clearer per-case commented rules
- caddy/Caddyfile (replaces snippet.example.caddyfile): complete Caddyfile
with all 4 auth-case examples; (accesslog) imported in every block so
fail2ban caddy-4xx jail covers all subdomains, not just gated ones;
full inline docs for enabling Frigate proxy auth
- README.md: expand "Which sites" from 3 to 4 cases; add proxy-auth service
compatibility table (Frigate, Grafana, Gitea, Nextcloud, HA, Portainer
etc.); clarify fail2ban covers all sites via single caddy-4xx jail;
add touch authelia/authelia.log to first-run; add troubleshooting entries
for authelia.log bind-mount directory bug and fail2ban chain verification
https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
- 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
Self-hosted SSO portal with file-based users, SQLite storage, filesystem
notifier, and an iptables-banning fail2ban sidecar. Designed to drop into
a DotheEvo-style ~/docker layout next to a dockerized Caddy on the main
server, joining the same external caddy_net so Caddy reaches Authelia by
container name. fail2ban runs in host network mode with NET_ADMIN/NET_RAW
caps so its bans hit DOCKER-USER and actually drop packets at the edge.
Includes a Caddy snippet (caddy/snippet.example.caddyfile) to merge into
the user's real Caddyfile -- this repo doesn't manage Caddy itself.
https://claude.ai/code/session_013XZ1vmgk78k2PEQ5DmJhF3