docs: prepare Authentik forward-auth for the Docusaurus wiki (not deployed)

Docusaurus is static and has no auth of its own, so the gate goes in Traefik in
front of it via an Authentik proxy outpost. Guide 09 carries the complete,
ready-to-apply config: the Authentik blueprint (forward_single proxy provider +
application + wiki-zugang group + policy binding) and the Overmind side (proxy
outpost container + Traefik forwardAuth middleware). Deliberately kept as a guide,
not merged into the applied blueprint ConfigMap: nothing goes live until the
wiki hostname (#0024) is settled and the outpost token (a credential) is created
by sorb. Dedicated outpost on Overmind so per-request checks stay local and only
the login redirect crosses the VPN. Indexed in the guides README.
This commit is contained in:
Thore Cimbal
2026-08-11 12:00:00 +00:00
parent eb5442e7bf
commit a661ceda11
2 changed files with 171 additions and 0 deletions
@@ -0,0 +1,164 @@
# Docusaurus-Wiki hinter Authentik (Forward-Auth)
**Status**: vorbereitet, **nicht** ausgerollt · Entscheidung: bei Docusaurus
bleiben, Zugang per Authentik einschränken (DOC-03/#0020, bei Docusaurus)
Docusaurus ist ein **statischer** Site-Generator — kein Nutzermodell, kein Login.
Der Zugang wird deshalb **im Reverse-Proxy davor** erzwungen: Traefik fragt bei
jedem Request einen Authentik-**Outpost**, ob eine gültige Sitzung vorliegt, und
leitet sonst zu `auth.axion1337.chat` um. Erst nach Login gibt Traefik die
statischen Seiten frei. Es ist ein **Alles-oder-nichts-Tor** (wer in der Gruppe
`wiki-zugang` ist, sieht das ganze Wiki; sonst nichts) — für Bereichs-Rechte
bräuchte es BookStack (ADR-0007), das war aber ausdrücklich nicht gewollt.
## Topologie
Das Wiki läuft als Dokploy-Stack **auf Overmind** (`git.lab/homelab/wiki`,
`axionwiki.lab`), Authentik im **K3s-Cluster auf Hetzner**. Deshalb ein
**eigener Proxy-Outpost als Container auf Overmind**, statt des eingebetteten
Outposts in Hetzner: So bleiben die Auth-Subrequests lokal auf Overmind — nur die
**Login-Umleitung** quert den Site-to-Site-VPN zu `auth.axion1337.chat`. Das passt
zur Leitlinie „das Lab hängt nicht am Prod-Host": ist eine Sitzung erst gesetzt,
liest sich das Wiki im Lab auch ohne ständige Rückfrage nach Hetzner.
```
Browser ──▶ Traefik (Overmind) ──forwardAuth──▶ authentik-proxy (Overmind, :9000)
│ │ Sitzung? nein ──▶ 302
└────────────── Login-Redirect ─────────────▶ auth.axion1337.chat (Hetzner, via VPN)
```
## Teil 1 — Authentik-Blueprint (deklarativ)
Als neues Dokument in `apps/authentik/authentik-blueprints.yaml` einfügen
(gleiche ConfigMap wie `matrix-oidc-provider.yaml`). **Erst nach Klärung von
#0024 einfügen** — `external_host` muss exakt dem echten Wiki-Host entsprechen.
```yaml
wiki-forward-auth.yaml: |
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
version: 1
metadata:
name: wiki-forward-auth
labels:
blueprints.goauthentik.io/instantiate: "true"
entries:
# Proxy-Provider im Forward-Auth-Modus. Kein internal_host (das wäre der
# Proxy-Modus) — forward_single reicht Traefik nur das Ja/Nein zurück.
- model: authentik_providers_proxy.proxyprovider
state: present
identifiers:
name: ThreadNet Wiki
id: wiki_proxy_provider
attrs:
mode: forward_single
# MUSS dem echten Wiki-Host entsprechen (#0024: axionwiki.lab vs wiki.lab).
external_host: https://axionwiki.lab
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
access_token_validity: hours=24
- model: authentik_core.application
state: present
identifiers:
slug: wiki
id: wiki_app
attrs:
name: ThreadNet Wiki
provider: !KeyOf wiki_proxy_provider
meta_description: Internes Docusaurus-Wiki, nur Gruppe wiki-zugang
policy_engine_mode: any
open_in_new_tab: true
# Zugangsbeschränkung: nur Mitglieder dieser Gruppe passieren das Tor.
- model: authentik_core.group
state: present
identifiers:
name: wiki-zugang
id: wiki_group
- model: authentik_policies.policybinding
state: present
identifiers:
target: !KeyOf wiki_app
group: !KeyOf wiki_group
order: 0
attrs:
enabled: true
negate: false
```
⚠️ **Vor dem Merge von Hand verifizieren**, nicht auf Flux vertrauen — ein
Blueprint-Fehler scheitert still (Lehre aus dem `matrix-recovery`-Fix):
```bash
kubectl exec -n authentik deploy/authentik-server -- \
ak apply_blueprint /blueprints/... # bzw. den ConfigMap-Pfad; auf Fehlerausgabe achten
```
## Teil 2 — Outpost + Token (Authentik-UI, **sorb**)
Der Outpost trägt ein **Token** — das ist ein Credential, kommt nicht ins Repo.
1. *Authentik → Applications → Outposts → Create*: Typ **Proxy**, Name
`wiki-forward-auth`, Provider **ThreadNet Wiki** zuweisen.
2. Das erzeugte **Outpost-Token** kopieren (View-Token) — es geht gleich in den
Overmind-Stack (Teil 3), **nirgends sonst hin**.
3. *Directory → Groups → wiki-zugang*: die internen Nutzer aufnehmen, die das Wiki
sehen dürfen.
## Teil 3 — Overmind: Outpost-Container + Traefik (`git.lab/homelab/wiki`)
Neben den Docusaurus-Service in den Dokploy-/Compose-Stack. Image-Tag **auf die
laufende Authentik-Version pinnen** (Outpost- und Server-Version müssen passen).
```yaml
services:
authentik-proxy:
image: ghcr.io/goauthentik/proxy:2024.x # == laufende Authentik-Version
environment:
AUTHENTIK_HOST: https://auth.axion1337.chat
AUTHENTIK_INSECURE: "false"
AUTHENTIK_TOKEN: ${WIKI_OUTPOST_TOKEN} # aus Teil 2, als Dokploy-Secret
labels:
traefik.enable: "true"
traefik.http.routers.wiki-authentik.rule: "Host(`axionwiki.lab`) && PathPrefix(`/outpost.goauthentik.io/`)"
traefik.http.routers.wiki-authentik.service: wiki-authentik
traefik.http.services.wiki-authentik.loadbalancer.server.port: "9000"
# bestehender Docusaurus-Service — nur die Auth-Middleware ergänzen:
wiki:
labels:
traefik.enable: "true"
traefik.http.routers.wiki.rule: "Host(`axionwiki.lab`)"
traefik.http.routers.wiki.middlewares: "wiki-auth@docker"
traefik.http.middlewares.wiki-auth.forwardauth.address: "http://authentik-proxy:9000/outpost.goauthentik.io/auth/traefik"
traefik.http.middlewares.wiki-auth.forwardauth.trustForwardHeader: "true"
traefik.http.middlewares.wiki-auth.forwardauth.authResponseHeaders: "X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid"
```
Beide Services müssen im selben Traefik-Netz liegen. Der `/outpost.goauthentik.io/`-
Router **ohne** die Auth-Middleware (sonst Redirect-Schleife).
## Abhängigkeiten
- **#0024 (Wiki-Hostname)** — blockierend: `external_host`, der Traefik-`Host()`
und der Cookie-Scope müssen alle auf denselben Namen zeigen.
- **#0018 (Wiki-Rollout)** — sollte abgeschlossen sein, bevor das Tor davor kommt.
- **Site-to-Site-VPN** — die Login-Umleitung braucht `auth.axion1337.chat` vom
Browser aus erreichbar; interne Nutzer im Lab/über VPN erreichen beides.
## Verifikation
1. Unauthentifiziert `https://axionwiki.lab`**302** auf `auth.axion1337.chat`.
2. Login als `wiki-zugang`-Mitglied → Wiki lädt.
3. Login als Nicht-Mitglied → **403** (Policy greift).
4. Gegenprobe: `auth.axion1337.chat` per Netzausfall kurz nicht erreichbar →
bestehende Sitzung liest weiter (lokaler Outpost), nur neuer Login blockiert.
## Was hier bewusst offen bleibt
- **Nichts ist live geschaltet** — der Blueprint liegt als Vorlage hier, nicht in
der angewandten ConfigMap; der Outpost-Token ist sorbs Schritt.
- **Kein Bereichs-Schutz** — das ist die Grenze von Docusaurus + Forward-Auth; wenn
je granulare Rechte nötig werden, ist das der Punkt, an dem ADR-0007 (BookStack)
wieder aufgemacht gehört.
+7
View File
@@ -16,6 +16,7 @@ Die Implementierungen wurden in dieser Reihenfolge durchgeführt. Für neue Setu
| 6 | Moderationsbot (Draupnir) & Content Scanning | `06-moderation-content-scanning.md` | ✅ Deployed | Matrix Synapse | | 6 | Moderationsbot (Draupnir) & Content Scanning | `06-moderation-content-scanning.md` | ✅ Deployed | Matrix Synapse |
| 7 | Host-Wartungsbenachrichtigungen (unattended-upgrades) | `07-host-maintenance-notifications.md` | ✅ Deployed | Host-Ebene (kein K8s) | | 7 | Host-Wartungsbenachrichtigungen (unattended-upgrades) | `07-host-maintenance-notifications.md` | ✅ Deployed | Host-Ebene (kein K8s) |
| 8 | @concierge — Gäste-Einladungen mit Ablauf | `08-concierge-gaeste-einladungen.md` | ⏳ Wartet auf Zugangsdaten | Matrix Synapse | | 8 | @concierge — Gäste-Einladungen mit Ablauf | `08-concierge-gaeste-einladungen.md` | ⏳ Wartet auf Zugangsdaten | Matrix Synapse |
| 9 | Docusaurus-Wiki hinter Authentik (Forward-Auth) | `09-wiki-forward-auth.md` | 📝 Vorbereitet, nicht ausgerollt | Authentik + Traefik (Overmind) |
--- ---
@@ -102,6 +103,12 @@ per Mail + Matrix-Thread-Reply anstehende `unattended-upgrades`, bevor sie laufe
Freischaltung nur durch Admin-Kommando im Matrix-Raum (Issue #48). Deployt, wartet auf Freischaltung nur durch Admin-Kommando im Matrix-Raum (Issue #48). Deployt, wartet auf
Zugangsdaten (Matrix-Konto, Authentik-Token, Secret). Zugangsdaten (Matrix-Konto, Authentik-Token, Secret).
### [09-wiki-forward-auth.md](09-wiki-forward-auth.md)
Statisches Docusaurus-Wiki hinter Authentik: Proxy-Provider (Forward-Auth) + Anwendung +
Gruppe `wiki-zugang` als Blueprint, Proxy-Outpost-Container plus Traefik-Middleware auf
Overmind. Vorbereitet, nicht ausgerollt — Blueprint als Vorlage im Guide, Outpost-Token
und `wiki-zugang`-Mitglieder sind sorbs Schritt; blockiert auf Wiki-Hostname (#0024, DOC-03).
--- ---
## 🛠️ Wartung & Troubleshooting ## 🛠️ Wartung & Troubleshooting