Files
command-center/agent/managed-skills/authentik-proxy-provider-app-link/SKILL.md
T
Frank 4b82f35354 Add blankpad-host auto-learn skills and memory store
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.
2026-09-13 00:25:29 -07:00

3.6 KiB

name, description
name description
authentik-proxy-provider-app-link 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:
      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

# 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
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)
# 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:

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.