Tracked the harness artifacts accumulated on blankpad (blank@), matching the existing convention for the --home-dank-* memory stores and the 36 already-tracked managed-skills. managed-skills (9): authentik-proxy-provider-app-link, dankclaw-guard-chain-layer-diagnosis, e2e-arr-rawip-reachability-triage, halogen-kv-pool-fit, lan-client-split-dns-fix, noctalia-reference, rootless-quadlet-log-retrieval, ssh-key-bootstrap-no-sshpass, swapfile-resize-safe-ordering. memories (2 stores): --home-blank-.omp-- (dotfiles_git, handy_lifecycle, input_permissions) and --home-blank-Projects-serverAppConfig-- (frank_large_quadlet). Secret sweep before staging: no PEM blocks, no credential literals. Content is fleet topology/IPs only, same class as the tracked dank stores.
53 lines
3.6 KiB
Markdown
53 lines
3.6 KiB
Markdown
---
|
|
name: authentik-proxy-provider-app-link
|
|
description: "Diagnose and fix an authentik embedded-outpost proxy provider that never authenticates (login wall / raw flow served on the app host): the provider must be linked to an Application, have a non-null invalidation_flow, and an exact external_host match."
|
|
---
|
|
|
|
# authentik proxy provider not authenticating (login wall)
|
|
|
|
Symptom: a service behind the authentik embedded outpost (Caddy -> Anubis -> outpost -> app) never lets an authenticated user through. The browser is parked on a login page served ON THE APP'S OWN HOST, e.g. `https://app.example.com/if/flow/default-authentication-flow/?next=/` or `https://app.example.com/flows/-/default/authentication/`. The IdP session cookie lives on `auth.example.com` and is never sent to `app.example.com`, so login is demanded forever.
|
|
|
|
## Root causes (check in this order)
|
|
|
|
1. **Provider not linked to an Application (most common).** The embedded outpost's config API filters `ProxyProvider.objects.filter(application__isnull=False)`. A provider created with `ProxyProvider.objects.create(...)` and no Application is never returned to the outpost, so the outpost never loads it and the request falls through to raw flow serving.
|
|
- FIX: create an Application bound to the provider:
|
|
```python
|
|
app = Application.objects.create(name="Marreta", slug="marreta", launch_url="https://marreta.franksdank.cloud")
|
|
app.provider = proxy_provider; app.save()
|
|
proxy_provider.application = app; proxy_provider.save()
|
|
```
|
|
2. **Null `invalidation_flow`.** The Rust outpost serde requires a formatted UUID; a null value aborts `get_outpost` with `invalid type: null, expected a formatted UUID string at line 1 column N` and takes down EVERY provider on that outpost.
|
|
- FIX: `proxy_provider.invalidation_flow = InvalidationFlow.objects.get(name="default-provider-invalidation-flow")`.
|
|
3. **`external_host` mismatch.** Must equal the Host header the outpost sees. Trailing-slash mismatch (`https://x` vs `https://x/`) = no match. Match the fleet convention (no trailing slash).
|
|
4. **Missing `authentication_flow` / `authorization_flow`.** Set to the fleet defaults (`default-authentication-flow`, `default-provider-authorization-implicit-consent`).
|
|
|
|
## Diagnose
|
|
|
|
```bash
|
|
# 1. Compare broken vs working provider field set (ak shell, as the authentik user):
|
|
sudo -u authentik AUTHENTIK_POSTGRESQL_HOST=127.0.0.1 AUTHENTIK_POSTGRESQL_PORT=5432 \
|
|
AUTHENTIK_POSTGRESQL_NAME=authentik AUTHENTIK_POSTGRESQL_USER=authentik \
|
|
AUTHENTIK_POSTGRESQL_PASSWORD='<pw>' ak shell
|
|
```
|
|
```python
|
|
for p in ProxyProvider.objects.all():
|
|
print(p.name, p.external_host, bool(p.application), p.authentication_flow_id, p.authorization_flow_id, p.invalidation_flow_id)
|
|
```
|
|
```bash
|
|
# 2. The serde error (this is the smoking gun for cause #2):
|
|
journalctl --user -u authentik-outpost.service --since '-10 min' | grep -iE 'error|invalid|panic'
|
|
# 3. Confirm the outpost loaded the provider after the fix:
|
|
journalctl --user -u authentik-outpost.service --since '-2 min' | grep -i 'loaded app'
|
|
```
|
|
|
|
## Apply + restart
|
|
|
|
After any provider/application change: `systemctl --user restart authentik-server.service authentik-outpost.service` (rootless, user dank on Dankclaw). Then verify the OAuth dance:
|
|
```bash
|
|
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' https://app.example.com/
|
|
# expect 302 -> /outpost.goauthentik.io/start?rd=... (NOT a raw /flows/ URL)
|
|
```
|
|
|
|
## Provenance note
|
|
On the Dank fleet these providers are NOT repo-managed (no blueprint). Fixes applied via `ak shell` are live-only. Capture any new provider+application as a repo blueprint or setup script to avoid drift.
|