Eine Mandanten-ID wählt aus, sie erteilt kein Recht
Ein Mandant ist hier eine organisatorische Einheit, deren Daten und Befugnisse abgegrenzt werden sollen, etwa ein Kundenunternehmen. Eine Person kann Mitglied mehrerer Mandanten sein. Sie muss dann einen auswählen dürfen; diese Auswahl allein beweist ihre Mitgliedschaft nicht.
Behandeln Sie tenant_id im Pfad, Header oder Requestbody als Auswahl. Der Server prüft, ob die verifizierte Identität im gewählten Mandanten handeln darf und welche Rolle dort aktuell gilt. Selbst eine signierte Tokenangabe benötigt einen passenden Vertrauensvertrag: Stimmt der Aussteller, gilt das Token für diese API, und welche Aktualität garantiert die enthaltene Mitgliedschaft? OWASP Multi Tenant Security, Tenant Identification.
Nach dieser Prüfung sollte ein klarer interner Kontext durch die Verarbeitung laufen. Nachgelagerte Komponenten dürfen ihn nicht mit einem ungeprüften Header überschreiben. Fehlt der Kontext für einen mandantengebundenen Vorgang, muss die Anwendung ihn ablehnen; eine Abfrage ohne Mandantenbedingung wäre kein sicherer Ersatz.
Kennzeichnen Sie eigene, geteilte und administrative Daten
Nicht jede Tabelle muss einem einzelnen Mandanten gehören. Ein öffentlicher Produktkatalog kann bewusst gemeinsam sein. Eine Plattformverwaltung kann ausdrücklich mehrere Mandanten bearbeiten. Entscheidend ist eine dokumentierte Einordnung, damit „kein Mandantenfeld“ nicht versehentlich „für alle lesbar“ bedeutet.
Bei schmaler Ansicht können Sie die Tabelle seitlich scrollen.
| Datenklasse | Beispiel | Benötigte Entscheidung |
|---|---|---|
| Einem Mandanten zugeordnet | Bericht, Rechnung, interner Kommentar | Aktiver Kontext und passende Rechte im zugeordneten Mandanten |
| Bewusst gemeinsam | Öffentliche Vorlagen | Welche Inhalte und Aktionen tatsächlich öffentlich sind |
| Explizit organisationsübergreifend geteilt | Gemeinsamer Projektraum | Eigene Freigaberegel mit Umfang und Widerruf |
| Plattformadministration | Enger Supportvorgang | Gesonderter privilegierter Weg und begrenzte Befugnis |
Auch Beziehungen müssen passen. Es reicht nicht, dass ein neuer Bericht den richtigen tenant_id erhält, wenn seine angehängte Datei einer anderen Organisation gehört. Prüfen Sie referenzierte Objekte nach derselben fachlichen Grenze. Datenbankbedingungen können solche Invarianten zusätzlich erzwingen, ersetzen aber nicht die Benutzerrechte. Die BOLA-/IDOR-Grundlage erklärt den einzelnen Objektzugriff.
Wählen Sie eine Speicherschranke, die Sie wirklich betreiben können
Getrennte Datenbanken, getrennte Schemas und gemeinsame Tabellen haben unterschiedliche Betriebsfolgen. Eine getrennte Datenbank kann eine zusätzliche Grenze schaffen, wenn Verbindungen, Zugangsdaten und administrative Wege entsprechend getrennt sind. Ein gemeinsames privilegiertes Konto für alle Datenbanken kann einen Teil dieses Vorteils wieder aufheben. Gemeinsame Tabellen benötigen konsequente mandantenbezogene Abfragen und gegebenenfalls zusätzliche Datenbankrichtlinien.
Eine verbreitete Ergänzung ist Row-Level Security (RLS): Die Datenbank schränkt sichtbare oder veränderbare Zeilen anhand einer Policy ein. Bei PostgreSQL ist dabei die tatsächlich verwendete Rolle entscheidend. Superuser und Rollen mit BYPASSRLS umgehen die Zeilenrichtlinien; Tabelleneigentümer normalerweise ebenfalls, sofern sie nicht mit FORCE ROW LEVEL SECURITY einbezogen werden. FORCE bindet jedoch weder Superuser noch BYPASSRLS-Rollen. PostgreSQL 18: Row Security Policies.
Das ist kein Rezept, RLS ungeprüft in Produktion einzuschalten. Vor einer Einführung müssen Tabellen, Richtlinien, Schreibfälle, privilegierte Jobs, Fehlerwege und die reale Verbindungsrolle zusammen geprüft werden. Eine aus Versehen uneingeschränkte Rolle macht einen korrekten Policytext wirkungslos.
Wiederverwendete Verbindungen dürfen keinen Mandanten „behalten“
Verbindungspools teilen Datenbankverbindungen zwischen Anfragen. Wenn Mandant A einen Sitzungswert setzt und die Verbindung später an Mandant B geht, kann ein übrig gebliebener Wert den nächsten Zugriff beeinflussen.
Für PostgreSQL kann ein transaktionslokaler Kontext Teil der Lösung sein: SET LOCAL gilt nur bis zum Ende der aktuellen Transaktion. Er muss in derselben Transaktion wie die davon abhängigen Abfragen gesetzt werden. Das normale SET hat grundsätzlich einen anderen, sitzungsbezogenen Lebenszyklus. Außerhalb eines Transaktionsblocks hat SET LOCAL nicht die gewünschte Wirkung. PostgreSQL 18: SET.
Die Anwendung muss trotzdem jede Transaktion mit korrekt geprüftem Kontext beginnen und sie vor Rückgabe an den Pool abschließen oder zurückrollen. Prüfen Sie den realen Poolmodus und Nebenpfade. Ein isolierter Datenbanktest mit einer anderen Rolle oder ohne Verbindungswiederverwendung beweist diesen Ablauf nicht.
Behalten Sie die Grenze in Cache, Dateien und Jobs
Bei schmaler Ansicht können Sie die Tabelle seitlich scrollen.
| Übergabe | Konkrete Frage | Passende Maßnahme im eigenen Entwurf |
|---|---|---|
| Antwort- oder Anwendungscache | Können zwei Mandanten denselben Cacheeintrag treffen? | Mandant und alle weiteren rechteabhängigen Varianten in der Cacheidentität berücksichtigen oder solche Antworten nicht gemeinsam cachen |
| Erzeugte Datei | Wer darf den Dateischlüssel oder Downloadlink nutzen? | Datei einem verifizierten Mandanten zuordnen und Zugriff erneut passend autorisieren |
| Warteschlange | Kann der Auftrag später ohne Requestkontext laufen? | Serverseitig geprüften Mandanten und Auftraggeber gebunden übergeben; Worker prüft den vorgesehenen Ausführungskontext |
| Rechteänderung vor Jobstart | Was geschieht nach Austritt oder Widerruf? | Bewusst entscheiden, ob und wann der Auftrag erneut autorisiert oder abgebrochen werden muss |
| Logs und Auswertungen | Können Support oder Kunden fremde Ereignisse sehen? | Zugriff auf gespeicherte Ereignisse selbst mandantenbezogen begrenzen |
Ein Cacheeintrag nur unter report:17 wäre problematisch, wenn diese Kennung pro Mandant vorkommt. tenant:<geprüfte-id>:report:17 trennt diesen Fall, ist aber noch keine allgemeine Lösung: Unterschiedliche Feldrechte, Sprache oder Version können weitere Varianten verlangen. Der Cache darf die Rechteentscheidung auch bei einem Treffer nicht umgehen. Die HTTP-Grundlagen liefert HTTP-Befunde lesen; hier geht es zusätzlich um interne Anwendungscaches.
Ein Worker hat oft mehr technische Rechte als ein normaler Benutzer. Deshalb darf ein Job nicht allein wegen dieser technischen Rechte beliebige Mandanten bearbeiten. Definieren Sie, ob er einen bereits verbindlich angenommenen Auftrag ausführt oder aktuelle Benutzerrechte benötigt. Beide Modelle brauchen eine klare, nachvollziehbare Begrenzung.
Prüfen Sie genau die Übergänge, die Ihre Anwendung verwendet
Richten Sie zwei synthetische Mandanten mit bewusst ähnlichen Datensätzen ein. Gleiche lokale Objektkennungen helfen, falsche Cache- und Dateizuordnungen sichtbar zu machen. Nutzen Sie die tatsächliche Anwendungsrolle und den vorgesehenen Poolpfad in einer isolierten Umgebung.
Prüfen Sie nacheinander einen erlaubten Zugriff, denselben Zugriff im anderen Mandanten, einen Kontextwechsel auf einer wiederverwendeten Verbindung und einen Hintergrundauftrag nach Rechteentzug. Vergleichen Sie Ergebnisinhalt, gespeicherte Änderungen, Cachetreffer und erzeugte Dateien. Kontrollieren Sie zusätzlich die ausdrücklich erlaubte Freigabe, damit die Prüfung nicht nur jede Nutzung blockiert.
Eine neue Tabelle oder ein neuer Exportweg muss in diese Zuordnung aufgenommen werden. Leiten Sie die betroffenen Datenklassen nach Möglichkeit aus dem Schema oder einem verbindlichen Inventar ab. Eine handgepflegte Testliste, die denselben neuen Pfad wie der Produktcode vergisst, würde falsche Sicherheit geben.
Einführung und Rücknahme ohne offene Datengrenze
Erproben Sie Änderungen an Mandantentrennung zunächst mit repräsentativen synthetischen Daten und den realen Rollen. Datenmigrationen, RLS und Cachewechsel brauchen einen gesonderten Einführungsplan. Ein Versionswechsel des Cache-Namensraums kann alte mehrdeutige Einträge gezielt aus dem neuen Ablauf ausschließen; die konkrete Löschung und Aufbewahrung bleiben Betriebsentscheidungen.
Wenn die neue Grenze gültige Abläufe blockiert, schließen Sie die betroffene Funktion oder kehren zu einem zuvor geprüften restriktiven Stand zurück. RLS abzuschalten oder Mandantenfilter zu entfernen, ohne eine gleichwertige Grenze sicherzustellen, wäre keine sichere Rücknahme. Der öffentliche API Security Check kann diese Trennung weder in der Datenbank noch in Cache oder Jobs prüfen.
Für die weitere Umsetzung verbinden Rollen und Berechtigungen, Feldrechte und API-Sicherheit selbst prüfen die einzelnen Entscheidungen. Überwachung und Reaktion behandelt Logging und Monitoring.
Quellen und Stand
Quellenstand: 27. September 2026. Die Links stehen zusätzlich bei den jeweils begründeten Aussagen.