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>
This commit is contained in:
parent
37410ed362
commit
31b66d23b9
105
README.md
105
README.md
@ -0,0 +1,105 @@
|
|||||||
|
# authelia
|
||||||
|
|
||||||
|
[Authelia](https://www.authelia.com/) 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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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.
|
||||||
Loading…
Reference in New Issue
Block a user