From 4ad85fae704577103462447e41b0dec5252319c4 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 1 Sep 2026 15:25:56 -0700 Subject: [PATCH] authentik: add LDAP outpost service for Jellyfin LDAP-Auth - New authentik-outpost-ldap quadlet: ghcr.io/goauthentik/ldap:2026.8.0, publishes host 389/636 -> container 3389/6636 for cross-host binds from dankserver's Jellyfin LDAP-Auth plugin; outpost token in host .env. - deploy-plan.py: register authentik-outpost-ldap in SERVICE_ORDER and DANKCLAW_SERVICES; map dankclaw/authentik/quadlet/ unit path. - deploy-remote.sh: deploy_authentik_outpost_ldap handler + dispatch case. - deploy.sh: valid-service entry. --- .../quadlet/authentik-outpost-ldap.container | 38 +++++++++++++++++++ scripts/deploy-plan.py | 4 +- scripts/deploy-remote.sh | 17 +++++++++ scripts/deploy.sh | 2 +- 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 dankclaw/authentik/quadlet/authentik-outpost-ldap.container diff --git a/dankclaw/authentik/quadlet/authentik-outpost-ldap.container b/dankclaw/authentik/quadlet/authentik-outpost-ldap.container new file mode 100644 index 0000000..233a7a7 --- /dev/null +++ b/dankclaw/authentik/quadlet/authentik-outpost-ldap.container @@ -0,0 +1,38 @@ +# Quadlet unit: Authentik LDAP outpost (rootless, boot-persistent). +# +# Install path on dankclaw: ~/.config/containers/systemd/authentik-outpost-ldap.container +# Unit name: authentik-outpost-ldap.service (podman 5.x drops the container- prefix) +# +# Serves the authentik LDAP provider ("Jellyfin LDAP", Base DN +# dc=franksdank,dc=cloud) so dankserver's Jellyfin can authenticate its users +# via the LDAP-Auth plugin. The type-specific ghcr.io/goauthentik/ldap image +# listens on 3389 (ldap) / 6636 (ldaps) inside the container; published to +# host 389/636 for cross-host binds from dankserver. The outpost token lives +# in the host .env (AUTHENTIK_LDAP_OUTPOST_TOKEN), never in this repo. The +# outpost dials core over websocket at AUTHENTIK_HOST; auth. is guard-chain +# exempt (IdP). + +[Unit] +Description=Authentik LDAP outpost container +After=network.target authentik-server.service +Wants=authentik-server.service + +[Container] +ContainerName=authentik-outpost-ldap +Image=ghcr.io/goauthentik/ldap:2026.8.0 +Network=dankclaw_default +EnvironmentFile=/home/dank/serverAppConfigs/dankclaw/.env +Environment=AUTHENTIK_HOST=https://auth.franksdank.cloud +Environment=AUTHENTIK_INSECURE=false +Environment=AUTHENTIK_TOKEN=${AUTHENTIK_LDAP_OUTPOST_TOKEN} +PublishPort=389:3389 +PublishPort=636:6636 +User=0:0 + +[Service] +EnvironmentFile=/home/dank/serverAppConfigs/dankclaw/.env +Restart=always +RestartSec=5 + +[Install] +WantedBy=default.target diff --git a/scripts/deploy-plan.py b/scripts/deploy-plan.py index 49ebb46..663db2f 100755 --- a/scripts/deploy-plan.py +++ b/scripts/deploy-plan.py @@ -41,6 +41,7 @@ SERVICE_ORDER = ( "authentik-server", "authentik-worker", "authentik-outpost", + "authentik-outpost-ldap", "caddy", "homepage", "romm-mariadb", @@ -83,6 +84,7 @@ DANKCLAW_SERVICES = { "authentik-server", "authentik-worker", "authentik-outpost", + "authentik-outpost-ldap", "caddy", "homepage", "frank-default-large", @@ -276,7 +278,7 @@ def services_for_path(path: str, target: str) -> set[str]: return services if len(parts) >= 4 and parts[1] == "authentik" and parts[2] == "quadlet": name = parts[3].removesuffix(".container") - if name in {"authentik-postgres", "authentik-server", "authentik-worker", "authentik-outpost"}: + if name in {"authentik-postgres", "authentik-server", "authentik-worker", "authentik-outpost", "authentik-outpost-ldap"}: _add(services, name) return services if len(parts) >= 2 and parts[1] == "searxng": diff --git a/scripts/deploy-remote.sh b/scripts/deploy-remote.sh index a1111fc..8a37f7a 100755 --- a/scripts/deploy-remote.sh +++ b/scripts/deploy-remote.sh @@ -706,6 +706,20 @@ deploy_authentik_outpost() { echo "WARN: authentik-outpost did not come up active" >&2 } +deploy_authentik_outpost_ldap() { + # Dedicated LDAP outpost for Jellyfin's LDAP-Auth plugin. The type-specific + # ghcr.io/goauthentik/ldap image serves 3389/6636 container-side, published + # as host 389/636 for cross-host binds from dankserver. The outpost token + # lives in the host .env, never in this repo. Restarting only this unit + # cycles LDAP auth for a few seconds; the rest of the stack is untouched. + cp dankclaw/authentik/quadlet/authentik-outpost-ldap.container "$quadlet_unit_dir/" + systemctl --user daemon-reload + systemctl --user restart authentik-outpost-ldap.service + sleep 5 + systemctl --user is-active --quiet authentik-outpost-ldap.service || \ + echo "WARN: authentik-outpost-ldap did not come up active" >&2 +} + deploy_hermes() { # The hermes trio (gateway, dashboard, webui) shares one image and the # /data volume and deploys as one unit: install the units, retire the @@ -981,6 +995,9 @@ deploy_service() { authentik-outpost) deploy_authentik_outpost ;; + authentik-outpost-ldap) + deploy_authentik_outpost_ldap + ;; anubis) deploy_anubis ;; seerr) deploy_seerr ;; frank-default-large) deploy_llm_large ;; diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 9f58eaa..fee5fe0 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -133,7 +133,7 @@ valid_service() { dankclaw:comfyui|dankclaw:hermes|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:authentik-outpost|dankclaw:anubis|dankclaw:seerr|\ + dankclaw:authentik-worker|dankclaw:authentik-outpost|dankclaw:authentik-outpost-ldap|dankclaw:anubis|dankclaw:seerr|\ dankclaw:frank-default-large|dankclaw:frank-default-npu|\ dankclaw:frank-default-sightsound|\ dankserver:romm-mariadb|dankserver:romm-redis|dankserver:romm|\