Mandantenisolation in PostgreSQL: eigene Instanz, Schema oder Row-Level Security?
Jedes SaaS-Produkt auf PostgreSQL muss diese Frage beantworten, bevor es dimensioniert, bepreist oder auditiert werden kann. Es gibt drei übliche Kandidaten, sie sind nicht gleich gut, und die richtige Antwort hängt weniger von deinem technischen Geschmack ab als davon, wer sie am Ende glauben muss.
Unsere Empfehlung für regulierte Daten, gleich vorweg: eine eigene PostgreSQL-Instanz pro Grosskunde, darunter Schema-Trennung für die einzelnen Mandanten. Der Rest dieser Seite erklärt, warum, und was dich das kostet, denn gratis ist es nicht.
Die drei Modelle
Row-Level Security
Eine Datenbank, ein Schema, ein Satz Tabellen. Jede Zeile trägt eine Mandantenkennung, und die Richtlinien der Row-Level Security von PostgreSQL filtern, was eine Sitzung sehen darf.
Das ist im Betrieb das günstigste Modell und im Nachweis das anspruchsvollste. Die Korrektheit hängt daran, dass jede Sitzung den richtigen Kontext setzt, dass jede Richtlinie stimmt und dass kein Codepfad daran vorbeikommt. Alle drei sind Eigenschaften deiner Applikation und nicht der Datenbankgrenze.
Genau dieser Unterschied zählt im Audit. Ein Prüfer kann Row-Level Security nicht verifizieren, indem er in die Datenbank schaut. Er muss über deinen Applikationscode nachdenken, und du musst das auch, jedes Mal wenn ein neuer Abfragepfad dazukommt. Für Mandanten, die nicht selbst reguliert sind, ist das eine vertretbare Wahl. Wenn deine Mandanten Versicherer oder Banken sind, ist es von den dreien das am schwersten zu verteidigende.
Schema-Trennung
Eine Instanz, eine Datenbank, ein Schema pro Mandant. Die Tabellen sind physisch getrennt, eine Verbindung lässt sich auf ein Schema einschränken, und ein Fehler im Applikationscode liefert viel seltener fremde Zeilen zurück.
Das gibt dir echte Datentrennung bei nur einer Instanz im Betrieb und passt gut für viele Mandanten mittlerer Grösse. Was es nicht gibt, ist Trennung von allem rundherum. Die Mandanten teilen sich eine Instanz und damit deren Ressourcen, deren Wartungsfenster, deren Major-Upgrade und deren Zeitachse für Point-in-Time Recovery. Einen einzelnen Mandanten auf letzten Dienstag zurückzusetzen heisst, die ganze Instanz zurückzusetzen.
Eigene Instanz pro Mandant
Jeder Kunde bekommt seine eigene PostgreSQL-Instanz mit eigenen Zugangsdaten, eigenen Backups, eigener Wiederherstellungszeitachse und eigenem Upgrade-Fahrplan.
Dieses Modell übersteht den Kontakt mit dem Prüfer eines regulierten Kunden, weil die Grenze eine ist, die er sehen kann. Die Trennung ist eine Tatsache des Deployments und keine Behauptung über deinen Code. Konkret bekommst du:
- Zugangsdaten pro Mandant. Ein abgeflossener Connection String betrifft einen Kunden.
- Backup und Restore pro Mandant. Du kannst einen Kunden auf einen Zeitpunkt zurückholen, ohne alle anderen anzufassen. Das ist der Unterschied zwischen einem eingegrenzten Vorfall und einem Ausfall für alle.
- Ein sauberer Auditscope. Wenn der Prüfer eines Kunden fragt, was sonst noch in der Datenbank mit seinen Daten liegt, lautet die Antwort: nichts.
- Ein sauberer Ausstieg. Offboarding ist ein Dump und eine Löschung, kein gefilterter Auszug, dessen Vollständigkeit du belegen musst.
Was es kostet
Eine eigene Instanz pro Kunde vervielfacht sich. Jede trägt ihre eigene Servicegebühr und ihren eigenen Storage, damit ist dein Isolationsmodell zugleich dein Skalierungsmodell. Ein zusätzlicher Grosskunde erzeugt wiederkehrende Kosten, und die gehören in deine eigene Preisgestaltung, bevor du ihn unterschreibst, nicht danach.
Das ist der ehrliche Zielkonflikt. Row-Level Security skaliert günstig auf viele Mandanten und ist schwer nachzuweisen. Eigene Instanzen sind leicht nachzuweisen und wachsen linear in den Kosten. Wer dir sagt, ein Modell sei auf beiden Achsen besser, will dir etwas verkaufen.
Die Form, die wir meistens empfehlen
Die wenigsten Schweizer B2B-SaaS-Produkte sind flach. Typisch sind einige wenige Grosskunden mit jeweils vielen Nutzern, dazu oft eine Hierarchie: deine Plattform, darunter ein Grosskunde, darunter dessen Abteilungen oder Tochtergesellschaften.
Daraus wird eine Mischform, und sie hat dieselbe Gestalt wie die kaufmännische Realität:
| Ebene | Trennung | Warum |
|---|---|---|
| Grosskunde | Eigene Instanz | Sein Prüfer stellt die Fragen, und sein Vertrag steht auf dem Spiel |
| Mandanten innerhalb dieses Kunden | Schema pro Mandant | Dieselbe juristische Person, derselbe Verantwortliche, Trennung aus Ordnung und nicht wegen einer Aufsicht |
| Einzelne Nutzer | Berechtigungen in der Applikation | Keine Sache der Datenbank |
Die Grenze liegt dort, wo die rechtliche Verantwortung wechselt. Das ist eine Regel, die du einem Prüfer in einem Satz erklären kannst, und das ist mehr wert als ein geringfügig günstigeres Design, das du in zehn Sätzen verteidigen musst.
Wie das auf Managed PostgreSQL aussieht
VSHN Managed PostgreSQL betreibt jede Instanz hochverfügbar als Primary und Replica mit automatischem Failover, mit Point-in-Time Recovery und Verschlüsselung im Ruhezustand. Die Instanzen laufen auf deinem eigenen Kubernetes-Cluster. Eine Instanz für einen neuen Kunden kostet deshalb ihre Servicegebühr und ihren Storage, ohne dass ein weiterer Cluster zu betreiben wäre.
Backups gehören zum Service. Rechenleistung und Arbeitsspeicher kommen aus dem Cluster, den du ohnehin betreibst. Damit sind die Kosten pro Kunde besser vorhersehbar, als es auf den ersten Blick wirkt.
Wenn du gerade ausrechnest, was deine Isolationsentscheidung mit deinen Stückkosten macht, buche ein Gespräch. Wir rechnen dir die Variante durch, die du im Kopf hast.
Weiterführend
- Was ist PostgreSQL? falls die Datenbankwahl noch offen ist
- Vergleich der Managed-PostgreSQL-Angebote in der Schweiz
- Souveränität zu Gerichtsstand und Datenstandort