authentik: route auth.renner.uno/outpost.goauthentik.io to the gate outpost

Each Authentik proxy outpost has its own session store. Sharing the
provider between the embedded outpost and the dedicated gate outpost
means the OAuth callback at /outpost.goauthentik.io/callback hits the
embedded outpost (which has no in-cluster /auth/nginx exposure), the
session is created in the embedded outpost's store, and the dedicated
gate outpost — which is what nginx auth_request actually queries —
never sees it. Result: an infinite redirect between /authorize and
/callback after every OAuth round-trip, surfaced as
ERR_TOO_MANY_REDIRECTS in the browser.

Add an Ingress in the authentik namespace that routes
auth.renner.uno/outpost.goauthentik.io/* to the dedicated outpost's
ClusterIP service, and detach the provider from the embedded outpost.
The dedicated outpost now serves /start, /callback, AND /auth/nginx
in the same process. The Authentik UI flow paths (/if, /application/o,
/api, /static, /flows, /media) continue to resolve via the chart's
authentik-server Ingress at the broader `/` rule, so 2FA still happens
on auth.renner.uno where credentials are bound.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 22:36:36 +02:00
co-authored by Claude Opus 4.7
parent 8f229a007c
commit 00d0c19f9c
3 changed files with 44 additions and 12 deletions
@@ -188,18 +188,12 @@ data:
state: present
attrs:
service_connection: !KeyOf k8s-conn
# The gate's ProxyProvider is also attached here so the
# embedded outpost (running inside authentik-server, served
# at auth.renner.uno) handles the browser-facing legs of the
# forward-auth flow: /outpost.goauthentik.io/start, the
# /application/o/authorize hop, the /if/flow login UI (with
# WebAuthn/2FA bound to auth.renner.uno), and the OAuth
# /outpost.goauthentik.io/callback. The cookie issued from
# auth.renner.uno is scoped to renner.uno so the dedicated
# paperless-gate outpost picks it up on its in-cluster
# /auth/nginx checks.
providers:
- !KeyOf paperless-gate-provider
# No providers attached — the dedicated paperless-gate outpost
# owns its own /outpost.goauthentik.io/* path on auth.renner.uno
# via the paperless-gate-ingress.yaml Ingress, so it sees
# /start, /callback, AND /auth/nginx in the same process and
# keeps a single session store for the gate's flow.
providers: []
# `Caddy` and `Local Radius` carried `kubernetes_namespace: default`
# in their config from the Proxmox-era data, which the chart Role
@@ -4,3 +4,4 @@ resources:
- secret.sops.yaml
- blueprints-configmap.yaml
- helmrelease.yaml
- paperless-gate-ingress.yaml
@@ -0,0 +1,37 @@
---
# Routes auth.renner.uno/outpost.goauthentik.io/* to the dedicated
# `paperless-gate` outpost. Without this rule, those paths hit the
# Helm-managed authentik-server Ingress (catch-all `/`) which forwards
# them to the embedded outpost — a separate process with its own
# session store. The OAuth callback the embedded outpost handles never
# materialises into a session the gate outpost can see, so the gate's
# auth_request keeps returning 401 and the browser loops between
# /authorize and /callback.
#
# nginx-ingress merges path rules across Ingress objects on the same
# host and picks the most specific match, so this Ingress's
# `/outpost.goauthentik.io` Prefix beats the chart's `/` rule.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: paperless-gate-outpost
namespace: authentik
annotations:
cert-manager.io/cluster-issuer: letsencrypt-cluster
spec:
ingressClassName: nginx
rules:
- host: auth.renner.uno
http:
paths:
- path: /outpost.goauthentik.io
pathType: Prefix
backend:
service:
name: ak-outpost-paperless-gate
port:
number: 9000
tls:
- secretName: paperless-gate-outpost-tls
hosts:
- auth.renner.uno