From ddf00fbf90e15002fcf08720422b94e3bcdf1137 Mon Sep 17 00:00:00 2001 From: Wayne Hayes Date: Thu, 11 Jun 2026 21:30:18 -0400 Subject: [PATCH 1/3] authelia: vendor into the tree under authelia/ with a single root .env MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the Authelia stack (compose, config, snippets, docs) out of the separate /opt/authelia repo into authelia/, so the whole deployment shares ONE operator .env at the repo root. The four shared infra vars (TS_OAUTH_CLIENT_SECRET, TS_TAILNET, DB_MAGIC_NAME, REDIS_MAGIC_NAME) are defined once; authelia/.env is a symlink to ../.env (gitignored, recreated per host). .env.example + .gitignore folded in. Run from the repo root: docker compose -f authelia/docker-compose.yml up -d (or: cd authelia && docker compose up -d — the .env symlink makes it resolve). The standalone /opt/authelia is left intact as a history archive; remove once this is verified. Co-Authored-By: Claude Opus 4.8 --- .env.example | 52 ++++++++++++++++++ .gitignore | 5 ++ authelia/CLAUDE.md | 83 +++++++++++++++++++++++++++++ authelia/README.md | 52 ++++++++++++++++++ authelia/acl-snippet.hujson | 18 +++++++ authelia/caddy-forward-auth.snippet | 27 ++++++++++ authelia/config/configuration.yml | 73 +++++++++++++++++++++++++ authelia/config/users_database.yml | 10 ++++ authelia/docker-compose.yml | 71 ++++++++++++++++++++++++ 9 files changed, 391 insertions(+) create mode 100644 authelia/CLAUDE.md create mode 100644 authelia/README.md create mode 100644 authelia/acl-snippet.hujson create mode 100644 authelia/caddy-forward-auth.snippet create mode 100644 authelia/config/configuration.yml create mode 100644 authelia/config/users_database.yml create mode 100644 authelia/docker-compose.yml diff --git a/.env.example b/.env.example index c58ba2f..99b1245 100644 --- a/.env.example +++ b/.env.example @@ -82,3 +82,55 @@ STALWART_SMARTHOST= # a certbot-issued cert (see config/config.toml [certificate]). STALWART_ACME_PROVIDER= STALWART_ACME_TOKEN= + + +# ============================================================================ +# AUTHELIA — merged from /opt/authelia. Shares TS_OAUTH_CLIENT_SECRET, TS_TAILNET, +# DB_MAGIC_NAME, REDIS_MAGIC_NAME from the stalwart section above. +# ============================================================================ +# ============================================================================ +# authelia — operator configuration (SSO / 2FA / OIDC, Tailscale sidecar) +# ============================================================================ +# Copy to .env and fill in. Self-contained stack at /opt/authelia, outside any +# upstream repo. Reuses the shared tailnet Postgres + Redis + SMTP relay. +# +# Authelia is a forward-auth / OIDC provider: it runs tailnet-only and the main +# box Caddy fronts its portal (auth.) and routes protected vhosts +# through its /api/verify endpoint. See caddy-forward-auth.snippet. +# ============================================================================ + +# Tailscale — same OAuth client as the rest of the tailnet (tag:authelia). +AUTHELIA_MAGIC_NAME=authelia + +# Identity / cookie scope. Portal lives at AUTHELIA_PORTAL_URL; the session +# cookie is valid across *.AUTHELIA_DOMAIN. +AUTHELIA_DOMAIN=infinidim.net +AUTHELIA_PORTAL_URL=https://auth.infinidim.net + +# Postgres (shared) — storage backend (users' 2FA devices, identity, consent). +AUTHELIA_DB_NAME=authelia +AUTHELIA_DB_USER=authelia +# Generate: openssl rand -hex 24 +AUTHELIA_DB_PASSWORD= + +# Redis (shared) — session backend. Dedicated logical DB index. +AUTHELIA_REDIS_DB=4 + +# SMTP relay (shared) — password-reset + 2FA notifications. +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_USER= +SMTP_PASSWORD= +AUTHELIA_SMTP_SENDER=no-reply@infinidim.net + +# Authelia secrets. Generate each: openssl rand -hex 32 +AUTHELIA_SESSION_SECRET= +AUTHELIA_STORAGE_ENCRYPTION_KEY= +AUTHELIA_JWT_SECRET= +AUTHELIA_OIDC_HMAC_SECRET= + +# First admin (web portal login). The hash goes in config/users_database.yml: +# docker run --rm authelia/authelia:latest \ +# authelia crypto hash generate argon2 --password 'YOURPASS' +AUTHELIA_ADMIN_USER=admin +AUTHELIA_ADMIN_PASSWORD= diff --git a/.gitignore b/.gitignore index 699fae5..623125c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,11 @@ export/ # config and is secret-free (DB password comes from $STALWART_DB_PASSWORD via # the EnvironmentVariable secret type). Don't add it here. +# Authelia (moved under authelia/) — single .env lives at repo root; authelia/.env +# is a symlink to it (matched by the .env rule above). Plus its runtime data. +authelia/config/*.db +authelia/config/notification.txt + # Editor swap / backup files *.swp *.swo diff --git a/authelia/CLAUDE.md b/authelia/CLAUDE.md new file mode 100644 index 0000000..e55602f --- /dev/null +++ b/authelia/CLAUDE.md @@ -0,0 +1,83 @@ +# CLAUDE.md — authelia + +Guidance for Claude Code in this repo. Read before editing. + +## What this is + +A standalone [Authelia](https://www.authelia.com/) deployment — SSO portal, 2FA, +and (optional) OIDC provider — as a Tailscale sidecar, plugged into the shared +tailnet **Postgres** (storage) and **Redis** (sessions), with the shared **SMTP +relay** for reset/2FA mail. Sibling to `tailwart`; same pattern, different job. +Domain: `infinidim.net` (portal `auth.infinidim.net`). + +Self-contained and **outside** any upstream repo (own `.env`, compose, config, +ACL snippet). Reads only the tailnet at runtime. + +## Architecture + +``` + main box Caddy (tag:reverse-proxy) tailnet-only auth + ┌────────────────────────────┐ ┌───────────────────────┐ + │ auth.infinidim.net ───────┼──────────────▶│ ts-authelia sidecar │ + │ reverse_proxy :9091 │ tailnet │ authelia (no WAN, no │ + │ protected vhosts: │ │ host ports) :9091 │ + │ forward_auth → :9091 │ └──────────┬─────────────┘ + └────────────────────────────┘ │ + ┌───────┴───────┐ + ▼ ▼ ▼ + Postgres Redis SMTP relay +``` + +- **Sidecar** (`tag:authelia`), `network_mode: service:ts-authelia`, no host ports. +- Authelia listens `:9091` on the tailnet. The **main box Caddy** (layer 7, not + a separate edge) fronts the portal and wires `forward_auth` for protected + services — see `caddy-forward-auth.snippet`. This is ordinary L7, unlike + tailwart's L4 mail edge. +- Storage → Postgres (`authelia` role/db), sessions → Redis (logical DB + `AUTHELIA_REDIS_DB`), mail → shared relay. + +## The `.env` contract + +`.env` (gitignored) is the whole surface. Secrets and infra hostnames reach +Authelia as `AUTHELIA_*` **env overrides** (set in `docker-compose.yml`), which +take precedence over `config/configuration.yml`. That keeps the committed yml +free of secrets and MagicDNS names. The yml holds only non-secret structure +(access_control, session.cookies, totp, regulation). + +## Prerequisites (shared tailnet infra) + +1. Postgres role+db: `authelia` / `AUTHELIA_DB_NAME`. Create via a one-off + `CREATE ROLE authelia LOGIN PASSWORD '…'; CREATE DATABASE authelia OWNER + authelia;` against `the-record-prod` (the federatedSocial shared Postgres). +2. Redis: nothing to create — uses logical DB index `AUTHELIA_REDIS_DB` (4) so + it won't collide with the fediverse apps or tailwart (which uses 3). +3. `config/users_database.yml`: at least one user with an argon2id hash: + `docker run --rm authelia/authelia:latest authelia crypto hash generate + argon2 --password 'PASS'`. +4. Admin console: assign `tag:authelia` to the OAuth client (Devices/Core + + Keys/AuthKeys) and add `acl-snippet.hujson` to the policy. +5. Main box Caddy: add `caddy-forward-auth.snippet` (portal vhost + the + `(authelia)` import) and a cert for `auth.infinidim.net`. + +## Pitfalls + +- **Authelia config schema drifts hard between minor versions** (4.37→4.38 moved + session to `cookies[]`, added `identity_validation`, changed `storage.postgres` + to `address`). The image is **pinned to 4.39.20** and the yml passes + `authelia config validate` against it. Re-validate before bumping the tag: + `docker run --rm -e ... -v ./config:/config:ro authelia/authelia: authelia config validate`. +- **Don't put secrets in `configuration.yml`.** Use the `AUTHELIA_*` env path. +- **Redis DB index collisions.** tailwart=3, authelia=4. Keep them distinct. +- **Postgres password drift.** Role passwords only apply on `CREATE`/`ALTER`; + test auth over the **tailnet** (scram), never `127.0.0.1` (that pg_hba line is + `trust` and accepts any password — it'll lie to you). +- **forward_auth is layer 7**, on the main Caddy. Don't confuse it with + tailwart's L4 edge — different mechanism entirely. + +## What not to do + +- Don't write into `/opt/federatedSocial` (read its `.env` if needed). +- Don't add `ports:` to the Authelia container — the main Caddy is the only + public path in. +- Don't commit `.env`. +- Don't break the sidecar netns boundary. diff --git a/authelia/README.md b/authelia/README.md new file mode 100644 index 0000000..49058f4 --- /dev/null +++ b/authelia/README.md @@ -0,0 +1,52 @@ +# authelia + +> SSO / 2FA / OIDC for `infinidim.net`, as a tailnet sidecar. Storage in +> Postgres, sessions in Redis, mail via the shared relay — no WAN presence; +> the main box Caddy fronts the portal and gates protected vhosts. + +Standalone sibling to [tailwart](/opt/tailwart). See [CLAUDE.md](./CLAUDE.md). + +## Layout + +``` +authelia/ +├── docker-compose.yml # ts-authelia sidecar + authelia +├── config/ +│ ├── configuration.yml # non-secret structure (4.38 strawman) +│ └── users_database.yml # file backend — admin user (argon2id) +├── caddy-forward-auth.snippet # portal vhost + (authelia) import for box Caddy +├── acl-snippet.hujson # tag:authelia owner + backend/edge grants +├── .env.example # operator surface +└── .gitignore +``` + +## Quickstart + +```bash +cp .env.example .env && $EDITOR .env # (a generated .env is already here) + +# 1. create the authelia role/db in shared Postgres: +docker exec -i federated-shared-db-postgres-1 psql -U postgres <<'SQL' +DO $$ BEGIN + IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname='authelia') THEN + CREATE ROLE authelia LOGIN PASSWORD 'PASTE_AUTHELIA_DB_PASSWORD'; + END IF; +END $$; +SELECT 'CREATE DATABASE authelia OWNER authelia' + WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname='authelia')\gexec +SQL + +# 2. admin console: assign tag:authelia to the OAuth client + paste acl-snippet +# 3. bring up (tailnet-only) +docker compose up -d +# 4. add caddy-forward-auth.snippet to the main box Caddy + a cert for auth.infinidim.net +``` + +Then log in at `https://auth.infinidim.net` with the admin user from `.env`. + +## Status + +Pinned to Authelia **4.39.20**. `configuration.yml` passes `authelia config +validate` against that image with the real env — schema and secrets check out. +Runtime backends (Postgres/Redis/SMTP connectivity) get exercised on the first +`docker compose up`. diff --git a/authelia/acl-snippet.hujson b/authelia/acl-snippet.hujson new file mode 100644 index 0000000..af0b4cb --- /dev/null +++ b/authelia/acl-snippet.hujson @@ -0,0 +1,18 @@ +// authelia — merge into your live Tailscale policy (admin console). Snippet only. + +// 1) tagOwners — self-ownership required for auth-key node creation: +// "tag:authelia": ["autogroup:admin", "tag:authelia"], + +// 2) grants — Authelia reaches its two shared backends: +{ "src": ["tag:authelia"], "dst": ["tag:db-postgres"], "ip": ["tcp:5432"] }, +{ "src": ["tag:authelia"], "dst": ["tag:db-redis"], "ip": ["tcp:6379"] }, + +// 3) grant — the main Caddy (tag:reverse-proxy) reaches the portal/verify API. +{ "src": ["tag:reverse-proxy"], "dst": ["tag:authelia"], "ip": ["tcp:9091"] }, + +// 4) admin console (not this file): assign tag:authelia to the same OAuth +// client, on the Devices/Core + Keys/AuthKeys scopes. + +// NOTE on SMTP: the sidecar reaches the relay (smtp.infinidim.net:587) the same +// way the fediverse apps do. If that relay is a TAILNET host (not public), +// add: { "src": ["tag:authelia"], "dst": [""], "ip": ["tcp:587"] } diff --git a/authelia/caddy-forward-auth.snippet b/authelia/caddy-forward-auth.snippet new file mode 100644 index 0000000..64d82d9 --- /dev/null +++ b/authelia/caddy-forward-auth.snippet @@ -0,0 +1,27 @@ +# Add to the MAIN box Caddyfile (/etc/caddy/Caddyfile). Authelia is layer 7, +# so unlike tailwart's mail edge it's an ordinary reverse_proxy + forward_auth. +# Replace majikthise with your AUTHELIA_MAGIC_NAME. + +# 1) The Authelia portal itself. +auth.infinidim.net { + import common_log + reverse_proxy majikthise.tail7b1641.ts.net:9091 + tls /etc/caddy/certs/auth.infinidim.net/fullchain.pem \ + /etc/caddy/certs/auth.infinidim.net/privkey.pem +} + +# 2) A reusable forward-auth snippet — import it into any vhost you want SSO on. +(authelia) { + forward_auth majikthise.tail7b1641.ts.net:9091 { + uri /api/verify?rd=https://auth.infinidim.net + copy_headers Remote-User Remote-Groups Remote-Name Remote-Email + } +} + +# 3) Example protected service: gate it behind Authelia, then proxy the backend. +# secure-app.infinidim.net { +# import authelia +# reverse_proxy some-backend.tail7b1641.ts.net:8080 +# tls /etc/caddy/certs/secure-app.infinidim.net/fullchain.pem \ +# /etc/caddy/certs/secure-app.infinidim.net/privkey.pem +# } diff --git a/authelia/config/configuration.yml b/authelia/config/configuration.yml new file mode 100644 index 0000000..ed62928 --- /dev/null +++ b/authelia/config/configuration.yml @@ -0,0 +1,73 @@ +# ============================================================================ +# Authelia config — non-secret structure only. Secrets + infra hosts (Postgres +# address, Redis host, SMTP) are injected via AUTHELIA_* env from the compose +# file, so this stays commit-safe. +# ============================================================================ +# STRAWMAN. Authelia's schema moves between releases (this targets 4.38+: note +# session.cookies[], identity_validation, storage.postgres.address). Verify +# against the pinned image tag before trusting it, then pin the tag. + +theme: dark + +server: + address: tcp://0.0.0.0:9091 + +log: + level: info + +totp: + issuer: infinidim.net + +# File-based user database (simple, good for play). Swap to LDAP later if needed. +authentication_backend: + file: + path: /config/users_database.yml + password: + algorithm: argon2 + +access_control: + default_policy: deny + rules: + # The portal itself must always be reachable. + - domain: auth.infinidim.net + policy: bypass + # Everything else under the domain needs at least one factor. + - domain: "*.infinidim.net" + policy: one_factor + +session: + # secret + redis host/port/db come from env (AUTHELIA_SESSION_*). + cookies: + - domain: infinidim.net + authelia_url: https://auth.infinidim.net + default_redirection_url: https://infinidim.net + +regulation: + max_retries: 3 + find_time: 2m + ban_time: 5m + +# storage (postgres), notifier (smtp), session.secret/redis, and +# identity_validation.reset_password.jwt_secret all arrive via env — see +# docker-compose.yml. Kept out of this file to avoid duplicating infra +# hostnames and to keep secrets off disk in the repo. + +# ---------------------------------------------------------------------------- +# OIDC provider (optional) — uncomment to let apps log in via OpenID Connect. +# Needs AUTHELIA_OIDC_HMAC_SECRET and a JWKS signing key: +# docker run --rm authelia/authelia:latest \ +# authelia crypto certificate rsa generate --directory /tmp && cat /tmp/... +# ---------------------------------------------------------------------------- +# identity_providers: +# oidc: +# hmac_secret: +# jwks: +# - key: | +# -----BEGIN PRIVATE KEY----- ... +# clients: +# - client_id: stalwart +# client_name: Stalwart Mail +# client_secret: '' +# redirect_uris: +# - https://mail.infinidim.net/... +# scopes: [openid, profile, email] diff --git a/authelia/config/users_database.yml b/authelia/config/users_database.yml new file mode 100644 index 0000000..f94c594 --- /dev/null +++ b/authelia/config/users_database.yml @@ -0,0 +1,10 @@ +# Authelia file user backend. Regenerate a hash with: +# docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'PASS' +users: + admin: + disabled: false + displayname: "Admin" + password: "$argon2id$v=19$m=65536,t=3,p=4$ZVJNUh4uH7VMccpo3aRihQ$b///aUhTewPsXZ2AcqqJKPb8nLq6xVNgLNJQ7/b5lmo" + email: admin@infinidim.net + groups: + - admins diff --git a/authelia/docker-compose.yml b/authelia/docker-compose.yml new file mode 100644 index 0000000..7960552 --- /dev/null +++ b/authelia/docker-compose.yml @@ -0,0 +1,71 @@ +# authelia — SSO / 2FA / OIDC provider as a Tailscale sidecar (NO WAN presence). +# +# Storage → shared Postgres, sessions → shared Redis, mail → shared SMTP relay, +# all over the tailnet via MagicDNS. The portal (auth.infinidim.net) and any +# forward-auth-protected vhosts are wired on the main box Caddy — see +# caddy-forward-auth.snippet. +# +# Prereq: the `authelia` Postgres role/db (see README). Bring up: docker compose up -d + +name: authelia + +services: + + ts-authelia: + image: tailscale/tailscale:latest + hostname: ${AUTHELIA_MAGIC_NAME} + environment: + TS_AUTHKEY: ${TS_OAUTH_CLIENT_SECRET}?ephemeral=true + TS_EXTRA_ARGS: --advertise-tags=tag:authelia + TS_HOSTNAME: ${AUTHELIA_MAGIC_NAME} + TS_ACCEPT_DNS: "true" + TS_AUTH_ONCE: "true" + TS_USERSPACE: "false" + TS_ENABLE_HEALTH_CHECK: "true" + TS_LOCAL_ADDR_PORT: "127.0.0.1:9002" + dns: [1.1.1.1, 1.0.0.1] + devices: + - /dev/net/tun:/dev/net/tun + cap_add: + - NET_ADMIN + - NET_RAW + healthcheck: + test: ["CMD", "wget", "-qO-", "http://127.0.0.1:9002/healthz"] + interval: 10s + timeout: 5s + retries: 6 + start_period: 30s + restart: unless-stopped + + authelia: + image: authelia/authelia:4.39.20 + network_mode: "service:ts-authelia" + environment: + X_AUTHELIA_CONFIG: /config/configuration.yml + # Secrets + infra hosts via env so configuration.yml stays commit-safe and + # free of hardcoded MagicDNS names. Env overrides win over the yml. + AUTHELIA_SESSION_SECRET: ${AUTHELIA_SESSION_SECRET} + AUTHELIA_STORAGE_ENCRYPTION_KEY: ${AUTHELIA_STORAGE_ENCRYPTION_KEY} + AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET: ${AUTHELIA_JWT_SECRET} + AUTHELIA_STORAGE_POSTGRES_ADDRESS: tcp://${DB_MAGIC_NAME}.${TS_TAILNET}:5432 + AUTHELIA_STORAGE_POSTGRES_DATABASE: ${AUTHELIA_DB_NAME} + AUTHELIA_STORAGE_POSTGRES_USERNAME: ${AUTHELIA_DB_USER} + AUTHELIA_STORAGE_POSTGRES_PASSWORD: ${AUTHELIA_DB_PASSWORD} + AUTHELIA_SESSION_REDIS_HOST: ${REDIS_MAGIC_NAME}.${TS_TAILNET} + AUTHELIA_SESSION_REDIS_PORT: "6379" + AUTHELIA_SESSION_REDIS_DATABASE_INDEX: ${AUTHELIA_REDIS_DB} + AUTHELIA_NOTIFIER_SMTP_ADDRESS: submission://${SMTP_HOST}:${SMTP_PORT} + AUTHELIA_NOTIFIER_SMTP_USERNAME: ${SMTP_USER} + AUTHELIA_NOTIFIER_SMTP_PASSWORD: ${SMTP_PASSWORD} + AUTHELIA_NOTIFIER_SMTP_SENDER: ${AUTHELIA_SMTP_SENDER} + volumes: + - ./config/configuration.yml:/config/configuration.yml:ro + - ./config/users_database.yml:/config/users_database.yml:ro + - authelia-data:/data + depends_on: + ts-authelia: + condition: service_healthy + restart: unless-stopped + +volumes: + authelia-data: From 7eefac0224674370dc227913aedcd5671aef6bbe Mon Sep 17 00:00:00 2001 From: Wayne Hayes Date: Sat, 13 Jun 2026 02:24:59 +0100 Subject: [PATCH 2/3] authelia: sync caddy-forward-auth snippet to deployed reality The portal vhost + forward-auth are now live on the main box Caddy. Align the template with what was actually deployed: - upstream host -> agrajag.tail7b1641.ts.net (the Authelia node's MagicDNS name), replacing the majikthise placeholder - drop the explicit `tls` cert-file lines: this Caddy uses automatic HTTPS (no /etc/caddy/certs); ACME for auth.infinidim.net rides the :443->:8443 SNI fan-out (tls-alpn-01) + :80 (http-01) - forward-auth endpoint /api/verify?rd=... -> /api/authz/forward-auth, the Authelia 4.39 path; portal redirect comes from authelia_url in the yml - note the infinidim.net CAA accounturi pin: a new L7 vhost 403s until this Caddy's LE account is allowlisted (now done alongside Stalwart's) Co-Authored-By: Claude Opus 4.8 --- authelia/caddy-forward-auth.snippet | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/authelia/caddy-forward-auth.snippet b/authelia/caddy-forward-auth.snippet index 64d82d9..e4ec88c 100644 --- a/authelia/caddy-forward-auth.snippet +++ b/authelia/caddy-forward-auth.snippet @@ -1,19 +1,29 @@ -# Add to the MAIN box Caddyfile (/etc/caddy/Caddyfile). Authelia is layer 7, +# Wired into the MAIN box Caddyfile (/etc/caddy/Caddyfile). Authelia is layer 7, # so unlike tailwart's mail edge it's an ordinary reverse_proxy + forward_auth. -# Replace majikthise with your AUTHELIA_MAGIC_NAME. +# This file mirrors what is deployed. Upstream host = AUTHELIA_MAGIC_NAME, the +# Authelia node's MagicDNS name (currently `agrajag`). +# +# Two deliberate differences from a vanilla Authelia example, to match this host: +# - No explicit `tls` cert files: this Caddy uses automatic HTTPS like its other +# vhosts (there is no /etc/caddy/certs). ACME for auth.infinidim.net works via +# the :443→:8443 SNI fan-out (tls-alpn-01) and :80 (http-01). +# NOTE: infinidim.net has a CAA record pinning issuance to Let's Encrypt by +# accounturi — this Caddy's LE account must be listed there or issuance 403s +# ("CAA record prevents issuance"). Stalwart's account + this Caddy's account +# are both allowlisted. +# - Endpoint is /api/authz/forward-auth (Authelia 4.38+/4.39 path). The legacy +# /api/verify?rd=... is deprecated; the portal redirect comes from +# `authelia_url` in configuration.yml, so no ?rd= query is needed. -# 1) The Authelia portal itself. +# 1) The Authelia portal itself (access_control marks it `bypass`). auth.infinidim.net { - import common_log - reverse_proxy majikthise.tail7b1641.ts.net:9091 - tls /etc/caddy/certs/auth.infinidim.net/fullchain.pem \ - /etc/caddy/certs/auth.infinidim.net/privkey.pem + reverse_proxy agrajag.tail7b1641.ts.net:9091 } # 2) A reusable forward-auth snippet — import it into any vhost you want SSO on. (authelia) { - forward_auth majikthise.tail7b1641.ts.net:9091 { - uri /api/verify?rd=https://auth.infinidim.net + forward_auth agrajag.tail7b1641.ts.net:9091 { + uri /api/authz/forward-auth copy_headers Remote-User Remote-Groups Remote-Name Remote-Email } } @@ -22,6 +32,4 @@ auth.infinidim.net { # secure-app.infinidim.net { # import authelia # reverse_proxy some-backend.tail7b1641.ts.net:8080 -# tls /etc/caddy/certs/secure-app.infinidim.net/fullchain.pem \ -# /etc/caddy/certs/secure-app.infinidim.net/privkey.pem # } From 783b09f463c96568ad1098a10415b9506c2443ec Mon Sep 17 00:00:00 2001 From: Wayne Hayes Date: Fri, 12 Jun 2026 22:26:26 -0400 Subject: [PATCH 3/3] authelia: set portal admin user to zarniwoop (match AUTHELIA_ADMIN_USER) The vendored user db carried the template `admin`, but the operator .env sets AUTHELIA_ADMIN_USER=zarniwoop, so portal login failed ("user not found"). Rename the file-backend user to `zarniwoop` with an argon2id hash of the .env AUTHELIA_ADMIN_PASSWORD (verified via `authelia crypto hash validate`). Email kept as admin@infinidim.net (a real Stalwart mailbox) so password-reset works. Co-Authored-By: Claude Opus 4.8 --- authelia/config/users_database.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/authelia/config/users_database.yml b/authelia/config/users_database.yml index f94c594..d1d6e58 100644 --- a/authelia/config/users_database.yml +++ b/authelia/config/users_database.yml @@ -1,10 +1,11 @@ # Authelia file user backend. Regenerate a hash with: -# docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'PASS' +# docker run --rm authelia/authelia:4.39.20 authelia crypto hash generate argon2 --password 'PASS' +# Username/password come from AUTHELIA_ADMIN_USER / AUTHELIA_ADMIN_PASSWORD in the root .env. users: - admin: + zarniwoop: disabled: false - displayname: "Admin" - password: "$argon2id$v=19$m=65536,t=3,p=4$ZVJNUh4uH7VMccpo3aRihQ$b///aUhTewPsXZ2AcqqJKPb8nLq6xVNgLNJQ7/b5lmo" + displayname: "Zarniwoop" + password: "$argon2id$v=19$m=65536,t=3,p=4$2Zh5wh3yN/kCvR26mTRo9Q$g86OC3E8Q4lH0czTOal7Gci2+U6t0ZIFhogIwtRoA5M" email: admin@infinidim.net groups: - admins