# Modul-Marketplace: Verbindungen und Katalog ## Zielbild Die Modulverwaltung bietet neben installierten Modulen einen Marketplace. Administratoren verbinden dort GitHub oder eine Gitea-/Forgejo-Instanz, wählen ausdrücklich Repositories als Katalogquellen aus und installieren veröffentlichte Modul-Releases per Klick. ```text OAuth-Verbindung -> Repository auswählen -> Release-Katalog -> Paket prüfen -> Installieren ``` ## Verbindungen - OAuth Authorization Code mit `state` und PKCE (S256). - Tokens bleiben ausschließlich im Backend, werden verschlüsselt gespeichert, nie in API-Antworten aufgenommen und bei jeder Verwendung nur mit minimal notwendigen Leserechten eingesetzt. - Verbindung, Katalogquelle und installierte Module sind getrennte Datensätze. Trennen einer Verbindung entfernt keine installierten Module. - Selbst gehostete Gitea-/Forgejo-Instanzen benötigen eine OAuth-Anwendung auf der jeweiligen Instanz. Callback-URL ist die öffentliche MPM-URL plus `/api/v1/marketplace/oauth//callback`. - OAuth-Client-Secrets und Verschlüsselungsschlüssel gehören in die Serverkonfiguration bzw. einen Secret Store, nie in das Frontend oder Repository. ## Katalog und Installation - Der Katalog lädt öffentliche Repositories verbundener Forge-Konten. Installiert wird der aktuelle Stand des jeweiligen Standard-Branches. - MPM lädt das vom Forge erzeugte Quellarchiv serverseitig, entfernt den Archiv-Stammordner und erwartet `module.json` im Repository-Stamm. ## Container-Vertrag für Module Installierbare Module müssen neben `module.json` eine Compose-Datei und einen App-Service enthalten: ```json { "composeFile": "compose.yml", "appService": "app" } ``` Der App-Service muss den Manifest-Port im Container bereitstellen (`expose`, kein `ports`) und auf `0.0.0.0` lauschen. Datenbanken gehören als weitere Services in dieselbe Compose-Datei. Die Dienste teilen ein privates Compose-Netz; nur der App-Service wird zusätzlich an das MPM-Gateway angeschlossen. Für SQLite kann der App-Service `/var/lib/mpm-module` als persistenten Speicher unter `MPM_MODULE_DATA_DIR` verwenden. Datenbankcontainer definieren eigene projektlokale named volumes. MPM startet/stoppt den gesamten Stack gemeinsam. Beim Entfernen löscht Compose alle App- und Datenbankcontainer, das Projekt-Netzwerk und sämtliche projektbezogenen Datenvolumes. Eine spätere Neuinstallation beginnt dadurch ohne die vorherigen Modul-Daten. Pakete dürfen keine Host-Ports, Host-Verzeichnisse, externen Docker-Ressourcen, privilegierten Optionen oder Docker-Socket-Mounts anfordern. Die Modulverwaltung benötigt Zugriff auf den Docker-Socket des Hosts; deshalb dürfen nur vertrauenswürdige Administratoren Module installieren. - Vor der Installation prüft MPM Downloadgröße, Archivpfade, Symlinks, Manifest und Modul-ID. Die bestehende `ModuleInstaller`-Validierung bleibt die letzte Instanz. - Der Browser übermittelt keine Download-URL; MPM erstellt sie aus Anbieter, Besitzer, Repository und Standard-Branch. - Die Installation registriert das Modul. Das Starten bleibt ein separater Lifecycle-Schritt und erfolgt erst nach Bestätigung durch den Administrator. - Verbindungen, Quellrepository, Release-Tag und Prüfsumme werden im Audit-Log erfasst; Secrets und Tokens niemals. ## GitHub-Rechte Für den ersten Verbindungs-Test wird eine GitHub OAuth App mit `read:user` verwendet. Das erlaubt MPM, das autorisierte Konto anzuzeigen; öffentliche Release-Kataloge können separat unauthentifiziert gelesen werden. Private GitHub-Repositories werden in dieser ersten Phase nicht abgerufen. Dafür soll später eine GitHub App mit `Contents: read` eingesetzt werden: OAuth Apps bieten für Quellcode keinen reinen Read-only-Scope und der klassische `repo`-Scope umfasst Schreibzugriff. Gitea und Forgejo verwenden kompatible Release- und Repository-APIs, aber jede selbst gehostete Instanz bleibt eine eigene OAuth-Konfiguration und eine explizit vertrauenswürdige Quelle. ## Umsetzungsschritte 1. OAuth-Provider-Konfiguration und verschlüsselte Zugangsdaten samt Datenbankmigration. 2. OAuth-Start/Callback mit zufälligem, einmalig verwendbarem `state`, Ablaufzeit, PKCE und Bindung an die anmeldende Admin-Session. 3. Verbindungen anzeigen und trennen; niemals Tokens zurückgeben. 4. Öffentliche Repositories verbundener Forge-Konten direkt als installierbaren Katalog anzeigen. 5. Repository-Archive vom Standard-Branch laden und vor dem Installieren sicher normalisieren. 6. Installation in die bestehende Modulregistrierung integrieren, auditieren und im UI anzeigen. Module starten nach der Installation nicht automatisch. ## Branch-basierte Modulupdates Marketplace-Installationen speichern Repository, installierte Branch und Commit-ID. MPM prüft das Repository alle fünf Minuten und bietet in der Modulverwaltung über **Update verfügbar** jede andere Branch als mögliche getestete Version an. Der Administrator wählt im Dialog eine Branch aus. Es wird nichts automatisch installiert. Das Update wird anhand des gewählten Branch-Commits geladen und durchläuft dieselbe Archiv- und Manifestprüfung wie eine Neuinstallation. Modul-ID, URL-Slug, Port und Compose-App-Service müssen stabil bleiben. MPM tauscht den Modulcode mit einer temporären Sicherung aus, behält die persistenten Daten und verschlüsselte Modulkonfiguration und startet zuvor laufende Module anschließend erneut. Schlägt der Start fehl, stellt MPM den vorherigen Code und das Datenbankmanifest wieder her. Datenbankinhalte in Modulvolumes werden nicht automatisch zurückgerollt; Modulmigrationen müssen daher rückwärtskompatibel sein oder eigene Sicherungs-/Wiederherstellungsverfahren bieten. Die installierte Branch wird nicht als Update angeboten. Auch bei einer Neuinstallation bleiben alternative Branches auswählbar, selbst wenn sie bereits vor der Installation im Repository vorhanden waren. ## Aktueller Umfang Der Marketplace in der Modulverwaltung unterstützt öffentliche Repositories von GitHub, Gitea und Forgejo. Private Repositories und Suche über fremde Katalogserver sind noch nicht enthalten. ## Voraussetzungen für den Betrieb Für die OAuth-Anmeldung müssen je Provider/Instanz Client-ID und Client-Secret in MPM hinterlegt werden. Die öffentliche HTTPS-URL der Plattform muss stabil sein, da sie als OAuth-Callback registriert wird. Vor Aktivierung privater GitHub-Repositories ist die GitHub-App mit Read-only-Berechtigung zu konfigurieren.