Replaces the anonymous-OK setup with JWT-gated joins. Only participants that Embertime invited get a valid token — random URL-guessers can no longer enter rooms even if they discover the slug. - ConfigMap: ENABLE_AUTH=1 + AUTH_TYPE=jwt + JWT_APP_ID=embertime - 20-secrets.yaml.example: JWT_APP_SECRET placeholder with docs - CLAUDE.md: documents the new auth model + rotation flow Pipeline rolls config out; the secret itself stays out-of-band — admin copies it from Embertime UI (Settings → Meeting-Server) or queries the embertime DB directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.2 KiB
jitsi-meet — Projekt-Kontext für Claude-Sessions
Selbst-gehostete Jitsi-Meet-Instanz auf darkemberserver via k3s. Same-Cluster-Deploy wie Embertime/Gitea/Headscale. Repo unter ~/Developer/jitsi-meet/, Public-URL https://meet.it.financeflow.de.
Zweck: privater Online-Meeting-Service ohne Google-/GitHub-Login-Zwang (das öffentliche meet.jit.si verlangt seit 2024/25 Moderator-Auth). Wird unter anderem von Embertime als Default-Meeting-URL referenziert.
Architektur
Vier Container nach offiziellem jitsi/docker-jitsi-meet-Pattern:
- web (
jitsi/web): Nginx + Meet-Frontend, exposed via Ingress :443 - prosody (
jitsi/prosody): XMPP-Server, cluster-intern - jicofo (
jitsi/jicofo): Focus/Conference-Manager, cluster-intern - jvb (
jitsi/jvb): Videobridge —hostNetwork: truedamit UDP 10001 direkt auf Node-Interface bindet. UDP 10000 ist auf darkember bereits von einer OpenDesk-Bundle-Jitsi-Instanz belegt (opendesk/jitsi-jvbLoadBalancer-Service), daher Shift auf 10001.
Inter-Component-Auth über shared XMPP-Component-Secrets (im Kubernetes-Secret, nicht im Repo).
Wichtigste Dateien
infra/k3s/00-namespace.yaml— Namespacejitsiinfra/k3s/10-config.yaml— ConfigMap mit nicht-sensiblen Env-Vars (XMPP-Domains, PUBLIC_URL, ...)infra/k3s/20-secrets.yaml.example— Vorlage; echte Secrets manuell erzeugen viascripts/generate-secrets.sh, dannkubectl apply -f infra/k3s/20-secrets.yamleinmalig out-of-bandinfra/k3s/30-prosody.yaml,40-jicofo.yaml,50-web.yaml,60-jvb.yaml— Component-Deployments + Servicesinfra/k3s/70-ingress.yaml— Ingress mit cert-manager (letsencrypt-prod ClusterIssuer).gitea/workflows/deploy.yml—kubectl apply -f infra/k3s/...auf Push nach mainscripts/generate-secrets.sh— generiert random Component-Passwords + schreibt20-secrets.yaml
Setup-Schritte (einmalig)
- DNS: A-Record
meet.it.financeflow.de→ öffentliche IP von darkemberserver - Firewall/Router: UDP-Port 10001 auf darkember-Node forwarden (kritisch! ohne das funktioniert nur Audio, kein Video). Hinweis: 10000 ist von OpenDesks Jitsi-Bundle belegt, daher der Versatz.
- Secrets generieren + applyen:
./scripts/generate-secrets.sh > infra/k3s/20-secrets.yaml # DOCKER_HOST_ADDRESS in 60-jvb.yaml auf die Public-IP von darkember setzen kubectl apply -f infra/k3s/20-secrets.yaml - Gitea-Repo + Secret KUBECONFIG_B64: Repo bei Gitea anlegen, KUBECONFIG_B64 als Repo-Secret hinterlegen (gleicher Wert wie bei Embertime), push.
Danach: Pipeline rollt aus, in ~3 Min steht https://meet.it.financeflow.de.
Auth-Modell (JWT, Stand 2026-05-11)
Prosody ist auf AUTH_TYPE=jwt (HS256) konfiguriert — Joins ohne signiertes Token werden abgelehnt. Embertime ist der einzige Token-Issuer:
- HMAC-Secret lebt in
app_settings.meeting_jwt_secret(Embertime-DB) - Wird auch im k8s-Secret
jitsi-secretsalsJWT_APP_SECRETbenötigt — beide müssen identisch sein - Embertime-Endpoint
GET /meetings/:id/joinmintet pro Teilnehmer + Meeting ein zeitlich begrenztes Token (gültig bis Meeting-Ende + 2h) - Token-Payload enthält
room(= room_slug),context.user(Display-Name + email + moderator-Flag)
Bei Secret-Rotation: neuer Wert über Embertime-Admin-UI sichtbar, dann kubectl -n jitsi patch secret jitsi-secrets ... + kubectl -n jitsi rollout restart deployment (sonst gilt noch der alte JWT_APP_SECRET in den laufenden Pods).
Was NICHT machen
ENABLE_AUTH=0zurücksetzen — würde das ganze Auth-Modell unwirksam machen. Wenn du eine offene Instanz brauchst, lieber zweite Jitsi-Instanz auf anderem Subdomain.- Keinen Jibri (Recording) ohne expliziten Auftrag — braucht extra Pod mit Chrome + viel mehr Ressourcen
- Kein Helm — bleibt beim raw-Manifest-Pattern wie Embertime
- Nicht
replicas > 1für prosody/jicofo — beide sind stateful Single-Instance - JVB skaliert prinzipiell horizontal, aber für ein Single-Cluster reicht 1 Replica
Verwandt im Obsidian-Vault
feedback_git_workflow.md— Klone-Pfad, Gitea-SSH-Setup- Embertime-CLAUDE.md (
~/Developer/embertime/CLAUDE.md) — gleicher Deploy-Pattern, gleiches KUBECONFIG-Secret