docs(communication): document federation pilot setup and validation

This commit is contained in:
2026-09-30 14:50:13 +02:00
parent 7b5696eda4
commit ca2d14b01e

View File

@@ -1,6 +1,6 @@
# Konzept: Föderierte Chats und externe Projektteilnehmer # Konzept: Föderierte Chats und externe Projektteilnehmer
Stand: 26. September 2026. Status: Architekturvorschlag auf Basis des FEDEO-Codes bei Commit `df48c976`. Dieses Dokument beschreibt ein Zielbild; Föderation, Gastzugang und die genannten APIs sind noch nicht implementiert. Es wurden keine Einladungen verschickt und keine laufenden Instanzen verändert. Stand: 30. September 2026. Das ursprüngliche Zielbild basiert auf Commit `df48c976`. Die Schritte 0, 1a, 1b und ein föderierter Web-Pilot aus Schritt 2 sind inzwischen implementiert (`21fe4723`, `ea641bb4`, `7b5696ed`). Die folgenden Architekturkapitel enthalten weiterhin spätere Ausbaustufen; den tatsächlichen Lieferumfang, die Einrichtung und verbleibende Grenzen beschreibt Abschnitt 15. Es wurden keine produktiven Instanzen verändert oder echten Einladungen versendet.
## 1. Empfehlung ## 1. Empfehlung
@@ -277,3 +277,55 @@ Migrationen erfolgen additiv mit Backfill für öffentliche IDs und lokale Princ
16. Archivierung erlaubt nur weiterhin berechtigtes Lesen; Sperrung verweigert auch direkte Inhaltsabrufe. Ein Wechsel der Projektzuordnung kann keine vorhandene Unterraumhistorie offenlegen. 16. Archivierung erlaubt nur weiterhin berechtigtes Lesen; Sperrung verweigert auch direkte Inhaltsabrufe. Ein Wechsel der Projektzuordnung kann keine vorhandene Unterraumhistorie offenlegen.
Als erster nutzbarer Meilenstein wird **ein abgegrenzter Projekt-Unterraum mit eigenem Chat und expliziten Einladungen** empfohlen. Zuerst wird die Mandantentrennung lokal geprüft, anschließend der Gastzugang ergänzt. Auf diesem gemeinsamen Modell baut der instanzübergreifende Transport auf. Als erster nutzbarer Meilenstein wird **ein abgegrenzter Projekt-Unterraum mit eigenem Chat und expliziten Einladungen** empfohlen. Zuerst wird die Mandantentrennung lokal geprüft, anschließend der Gastzugang ergänzt. Auf diesem gemeinsamen Modell baut der instanzübergreifende Transport auf.
## 15. Implementierter Stand und Pilotbetrieb
### Verfügbare Abläufe
Unter **Kommunikation → Zusammenarbeit** können interne Teilnehmer ihre eigenen Unterräume und Einladungen öffnen. Projektverantwortliche mit `organisation.projects.write` beziehungsweise Administratoren können Unterräume verwalten und freie Partnerchats anlegen. Der Projektkopf verlinkt ebenfalls auf die Zusammenarbeit. Die Verwaltung eines Raums berechtigt weiterhin nicht zum Lesen seiner Nachrichten; nur der Ersteller wird bei der Anlage automatisch Teilnehmer.
Einladungen unterstützen eigene Mitarbeiter, persönliche FEDEO-Kontaktadressen und Gäste ohne FEDEO-Konto. Eine Kontaktadresse bezeichnet immer genau einen Benutzer in einem Heimatmandanten. Sie lässt sich in der Zusammenarbeit kopieren. Kontakte anderer Mandanten derselben Instanz benötigen keinen Server-Server-Transport. Fremde Instanzen müssen auf beiden Seiten im jeweiligen Mandanten unter **Partnerinstanzen** freigegeben sein. Beim Empfänger erscheint ein Angebot, das ausdrücklich angenommen oder abgelehnt wird.
Gäste erhalten ausschließlich einen Projekt-Unterraum. Der Link öffnet `/guest`; ein achtstelliger, zehn Minuten gültiger Einmalcode wird an die eingeladene Adresse geschickt. Nach fünf falschen Versuchen ist der Code gesperrt. Die eigene Gastsitzung gilt zwölf Stunden und wird nicht als reguläres FEDEO-Token akzeptiert. Für spätere Anmeldungen bietet die Gastoberfläche eine als Lesezeichen speicherbare Adresse mit öffentlicher Workspace-ID an. Ohne gewähltes Ablaufdatum gilt die Teilnahme eines Gasts 30 Tage. Der Einladungslink allein erlaubt keinen Inhaltszugriff.
Rollen sind **Lesen und schreiben** sowie **Nur lesen**. Eine gesonderte Freigabe erlaubt die manuell zusammengestellte Projektübersicht mit ausschließlich Titel, Status, Termin und Beschreibung. Interne Projektfelder werden nicht automatisch übertragen. Die Nachrichtenhistorie beginnt beim Beitritt; nach Entzug und erneuter Einladung beginnt sie erneut. Archivierung erlaubt berechtigtes Lesen, Sperrung verhindert Inhaltszugriffe. Mitgliedschaften und offene Einladungen können widerrufen werden.
Die Eigentümerinstanz vergibt die Nachrichtenreihenfolge und prüft jeden Zugriff. Einladungen, Änderungs- und Widerrufshinweise sowie ausgehende Nachrichten werden dauerhaft vorgemerkt. Wiederholungen erzeugen keine doppelten Nachrichten. Nachrichten tragen zusätzlich die Version der Teilnahme, damit alte Aufträge nach Rechteänderungen oder einer erneuten Einladung nicht ausgeführt werden. Die Oberfläche unterscheidet wartende, bestätigte und fehlgeschlagene Nachrichten. Fehlgeschlagene Einladungslieferungen können in der Verwaltung erneut angestoßen werden.
Bei einem vorübergehend nicht erreichbaren Eigentümer sind bereits geladene Nachrichten mit einem Offline-Hinweis lesbar; die Projektübersicht wird dann ausgeblendet. Neue Nachrichten warten auf erneute Autorisierung beim Eigentümer. Eine bestätigte Zugangssperre entfernt den lokalen Nachrichtencache. Bereits ausgelieferte Informationen können bei einem fremden Betreiber grundsätzlich nicht sicher zurückgerufen werden.
### Einrichtung
1. Vor dem Backendstart die additiven Migrationen `0075_project_collaboration.sql` und `0076_collaboration_federation.sql` über den bestehenden Migrationslauf einspielen. Der Selfhost-Container führt standardmäßig `npm run migrate` aus. Bestehende interne Chats bleiben getrennt; kein vorhandener Chat wird automatisch freigegeben.
2. `FEDEO_PUBLIC_URL` auf die öffentliche Webadresse setzen. Für Gastcodes und optional versendete Einladungs-E-Mails muss der bestehende SMTP-Versand funktionieren. `ENCRYPTION_KEY` muss wie für die übrige Backend-Verschlüsselung ein stabiler 64-stelliger Hex-Schlüssel sein.
3. Für den instanzübergreifenden Pilotbetrieb `FEDEO_FEDERATION_URL` auf die kanonische öffentliche HTTPS-API-Adresse setzen, einschließlich des Reverse-Proxy-Präfixes, etwa `https://fedeo.example/backend`. Anschließend `FEDEO_FEDERATION_ENABLED=true` setzen. Die Variablen sind in `.env.example` und `docker-compose.selfhost.yml` aufgenommen. Föderation ist standardmäßig deaktiviert; lokale Unterräume und Gäste funktionieren unabhängig davon.
4. Der Proxy muss `GET <API-Adresse>/.well-known/fedeo-federation` und `POST <API-Adresse>/federation/v1/rpc` durchreichen und darf JSON-Body oder Signaturheader nicht verändern. Externe Ziele benötigen öffentlich auflösbare HTTPS-Adressen auf Port 443. Private/reservierte IPv4- und IPv6-Ziele sowie Weiterleitungen werden abgewiesen; die geprüfte DNS-Adresse wird für die TLS-Verbindung festgehalten.
5. In beiden beteiligten Mandanten die jeweils andere API-Adresse unter **Partnerinstanzen** freigeben. Discovery ermittelt Instanz-ID und öffentlichen Schlüssel über HTTPS. Die erste Freigabe pinnt diese Identität. Ein später abweichender Schlüssel wird abgelehnt und braucht eine gesonderte Betreiberprüfung; eine automatische Schlüsselrotation ist noch nicht vorhanden.
6. Persönliche Kontaktadresse des Empfängers verwenden, gezielt in einen Unterraum einladen und beim Empfänger annehmen. Für einen ersten Pilotversuch anschließend Rechteänderung, Widerruf und eine vorübergehend unterbrochene Verbindung prüfen.
Das feste Signaturprofil verwendet Ed25519 mit HTTP Message Signatures und Content-Digest. Signiert werden Methode, vollständige Zieladresse, Inhaltstyp, Inhaltsdigest und Herkunft; Zeitfenster und gespeicherte Nonces verhindern Replay. Das RPC-Protokoll ist Version 1 und ausschließlich für diese FEDEO-Implementierung bestimmt. Es ersetzt weder Matrix-Kompatibilität noch Ende-zu-Ende-Verschlüsselung.
### Speicherung, Betrieb und Wiederaufnahme
Die tatsächlichen Tabellen heißen `collaboration_workspaces`, `collaboration_principals`, `collaboration_rooms`, `collaboration_members`, `collaboration_invitations`, `collaboration_messages` sowie die zugehörigen Gast- und Audittabellen. Der Föderationsteil ergänzt `collaboration_federation_identity`, `collaboration_partners`, `collaboration_federation_nonces`, `collaboration_remote_bindings`, `collaboration_remote_messages` und `collaboration_outbox`. Lokale Identitäten werden bei Nutzung erzeugt; es gibt keinen automatischen Versand oder Backfill bestehender Chatinhalte.
Der Worker läuft alle fünf Sekunden, beansprucht Aufträge mit einer zeitlich begrenzten Sperre und wiederholt vorübergehende Fehler mit wachsender Wartezeit. Dauerhafte Ablehnungen oder 20 erfolglose Versuche beenden die Zustellung. Einladung und ausgehender Zustellauftrag werden atomar gespeichert. Nachrichtencache und Synchronisationsposition sind getrennt, damit eine sofort bestätigte eigene Nachricht keine noch nicht abgeholten Nachrichten überspringt. Gastcodes, abgelaufene Sitzungen, Nonces und alte Ratenzähler werden regelmäßig bereinigt. Für Nachrichten, Audit und Zustellhistorie ist noch keine automatische Aufbewahrungsrichtlinie implementiert.
Datenbank und `ENCRYPTION_KEY` gemeinsam sichern; der private Instanzschlüssel liegt verschlüsselt in der Datenbank. Ein normaler Prozessneustart behält Instanzidentität, aktive Teilnahmen und ausstehende Aufträge. Eine Partnerblockade stoppt neue autorisierte Zugriffe und Zustellungen. Ist dadurch die lokale Bindung widerrufen worden, muss der Eigentümer die alte Teilnahme entziehen und neu einladen. Beim Abschalten der Föderation bleiben lokale Chats und Gäste verfügbar. Für einen dauerhaften Austritt externe Teilnahmen vor der Abschaltung entziehen. Ein Restore eines alten Backups sowie Schlüsselverlust oder Schlüsselwechsel brauchen eine Betreiberabstimmung mit den Partnern; dafür besteht noch kein automatischer Wiederherstellungsablauf.
### Prüfung und verbleibender Ausbau
Geprüft wurden 21 Tests ohne Überspringen auf einer isolierten PostgreSQL-17-Testdatenbank. Darunter sind die Absicherung bestehender Chatgrenzen, die Trennung von Gast- und regulären Sitzungen, benachbarte Unterräume, der Historienbeginn, abgelaufene und widerrufene Einladungen sowie zwei unabhängige Instanzdatenbanken mit echten Fastify-Routen und Signaturprüfung. Der Transport zwischen diesen Instanzen ist im Test simuliert: Verbindungsfehler, verlorene Bestätigungen, doppelte Zustellung, veraltete Teilnahmeversionen, verspätete Widerrufe und erneute Einladungen werden gezielt erzeugt. HTTPS/DNS-Einschränkungen und Signaturmanipulationen besitzen zusätzliche Tests. Eine Verbindung zwischen zwei produktiven HTTPS-Installationen wurde nicht ausgeführt.
Reproduzierbar aus `backend/` mit einer ausdrücklich bereitgestellten, entbehrlichen Datenbank namens `collaboration_test`:
```sh
COLLABORATION_TEST_DATABASE_URL=postgresql://USER:PASSWORD@127.0.0.1:PORT/collaboration_test \
node --import tsx --test tests/communicationAccess.test.ts tests/collaboration.test.ts \
tests/collaborationRoutes.test.ts tests/collaborationFederation.test.ts
```
Jeder Datenbanktest erzeugt ein eigenes Schema und räumt es anschließend auf. Ohne gesetzte Testadresse werden die Datenbanktests bewusst übersprungen; der Datenbankname wird vor dem Anlegen geprüft. Backend-Typprüfung und Nuxt-Produktionsbuild waren erfolgreich, die abschließenden Vue-Komponenten lassen sich kompilieren. Eine visuelle Browserabnahme war in der Arbeitsumgebung mangels verbundenem Browser nicht möglich.
Die nächste Ausbaustufe aus Schritt 3 umfasst insbesondere native Mobile-Parität, Push-Benachrichtigungen, Moderation, feinere Kontingente sowie Schlüsselrotation und abgestimmte Wiederherstellung. Dateifreigaben, Aufgabenfreigaben und E2EE sind weiterhin Erweiterungen. Der hier implementierte Stand ist ein nutzbarer Web-Pilot für Chats und ausdrücklich begrenzte Projektzusammenarbeit; ein produktiver Rollout ist damit noch nicht erfolgt.