From 2bccf2f207c2882bbe6fce88f30097c661a681f9 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 28 Aug 2026 19:05:20 -0700 Subject: [PATCH] authentik: deploy outpost as worker-role container with dial-back MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In authentik 2026.8.x the proxy-provider URL space (/outpost.goauthentik.io/*) is served by the Rust worker binary, not the server — verified live: with a tenant-matching Host header, /if/flow/... answers 200 on the server while /auth/caddy still 404s. The outpost instance existed in the DB but no process ever served it, so Caddy's forward_auth subrequests hit a 404 and browsers got authentik's own Not-Found page instead of the authentication flow. The new unit runs the same image as server/worker with Exec=worker and flips into outpost mode via AUTHENTIK_HOST/AUTHENTIK_INSECURE/AUTHENTIK_TOKEN (the token is read from the DB into the host .env at deploy time; it never enters the repo). It dials back to core over websocket and serves forward-auth on its own 9000. Deploy handler restarts only this unit — the rest of the stack is untouched. --- .../quadlet/authentik-outpost.container | 44 +++++++++++++++++++ scripts/deploy-remote.sh | 20 ++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 dankclaw/authentik/quadlet/authentik-outpost.container diff --git a/dankclaw/authentik/quadlet/authentik-outpost.container b/dankclaw/authentik/quadlet/authentik-outpost.container new file mode 100644 index 0000000..6463bab --- /dev/null +++ b/dankclaw/authentik/quadlet/authentik-outpost.container @@ -0,0 +1,44 @@ +# Quadlet unit: Authentik outpost (rootless, boot-persistent). +# +# Install path on dankclaw: ~/.config/containers/systemd/authentik-outpost.container +# Unit name: authentik-outpost.service (podman 5.x drops the container- prefix) +# +# In authentik 2026.8.x the proxy-provider URL space (/outpost.goauthentik.io/*) +# is served by the Rust worker binary, not the server — verified live: with a +# tenant-matching Host header, /if/flow/... answers 200 on the server while +# /auth/caddy still 404s. This container runs the same image as the server and +# worker units; Exec=worker selects the Rust worker role, and the +# AUTHENTIK_HOST/AUTHENTIK_TOKEN env flips it into outpost mode: it dials back +# to core over websocket (ws/outpost//) and serves forward-auth for Caddy +# on its own 9000. No published port — Caddy reaches it by container DNS on +# dankclaw_default; the token lives in the host .env, never in this repo. + +[Unit] +Description=Authentik outpost container +After=network.target authentik-postgres.service authentik-server.service +Wants=authentik-server.service + +[Container] +ContainerName=authentik-outpost +Image=ghcr.io/goauthentik/server:2026.8.0 +Exec=worker +Network=dankclaw_default +EnvironmentFile=/home/dank/serverAppConfigs/dankclaw/.env +Environment=AUTHENTIK_POSTGRESQL__HOST=authentik-postgres +Environment=AUTHENTIK_POSTGRESQL__NAME=authentik +Environment=AUTHENTIK_POSTGRESQL__USER=authentik +Environment=AUTHENTIK_POSTGRESQL__PASSWORD=${AUTHENTIK_PG_PASS} +Environment=AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY} +Environment=AUTHENTIK_HOST=https://auth.franksdank.cloud +Environment=AUTHENTIK_INSECURE=false +Environment=AUTHENTIK_TOKEN=${AUTHENTIK_OUTPOST_TOKEN} +Volume=/home/dank/authentik/data:/data +User=0:0 + +[Service] +EnvironmentFile=/home/dank/serverAppConfigs/dankclaw/.env +Restart=always +RestartSec=5 + +[Install] +WantedBy=default.target diff --git a/scripts/deploy-remote.sh b/scripts/deploy-remote.sh index 2a7f68e..fa5422d 100755 --- a/scripts/deploy-remote.sh +++ b/scripts/deploy-remote.sh @@ -88,7 +88,8 @@ service_is_allowed() { dankclaw:hermes-dashboard|dankclaw:hermes-webui|dankclaw:prometheus|dankclaw:grafana|\ dankclaw:loki|dankclaw:alloy|dankclaw:node-exporter|\ dankclaw:authentik-postgres|dankclaw:authentik-server|\ - dankclaw:authentik-worker|dankclaw:anubis|dankclaw:caddy|dankclaw:homepage|\ + dankclaw:authentik-worker|dankclaw:authentik-outpost|dankclaw:anubis|\ + dankclaw:caddy|dankclaw:homepage|\ dankclaw:frank-default-large|dankclaw:frank-default-npu|\ dankserver:mariadb|dankserver:redis|dankserver:romm|\ dankserver:copyparty|dankserver:jellyfin|dankserver:calibre-web|\ @@ -550,6 +551,20 @@ deploy_authentik() { systemctl --user start authentik-worker.service } +deploy_authentik_outpost() { + # The outpost is the worker-role binary of the same server image; it dials + # back to core over websocket and serves /outpost.goauthentik.io/* for + # Caddy's forward_auth. Image already in storage — zero pulls. Restarting + # only this unit cycles auth for guarded vhosts for a few seconds; the + # rest of the stack is untouched. + cp dankclaw/authentik/quadlet/authentik-outpost.container "$quadlet_unit_dir/" + systemctl --user daemon-reload + systemctl --user restart authentik-outpost.service + sleep 5 + systemctl --user is-active --quiet authentik-outpost.service || \ + echo "WARN: authentik-outpost did not come up active" >&2 +} + deploy_anubis() { # Anubis is the bot-challenge proxy in front of the guarded vhosts. # The image lives on ghcr.io; pull once, then the unit runs it from @@ -624,6 +639,9 @@ deploy_service() { authentik-postgres|authentik-server|authentik-worker) deploy_authentik ;; + authentik-outpost) + deploy_authentik_outpost + ;; anubis) deploy_anubis ;; frank-default-large) deploy_llm_large ;; frank-default-small) deploy_llm_small ;;