authelia/README.md
Travis Herbranson 31b66d23b9 docs: write operator README
Repo had a 0-byte README. New one covers:
- Service inventory (authelia + redis) with in-network ports
- What the stack provides (login portal + forwardAuth middleware)
- How to chain authelia-auth onto other Traefik routes
- File-based authentication backend + how to mint argon2id hashes
- Configuration file inventory + the three secret env vars
- Volume / persistence model (sqlite + Redis session store)
- Tailscale-hostname coupling + default one_factor policy as gotchas

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 07:47:51 -04:00

3.8 KiB

authelia

Authelia deployment for the homelab — provides forward-auth for Traefik-fronted services. Single-factor by default, with TOTP available.

Services

Service Image Port (in-network)
authelia authelia/authelia:latest 9091
authelia-redis redis:alpine 6379

No host ports are published — both services are reachable only on the external traefik docker network. Traefik exposes Authelia at https://us-test-authy.taila7f44e.ts.net/authelia/ via Tailscale-issued certs.

What this stack provides

  • A /authelia portal for login, password reset, and TOTP enrollment.
  • A authelia-auth forwardAuth middleware that other Traefik routes can chain onto for SSO-style gated access.

The forward-auth middleware is declared by labels on the authelia service:

traefik.http.middlewares.authelia-auth.forwardAuth.address=http://authelia:9091/authelia/api/authz/forward-auth

To gate any other Traefik route, add the middleware to that service's labels:

traefik.http.routers.<svc>.middlewares=authelia-auth@docker

Authentication backend

File-based, not LDAP. Users live in users_database.yml at the repo root, mounted read-only into the container at /config/users_database.yml. Passwords are argon2id hashes — generate with:

docker run --rm authelia/authelia:latest \
    authelia crypto hash generate argon2

Then paste the resulting $argon2id$... string under users.<id>.password.

Configuration

File Purpose
configuration.yml Server settings, access-control rules, session + storage, notifier
users_database.yml File-based user records (id, displayname, argon2id hash, email, groups)
compose.yml Service definitions + Traefik labels + secret env vars

Three secrets are injected as env vars in compose.yml:

  • AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET
  • AUTHELIA_SESSION_SECRET
  • AUTHELIA_STORAGE_ENCRYPTION_KEY

Rotate by replacing those values; restart the stack to pick them up.

Run it

docker compose up -d
docker compose logs -f authelia

Persistence

Volume Purpose
authelia_data /config — sqlite storage (db.sqlite3), notifications
authelia_redis /data — Redis session store

Sessions are kept in Redis (in-memory + AOF), so an authelia-redis restart loses active logins. Persistent state (TOTP secrets, password resets) is in the sqlite DB inside authelia_data.

Gotchas

  • Hard-coded Tailscale hostname. The TOTP issuer, cookie domain, and access-control rule all reference us-test-authy.taila7f44e.ts.net (this host's Tailscale magic-DNS name). Changing the host requires editing configuration.yml, compose.yml Traefik labels, and any clients with TOTP secrets enrolled under the old issuer.
  • access_control.default_policy: one_factor. No 2FA-required rules in the file by default — anything routed through authelia-auth middleware lets users in with just a password. Tighten to two_factor for high-sensitivity services by adding a rules: entry above the default.
  • External traefik network must exist before this stack starts — it's created by the traefik stack in this same docker/ directory.
  • The repo also contains some leftover uv-init artifacts (main.py, pyproject.toml, uv.lock, .python-version). These are not part of the deployment.