Protect the coaching site admin: real domain, per-site Authelia portal, optional 2FA #292

Open
opened 2026-10-19 17:56:07 -04:00 by jfraeys · 0 comments
Owner

Authelia is the right mechanism and already defines the ACL for client_sites. It isn't applied to a real domain yet.

Current state (read from origin/main)

  • roles/authelia/templates/configuration.yml.j2: default_policy: deny. For each client_sites entry with auth: authelia:
    • DELETE/PUT/PATCH on /admin/ and /api/admin/ → group:admin or group:client-<slug>-admin
    • other methods on those paths → those groups plus group:client-<slug>-employee
    • everything else → bypass
    • all rules are one_factor
  • inventory/group_vars/all.yml: client_sites[coaching].domain is the placeholder example.com (TODO), so the rules apply to no real domain.
  • The session cookie domain is base_domain. The config comment says client sites need their own auth.<site domain> portal first (cookie scope must match the Authelia URL). Not tested.
  • Demos are deliberately outside this: demo_hostname must not be added to client_sites; each demo session's token is its access control.

To do

  • Register the real domain and set client_sites[coaching].domain
  • Add an auth.<that domain> Authelia portal and a matching session cookie entry
  • Create LLDAP groups client-coaching-admin (and client-coaching-employee if needed) and add users
  • Decide whether admin rules move from one_factor to two_factor (TOTP and WebAuthn are already configured)
  • Apply, then confirm /admin/ is refused from outside the tailnet and shows the Authelia login from inside it

Related app side: ansible/roles/coaching_site/templates/site.conf.j2 (tailnet allow 100.64.0.0/10; deny all; plus auth_request) and docs/DEPLOYMENT.md "Admin access" in jfraeys/coaching-site.

🤖 Generated with Claude Code

https://claude.ai/code/session_01B1FuEx3w8ax6P8QvdxxADM

Authelia is the right mechanism and already defines the ACL for `client_sites`. It isn't applied to a real domain yet. ## Current state (read from `origin/main`) - `roles/authelia/templates/configuration.yml.j2`: `default_policy: deny`. For each `client_sites` entry with `auth: authelia`: - `DELETE`/`PUT`/`PATCH` on `/admin/` and `/api/admin/` → `group:admin` or `group:client-<slug>-admin` - other methods on those paths → those groups plus `group:client-<slug>-employee` - everything else → `bypass` - all rules are `one_factor` - `inventory/group_vars/all.yml`: `client_sites[coaching].domain` is the placeholder `example.com` (TODO), so the rules apply to no real domain. - The session cookie domain is `base_domain`. The config comment says client sites need their own `auth.<site domain>` portal first (cookie scope must match the Authelia URL). Not tested. - Demos are deliberately outside this: `demo_hostname` must not be added to `client_sites`; each demo session's token is its access control. ## To do - [ ] Register the real domain and set `client_sites[coaching].domain` - [ ] Add an `auth.<that domain>` Authelia portal and a matching session cookie entry - [ ] Create LLDAP groups `client-coaching-admin` (and `client-coaching-employee` if needed) and add users - [ ] Decide whether admin rules move from `one_factor` to `two_factor` (TOTP and WebAuthn are already configured) - [ ] Apply, then confirm `/admin/` is refused from outside the tailnet and shows the Authelia login from inside it Related app side: `ansible/roles/coaching_site/templates/site.conf.j2` (tailnet `allow 100.64.0.0/10; deny all;` plus `auth_request`) and `docs/DEPLOYMENT.md` "Admin access" in jfraeys/coaching-site. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01B1FuEx3w8ax6P8QvdxxADM
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jfraeys/infra#292
No description provided.