docs(authentik): outpost claim-cache gotcha (proxysession) + Containers data paths
This commit is contained in:
@@ -70,8 +70,9 @@ contract:
|
||||
(`server` / `worker`).
|
||||
- The worker runs as `0:0` (rootless: container root maps to the host user that
|
||||
owns the data dir).
|
||||
- Data persists under `/home/dank/authentik/` (bind mounts, repo policy — no
|
||||
named volumes).
|
||||
- Data persists under `/home/dank/Containers/authentik/{data,postgres}`
|
||||
(bind mounts, repo policy — no named volumes; moved from `/home/dank/authentik/`
|
||||
in the 2026-09-01 quadlet standardization).
|
||||
|
||||
## Caddy integration
|
||||
|
||||
@@ -232,10 +233,39 @@ Two secrets live in the host `.env` (git-ignored; placeholders in
|
||||
probes this).
|
||||
- **Logs:** `podman logs authentik-server` / `podman logs authentik-worker`.
|
||||
- **Backups:** `pg_dump` the `authentik-postgres` database (the single source of
|
||||
truth). The `/home/dank/authentik/` dir holds media + static files.
|
||||
truth). The `/home/dank/Containers/authentik/data` dir holds media + static files.
|
||||
- **Upgrades:** bump the image tag in `dankclaw/compose.yaml`, run
|
||||
`./scripts/deploy.sh dankclaw`. Authentik migrates the schema on startup.
|
||||
|
||||
## Outpost claim cache (`proxysession`) — 403 after a group add
|
||||
|
||||
The embedded outpost does not re-evaluate group membership per request. Each
|
||||
completed authorize writes one row to `authentik_providers_proxy_proxysession`
|
||||
whose `session_data` JSON holds the claims (`groups` included) that get served
|
||||
for that browser session until the row expires (observed TTLs 1–24 h per
|
||||
row). A session authorized **before** a user was added to a group keeps
|
||||
serving the old group list — Caddy-side RBAC header gates then 403 despite
|
||||
correct membership, and no authentik event is generated (the 403 happens at
|
||||
Caddy; authentik never sees the request).
|
||||
|
||||
Diagnosis + fix (verified live 2026-09-01):
|
||||
|
||||
```sql
|
||||
-- who holds which cached groups (run in the authentik-postgres container)
|
||||
SELECT session_data->'claims'->>'preferred_username' AS user,
|
||||
session_data->'claims'->>'groups' AS cached_groups,
|
||||
expires
|
||||
FROM authentik_providers_proxy_proxysession ORDER BY expires;
|
||||
-- invalidate one user's cache; their authentik login session is untouched,
|
||||
-- so the next visit re-authorizes silently and mints fresh claims
|
||||
DELETE FROM authentik_providers_proxy_proxysession
|
||||
WHERE session_data->'claims'->>'preferred_username' = 'akadmin';
|
||||
```
|
||||
|
||||
The silent re-auth path was proven end-to-end: after deleting
|
||||
`qa-e2e-admin`'s rows, the e2e admin spec ran against the stale storage
|
||||
state and passed with no login prompt (2 tests, 2.9 s).
|
||||
|
||||
## Failure modes
|
||||
|
||||
| Symptom | Cause | Fix |
|
||||
@@ -247,6 +277,7 @@ Two secrets live in the host `.env` (git-ignored; placeholders in
|
||||
| "Request has been denied: Invalid next URL" at sign-in | Flow entered with an absolute cross-host `next=` (old redirect design) | Do not hand-craft flow URLs; enter guarded hosts normally — the outpost carries state in its own cookie |
|
||||
| `/outpost.goauthentik.io/*` 404s on every host | A provider row with null `authorization_flow`/`invalidation_flow` wedges the outpost config fetch | Backfill the flows; watch `podman logs authentik-server` for `Failed to fetch outpost from API` |
|
||||
| Off-LAN clients get "hostname could not be found" | Guarded host missing from the public DNS zone | Every host in the lockstep set needs a public A record (Porkbun) as well as the Pi-hole LAN answer |
|
||||
| Correct membership but one user still 403s at a header gate | Outpost claim cache: a `proxysession` row minted before the membership change serves old claims until expiry | Delete that user's `proxysession` rows (section above) — next visit re-authorizes silently |
|
||||
|
||||
## Cross-references
|
||||
|
||||
|
||||
@@ -311,3 +311,4 @@ timestamp: 2026-09-14
|
||||
- `/tests/seerr_quadlet.bats` — new seam: boot persistence, self-healing, pinned tag, loopback-only publish, data-root contract, appnet join, no env/envfile secrets.
|
||||
- `/serverAppConfigs-docs/Dankclaw/Seerr.md`, `/serverAppConfigs-docs/index.md` — service doc + index entry.
|
||||
- Lessons: rootless podman uid mapping is continuous (container N → host 100000+N-1; uid 1000 → 100999 — an off-by-one chown EACCES-crash-looped first boot); new quadlet bind-source dirs must pre-exist on target (statfs 125 otherwise); new vhost TLS issues at Caddy reload (~15 s dns-01), not at first request.
|
||||
- Authentik outpost claim cache fixed (root cause of the persistent `/admin` 403 despite homepage-admins membership): the outpost serves per-browser-session claims from `authentik_providers_proxy_proxysession` until row expiry — akadmin's live row predated the group add and carried `["authentik Admins"]` only, and the 403 never generates an authentik event. Deleted his 4 rows; the next visit re-authorizes silently against the untouched authentik login session. Silent re-auth proven live: deleted qa-e2e-admin's 13 rows, ran the e2e admin spec against the stale storage state — 2 passed in 2.9 s, no login prompt. Mechanism + diagnosis SQL documented in `/serverAppConfigs-docs/Infrastructure/Authentik.md` (new "Outpost claim cache" section + failure-mode row); the doc's data-path references updated to the 2026-09-01 Containers layout.
|
||||
|
||||
Reference in New Issue
Block a user