Persist TB-006 batch 2 media SSO and batch 1 auth fixes to the repo.

Media sites get Caddy forward_auth; Authentik scripts cover all proxy providers. BookStack OIDC and Plane admin routing fixes included, plus ops scripts for external auth on valhalla.
This commit is contained in:
ginnoir
2026-06-11 01:19:06 -05:00
parent 63889fc150
commit 1ce63153ab
8 changed files with 308 additions and 27 deletions
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""Apply TB-006 batch 1 forward_auth proxy providers (forward_auth-only sites).
"""Apply TB-006 forward_auth proxy providers (admin batch 1 + media batch 2).
Native OAuth/OIDC apps (bookstack, gitea, portainer, minio, plane, homarr) use
Native OAuth/OIDC apps (bookstack, gitea, portainer, minio, homarr) use
setup-batch1-oidc.py instead. Run this via: ak shell -c exec(open(...).read())
"""
from authentik.core.models import Application
@@ -21,12 +21,25 @@ UPTIME_UNAUTH = """^/status/.*
^/upload/.*"""
SITES = [
# Batch 1 — admin
("homelab-code", "code", "code-server", "https://code.ginnoir.com", None, None),
("homelab-registry-ui", "registry-ui", "Registry UI", "https://registry-ui.ginnoir.com", None, None),
("homelab-vault", "vault", "Vault", "https://vault.ginnoir.com", None, None),
("homelab-uptime", "uptime", "Uptime Kuma", "https://uptime.ginnoir.com", "http://uptime-kuma:3001", UPTIME_UNAUTH),
("homelab-backup", "backup", "Kopia", "https://backup.ginnoir.com", None, None),
("homelab-dbx", "dbx", "DBX", "https://dbx.ginnoir.com", None, None),
("homelab-plane", "plane", "Plane", "https://plane.ginnoir.com", None, None),
# Batch 2 — media *arr stack (internal_only + forward_auth at Caddy)
("homelab-sonarr", "sonarr", "Sonarr", "https://sonarr.ginnoir.com", None, None),
("homelab-radarr", "radarr", "Radarr", "https://radarr.ginnoir.com", None, None),
("homelab-bazarr", "bazarr", "Bazarr", "https://bazarr.ginnoir.com", None, None),
("homelab-prowlarr", "prowlarr", "Prowlarr", "https://prowlarr.ginnoir.com", None, None),
("homelab-tautulli", "tautulli", "Tautulli", "https://tautulli.ginnoir.com", None, None),
("homelab-qbit", "qbit", "qBittorrent", "https://qbittorrent.ginnoir.com", None, None),
("homelab-deluge", "deluge", "Deluge", "https://deluge.ginnoir.com", None, None),
("homelab-nzbget", "nzbget", "NZBGet", "https://nzbget.ginnoir.com", None, None),
("homelab-whisparr", "whisparr", "Whisparr", "https://whisparr.ginnoir.com", None, None),
("homelab-stash", "stash", "Stash", "https://stash.ginnoir.com", None, None),
]
providers = []
@@ -1,13 +1,15 @@
"""Create OAuth2 providers for batch-1 apps with native SSO (ak shell: exec(open(...).read()))."""
from authentik.core.models import Application
from authentik.crypto.models import CertificateKeyPair
from authentik.flows.models import Flow
from authentik.outposts.models import Outpost
from authentik.providers.oauth2.models import OAuth2Provider, RedirectURI, RedirectURIMatchingMode
from authentik.providers.oauth2.models import OAuth2Provider, RedirectURI, RedirectURIMatchingMode, SubModes
from authentik.providers.proxy.models import ProxyProvider
AUTHZ = Flow.objects.get(slug="default-provider-authorization-implicit-consent")
INVALID = Flow.objects.get(slug="default-provider-invalidation-flow")
DEFAULT_MAPPINGS = OAuth2Provider.objects.get(name="famapp").property_mappings.all()
SIGNING_KEY = CertificateKeyPair.objects.get(name="authentik Self-signed Certificate")
# slug, provider name, redirect URI(s)
OIDC_APPS = [
@@ -15,7 +17,6 @@ OIDC_APPS = [
("gitea", "gitea", ["https://gitea.ginnoir.com/user/oauth2/Authentik/callback"]),
("portainer", "portainer", ["https://portainer.ginnoir.com/"]),
("minio", "minio-console", ["https://minio.ginnoir.com/oauth_callback"]),
("plane", "plane", ["https://plane.ginnoir.com/auth/oidc/callback/"]),
]
native_slugs = []
@@ -25,6 +26,8 @@ for slug, pname, redirects in OIDC_APPS:
defaults={
"authorization_flow": AUTHZ,
"invalidation_flow": INVALID,
"signing_key": SIGNING_KEY,
"sub_mode": SubModes.USER_UUID if slug == "bookstack" else SubModes.HASHED_USER_ID,
"redirect_uris": [
RedirectURI(matching_mode=RedirectURIMatchingMode.STRICT, url=url)
for url in redirects
@@ -60,7 +63,6 @@ PROXY_NAMES = {
"gitea": "homelab-gitea",
"portainer": "homelab-portainer",
"minio": "homelab-minio",
"plane": "homelab-plane",
}
outpost = Outpost.objects.get(name="authentik Embedded Outpost")
for slug in native_slugs:
@@ -1,4 +1,4 @@
"""Update proxy providers for forward_auth-only batch-1 apps (ak shell: exec(open(...).read()))."""
"""Update proxy providers for forward_auth apps (admin batch 1 + media batch 2)."""
from authentik.core.models import Application
from authentik.flows.models import Flow
from authentik.outposts.models import Outpost, OutpostType
@@ -17,12 +17,25 @@ UPTIME_UNAUTH = """^/status/.*
# Proxy-only sites (native OIDC apps managed by setup-batch1-oidc.py).
SITES = [
# Batch 1 — admin
("homelab-code", "code", "code-server", "https://code.ginnoir.com", None, None),
("homelab-registry-ui", "registry-ui", "Registry UI", "https://registry-ui.ginnoir.com", None, None),
("homelab-vault", "vault", "Vault", "https://vault.ginnoir.com", None, None),
("homelab-uptime", "uptime", "Uptime Kuma", "https://uptime.ginnoir.com", "http://uptime-kuma:3001", UPTIME_UNAUTH),
("homelab-backup", "backup", "Kopia", "https://backup.ginnoir.com", None, None),
("homelab-dbx", "dbx", "DBX", "https://dbx.ginnoir.com", None, None),
("homelab-plane", "plane", "Plane", "https://plane.ginnoir.com", None, None),
# Batch 2 — media
("homelab-sonarr", "sonarr", "Sonarr", "https://sonarr.ginnoir.com", None, None),
("homelab-radarr", "radarr", "Radarr", "https://radarr.ginnoir.com", None, None),
("homelab-bazarr", "bazarr", "Bazarr", "https://bazarr.ginnoir.com", None, None),
("homelab-prowlarr", "prowlarr", "Prowlarr", "https://prowlarr.ginnoir.com", None, None),
("homelab-tautulli", "tautulli", "Tautulli", "https://tautulli.ginnoir.com", None, None),
("homelab-qbit", "qbit", "qBittorrent", "https://qbittorrent.ginnoir.com", None, None),
("homelab-deluge", "deluge", "Deluge", "https://deluge.ginnoir.com", None, None),
("homelab-nzbget", "nzbget", "NZBGet", "https://nzbget.ginnoir.com", None, None),
("homelab-whisparr", "whisparr", "Whisparr", "https://whisparr.ginnoir.com", None, None),
("homelab-stash", "stash", "Stash", "https://stash.ginnoir.com", None, None),
]
providers = []
+19 -3
View File
@@ -147,12 +147,11 @@ services:
- DB_PASS=${BOOKSTACK_DB_PASSWORD}
- DB_DATABASE=bookstack
- AUTH_METHOD=oidc
- AUTH_AUTO_INITIATE=true
- AUTH_AUTO_INITIATE=false
- OIDC_NAME=Authentik
- OIDC_CLIENT_ID=${BOOKSTACK_OIDC_CLIENT_ID}
- OIDC_CLIENT_SECRET=${BOOKSTACK_OIDC_CLIENT_SECRET}
- OIDC_ISSUER=https://auth.ginnoir.com/application/o/bookstack/
- OIDC_ISSUER_DISCOVER=true
- OIDC_END_SESSION_ENDPOINT=true
volumes:
- /config/bookstack:/config
ports:
@@ -197,6 +196,23 @@ services:
- NEXT_PUBLIC_API_BASE_URL=https://plane.ginnoir.com
- HOSTNAME=0.0.0.0
plane-admin:
container_name: plane_admin
image: makeplane/plane-admin:v0.23.1
restart: unless-stopped
networks: [dev, edge]
command: node admin/server.js
env_file:
- stack.env
environment:
- NEXT_PUBLIC_API_BASE_URL=https://plane.ginnoir.com
- HOSTNAME=0.0.0.0
depends_on:
plane-api:
condition: service_started
plane-web:
condition: service_started
plane-api:
container_name: plane_api
image: makeplane/plane-backend:latest
+3
View File
@@ -14,6 +14,9 @@ BOOKSTACK_DB_PASSWORD=bookstack_d3v_pass
BOOKSTACK_DB_ROOT_PASSWORD=bookstack_r00t_pass
BOOKSTACK_OIDC_CLIENT_ID=8YV4BI2JVIG1QzS2DbylEgqv56sgfiOVRXOgw2Z5
BOOKSTACK_OIDC_CLIENT_SECRET=wIyiw7LmGBORDyTdc2crSZryXJHzIq4gtajAKSpOU7e8BkBSO6SstM9gGPrnp4tbJhCFSQggYAgtYd5LOjUvQpSWInzm0JLlmLg1BTlPq5EVVieNYuWRCCQrerj8gRZ0
# BookStack reads OIDC_* directly (env_file); BOOKSTACK_* kept for Portainer UI mirror if using ${} in compose.
OIDC_CLIENT_ID=8YV4BI2JVIG1QzS2DbylEgqv56sgfiOVRXOgw2Z5
OIDC_CLIENT_SECRET=wIyiw7LmGBORDyTdc2crSZryXJHzIq4gtajAKSpOU7e8BkBSO6SstM9gGPrnp4tbJhCFSQggYAgtYd5LOjUvQpSWInzm0JLlmLg1BTlPq5EVVieNYuWRCCQrerj8gRZ0
# Plane project management
# Rotate with: openssl rand -hex 32