Dokumentation

Strikte Mandantentrennung

Wie betool Ihre Daten, Geheimnisse und Ausführungen von anderen Organisationen isoliert.

Strikte Mandantentrennung

Die Isolation zwischen Organisationen ist die grundlegende Invariante von betool. So wird sie Schicht für Schicht durchgesetzt.

Auf Datenbankebene

Jede Geschäftstabelle trägt eine Spalte org_id (UUID), indiziert und durch einen Fremdschlüssel auf organisation(id) eingeschränkt.

Alle serverseitigen Abfragen laufen über Store-Methoden, die systematisch nach der org_id der aktuellen Sitzung filtern. Kein Codepfad legt eine beliebige Abfrage offen; kein Client kann eine andere org_id erzwingen.

Für die wenigen Ressourcen, die organisationsübergreifend geteilt werden können (typischerweise gemeinsam genutzte LLM-Konten auf Plattformebene), ermöglicht eine Spalte is_shared BOOLEAN NOT NULL DEFAULT FALSE ein explizites Opt-in. Regeln:

  • Jeder Lesevorgang ist mit WHERE org_id = %s OR is_shared = TRUE autorisiert.
  • Jede Mutation einer Zeile mit is_shared = TRUE erfordert die Hyperadmin-Rolle (Plattformbetreiber).
  • Jede Mutation invalidiert den Cache global — keine Divergenz pro Organisation.

Auf Dateisystemebene

Jede Organisation hat ihr eigenes Speicher-Stammverzeichnis:

<data_root>/
└── orgs/
    └── <org_id>/
        ├── fixtures/
        ├── uploads/
        ├── knowledge/
        └── exchanges/

Server-Helfer (org_*_dir(org_id)) lösen diese Pfade auf. Kein Geschäftscode kann außerhalb des Stammverzeichnisses einer Organisation schreiben.

Auf Cache-Ebene

Alle Anwendungs-Caches (Auflösung des LLM-Providers, aktuelle Kontexte, geparste Dateien) sind pro Organisation. Wenn eine Ressource mit is_shared = TRUE mutiert wird, wird der Cache global invalidiert — es gibt kein Zeitfenster, in dem eine Organisation einen veralteten Wert sehen könnte.

Auf Geheimnisebene

Zugangsdaten (LLM-Schlüssel, Operator-Auth-Tokens, Webhook-Geheimnisse) werden im Tresor jeder Organisation gespeichert. Sie werden von der API niemals im Klartext zurückgegeben: GET-Routen geben nur has_api_key: bool zurück.

Im Enterprise-Plan kann der Tresor an HashiCorp Vault, AWS Secrets Manager oder Azure Key Vault angebunden werden.

Auf Ausführungsebene

Wenn eine Pipeline läuft:

  • Operatoren haben nur Zugriff auf die externen Konten, die innerhalb ihrer Organisation deklariert sind.
  • LLM-Modelle werden in der Reihenfolge eigenes > geteilt (automatischer Fallback) aufgelöst — immer.
  • Angehängte Dateien sind nur unter dem Stammverzeichnis der aktuellen Organisation lesbar.

Versucht ein Operator, auf eine Ressource außerhalb seines Geltungsbereichs zuzugreifen, ist der Fehler explizit (OrgScopeViolation) — kein stiller Timeout.

Praktische Checkliste

Wann immer eine neue teilbare Ressource hinzugefügt wird, beantwortet das Team diese 4 Fragen:

  1. Wenn eine zweite Backoffice-Organisation auftaucht, verhält sich mein Code dann korrekt?
  2. Wenn ich eine geteilte Zeile mutiere, werden dann alle Caches pro Organisation invalidiert?
  3. Bleiben meine Geheimnisse strikt serverseitig?
  4. Erlaubt mein GET den Auswahlmenüs anderer Organisationen, die Ressource aufzulisten, ohne das Geheimnis offenzulegen?

Wenn eine der Antworten Nein lautet, wird die Ressource nicht ausgeliefert.