my_voice_assistant_v2/deploy/README.md
Dieter Schlüter 887faa315e feat(admin): Header-Discovery per ?key= durchs SSO aufrufbar
Beim SSO-Setup kennt das Gateway den Admin-Nutzer noch nicht (Henne-Ei). Der
Discovery-Endpoint /api/admin/request-headers akzeptiert daher zusaetzlich den
ADMIN_API_KEY als Query (?key=) oder X-Admin-Key-Header, damit man den von SSOwat
injizierten Identitaets-Header im Browser bestimmen kann. Doku entsprechend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 05:19:41 +02:00

57 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Remote-Betrieb über YunoHost (assistent.linix.de)
Web-UI + Mikrofon vom Handy/Browser, abgesichert per HTTPS und YunoHost-SSO.
Topologie: `https://assistent.linix.de` → nginx@YunoHost (TLS, SSO) → über LAN →
`http://<GPU-Box>:8003` (Gateway). Der interne LAN-Hop ist unverschlüsselt
(vertrautes LAN, wie bei Ollama).
> **Warum HTTPS Pflicht ist:** Browser geben das Mikrofon (`getUserMedia`) nur in
> einem „secure context" frei also HTTPS oder `http://localhost`. Über einfaches
> `http://` vom Handy gibt es **kein** Mikrofon.
## 1. Gateway auf der GPU-Box
`deploy/voice-assistant.env.example``/etc/voice-assistant/voice-assistant.env` anpassen:
- `HOST` = **LAN-IP** der GPU-Box (nicht `0.0.0.0`), `PORT=8003`
- `AUTH_ENABLED=true`
- `TRUSTED_AUTH_HEADER` (nach Discovery, s. u.), `TRUSTED_PROXY_IPS` = LAN-IP von linix.de
- `ADMIN_USERS=atoor,dieterschlueter,dschlueter`, `SSO_LOGOUT_URL=…`
> Kein `--forwarded-allow-ips` setzen: Das Identitäts-Vertrauen prüft die
> **direkte Quell-IP** (= der Proxy). Würde uvicorn den Client aus
> `X-Forwarded-For` überschreiben, schlüge der Proxy-IP-Check fehl.
## 2. Drei Sicherheits-Pflichten
1. **Bind:** Gateway nur an die LAN-IP (Schritt 1).
2. **Firewall:** Port 8003 der GPU-Box **nur** von der linix.de-IP erlauben, z. B.:
```
sudo ufw allow from <linix.de_LAN_IP> to any port 8003 proto tcp
sudo ufw deny 8003
```
3. **Header überschreiben:** nginx setzt den Identitäts-Header selbst; Client-Eingaben
werden verworfen (siehe nginx-Conf). App-seitig zusätzlich der Proxy-IP-Check.
## 3. nginx auf YunoHost
`deploy/assistent.linix.de.nginx.conf` als Vorlage → auf dem YunoHost-Server unter
`/etc/nginx/conf.d/assistent.linix.de.d/assistant.conf` ablegen, `GPU_BOX_LAN_IP`
eintragen, die `map $http_upgrade …` einmalig im http{}-Kontext anlegen, dann
`nginx -t && systemctl reload nginx`. Subdomain `assistent.linix.de` in YunoHost
anlegen (Let's Encrypt) und per SSO schützen (nur erlaubte Tester/Gruppe).
## 4. Discovery: richtigen Identitäts-Header bestimmen
**Hinter dem SSO** aufrufen (durchs SSO-Portal einloggen, dann diese URL). Da das
Gateway den SSO-Admin zu diesem Zeitpunkt noch nicht kennt (Henne-Ei), den Admin-Key
als Query mitgeben:
```
https://assistent.linix.de/api/admin/request-headers?key=<ADMIN_API_KEY>
```
In der Ausgabe den Header finden, der den eingeloggten SSO-Usernamen trägt (z. B.
`X-Remote-User`, `Remote-User`, `Auth-User`, oder `Authorization: Basic …` mit dem
Usernamen). Diesen Namen in `TRUSTED_AUTH_HEADER` **und** in der nginx-`proxy_set_header
`-Zeile eintragen, Gateway + nginx neu laden. Danach `?key=` nicht mehr nutzen
(landet in Proxy-Logs) bzw. den Key rotieren.
## 5. Test
- `https://assistent.linix.de/` lädt die UI, links „Angemeldet als <SSO-User>".
- Text-Chat funktioniert; **Mikrofon-Button** nimmt auf und spielt die Antwort ab.
- Admins (`ADMIN_USERS`) sehen den Admin-Bereich (Nutzerliste).