Worum es geht
Die Mandantentrennung ist die wichtigste Sicherheitszusage von CDMS: Ein Kunde sieht nie die Daten eines anderen. Damit das hält, gibt es ein paar Regeln, die überall gelten und für die es keine Ausnahme gibt. Man nennt solche Regeln Invarianten.
Diese Seite sammelt sie an einer Stelle. Jede Regel hat einen Grund. Wer eigenen Code schreibt, einen Hook, einen Job oder eine Erweiterung, darf keine davon umgehen.
Die Merkliste
| Nr. | Regel | Warum |
|---|---|---|
| 1 | Kein Rückfall auf die System-Datenbank. Fehlt der Mandant, fehlt der RequestContext oder lässt sich die Mandanten-Datenbank nicht öffnen, bricht der Zugriff ab. | Sonst landen Mandanten-Daten in der System-Datenbank und sind dort für alle Mandanten erreichbar. |
| 2 | System-Modelle gehen immer in die System-Datenbank, und das wird vor jeder Prüfung des Kontexts entschieden. | Ein fehlender oder manipulierter Kontext kann System-Daten weder umleiten noch blockieren. |
| 3 | Getrennte Typmengen. Die System-Datenbank kennt nur System-Modelle, eine Mandanten-Datenbank nur Mandanten- und Benutzer-Modelle. | Ein falsch geleitetes Objekt scheitert an Hibernate, statt in der falschen Datenbank gespeichert zu werden. Das ist eine zweite, vom Routing unabhängige Sicherung. |
| 4 | Nur drei Stellen setzen einen Mandanten: das Lesen des Tokens, der erlaubte Mandantenwechsel und der Rahmen für Arbeit ohne Anfrage. | Jede weitere Stelle wäre ein Weg, den Mandanten an den Prüfungen vorbei zu ändern. |
| 5 | Der Mandant stammt aus einer signierten Quelle. Header sind nur Wünsche; die Liste der erlaubten Mandanten kommt aus dem Token. | Einen Header kann jeder Client setzen. |
| 6 | Ein Wechsel wird zweimal geprüft: in CIAS und noch einmal in der Persistenz. | Fällt eine Prüfung einem Fehler zum Opfer, hält die andere. |
| 7 | Das Tor fragt nach dem tatsächlich genutzten Mandanten, also nach einem Wechsel noch einmal. | Ein Wechsel darf keinen gesperrten Mandanten zurückholen, auch nicht für Administratoren. |
| 8 | Keine unbestätigte Antwort bei Ausfall. Ist CIAS nicht erreichbar, gilt nur eine schon gemerkte Antwort; ohne sie wird abgelehnt. | Ein Ausfall darf niemanden hereinlassen, der vorher nicht drin war. |
| 9 | Eine Datenbank entsteht nur mit Freigabe, und „nicht erreichbar“ gilt nie als „nicht vorhanden“. | Ein kurzer Ausfall oder ein Tippfehler im Schlüssel darf keine Datenbank anlegen. |
| 10 | Nichts in CDMS löscht eine Datenbank. | Eine verlorene Datenbank lässt sich nicht zurückholen. Eine leere, verwaiste ist das kleinere Übel. |
| 11 | Der Mandantenschlüssel ist fest: nur a-z, 0-9 und -, höchstens 64 Zeichen, nicht system oder single, nie umbenannt. Er wird geprüft, nicht bereinigt. | Er ist Datenbankname und Verzeichnisname. Bereinigen könnte zwei Mandanten auf denselben Namen abbilden. |
| 12 | Die Betriebsart hat keinen Standardwert, und widersprüchliche Angaben halten den Start an. | Ein geratener Wert würde still eine Trennung abschalten oder erfinden. |
| 13 | Der RequestContext wird nach jeder Anfrage gelöscht. | Sonst trägt der nächste Auftrag auf demselben Thread Mandant, Person und Rollen der vorigen Anfrage. |
Verbotene Rückfälle
Diese Abkürzungen gibt es nicht und darf es auch in eigenem Code nicht geben:
| Situation | Was passiert |
|---|---|
| Mandant fehlt | 400 CDMS_TENANT_REQUIRED bzw. vorher 403 tenant-required; nie System-Datenbank |
| RequestContext fehlt | 500 CDMS_PERSISTENCE_CONTEXT_MISSING; nie System-Datenbank |
| Mandant unbekannt oder gesperrt | 403 tenant-not-served; nie automatisch anlegen |
| Wechsel nicht erlaubt | 403 CDMS_TENANT_SWITCH_NOT_AUTHORIZED; nicht still im eigenen Mandanten weiter |
| Mandanten-Datenbank fehlt oder ist nicht erreichbar | 500 bzw. 503; nie System-Datenbank |
| Token nennt mehrere Mandanten ohne Auswahl | 403 tenant-unresolved; nie der erste oder ein Standard-Mandant |
Eine Ausnahme ist gewollt und keine Abkürzung: Fehlt nur die Rolle für einen Wechsel, dessen Ziel erlaubt ist, läuft die Anfrage still im eigenen Mandanten weiter. Das Token hat dann keinen Wechsel verlangt, sondern der Client hat ihn nur gewünscht. Siehe Mandantenwechsel per Header.
Die drei Stellen, die einen Mandanten setzen
- bestimmt den Mandanten aus Organisation oder Attribut
tenant - fragt das Mandanten-Tor
- füllt die Liste der erlaubten Mandanten
tenant- nur mit Realm-Rolle
allowed-tenant-context-switch - nur zu einem Ziel aus der Liste der erlaubten Mandanten
- danach fragt das Tor noch einmal
- Code nennt Mandant und das technische Konto, für das er handelt
- fragt vorher das Mandanten-Tor
- läuft ohne Rollen und nur in diesem einen Mandanten
Wie der dritte Weg aussieht, steht unter Arbeiten für einen Mandanten ohne Anfrage.
Was das für eigenen Code heißt
Wie es weitergeht
- Die Entscheidung Schritt für Schritt: Welche Datenbank? Das Persistenzziel
- Die Prüfung in CIAS: Wird der Mandant bedient?
- Dieselben Regeln für Dateien: Ablage und Mandantentrennung im Speicher