Files
Hosting-Backoffice/decisions/0004-tenancy-model.md
T
2026-05-18 04:37:23 +00:00

4.3 KiB

ADR 0004 — Tenancy-Modell

Status

Accepted

Kurz erklärt

Tenancy bedeutet Mandantenfähigkeit.

Ein Mandant ist z. B. ein Anbieter, eine Agentur oder später ein Reseller, der seine eigenen Kunden, Verträge, Domains und Rechnungen verwaltet.

Das Tenancy-Modell legt fest, wie Daten verschiedener Mandanten technisch voneinander getrennt werden.

Kontext

Hosting-Backoffice soll zunächst einfach nutzbar sein, später aber mandantenfähig und ggf. resellerfähig erweitert werden können.

Die bisherige Planung enthielt die Begriffe tenant_id und organisation_id, ohne deren Verhältnis eindeutig zu definieren.

Das wurde im Architekturreview als kritisches Risiko bewertet, da eine nachträgliche Mandantenfähigkeit sehr teuer und fehleranfällig wäre.

Entscheidung

Hosting-Backoffice verwendet von Beginn an ein mandantenfähiges Datenmodell mit:

  • tenant_id als zentrale Mandantenreferenz
  • Shared Database Modell
  • PostgreSQL als bevorzugte Datenbank
  • Tenant Scope auf Anwendungsebene
  • Row Level Security als spätere zusätzliche Sicherheitsschicht

organisation_id wird vorerst nicht als separates Standardfeld verwendet.

Falls später eine Organisationshierarchie benötigt wird, wird diese über das Tenant-Modell abgebildet.

Gewähltes Modell

Platform
└── Tenant
    └── Kunde
        └── Verträge
        └── Domains
        └── Hostingpakete
        └── Tickets
        └── Dokumente

Später möglich:

Platform
└── Tenant
    └── Reseller-Tenant
        └── Kunden

Dafür kann später ein Feld wie parent_tenant_id in der Tenant-Struktur ergänzt oder vorbereitet werden.

Begründung

Ein Shared-Database-Modell mit tenant_id ist für den Start sinnvoll, weil:

  • V1 klein bleiben soll
  • alle Daten zentral verwaltbar bleiben
  • Migrationen einfacher sind
  • Betrieb und Backups weniger komplex sind
  • spätere Mandantenfähigkeit vorbereitet wird
  • Resellerstrukturen später möglich bleiben

PostgreSQL wird bevorzugt, weil es Row Level Security unterstützt.

Row Level Security bedeutet:

Die Datenbank selbst kann verhindern,
dass Mandant A Datensätze von Mandant B sieht.

Das ist eine zusätzliche Sicherheitsschicht neben der Anwendung.

Konsequenzen

Positiv

  • Mandantenfähigkeit wird nicht später „angeklebt“
  • bessere Grundlage für spätere SaaS-/Resellerfähigkeit
  • klare Datenisolation
  • bessere Sicherheitsarchitektur
  • weniger Refactoring-Risiko

Negativ

  • jede mandantenbezogene Tabelle braucht tenant_id
  • alle Abfragen müssen tenant-aware sein
  • Entwickler müssen von Anfang an sauber mit Tenant-Kontext arbeiten
  • Tests müssen Mandantenisolation prüfen

Technische Leitlinien

Alle mandantenbezogenen Tabellen erhalten:

tenant_id

Beispiele:

customers.tenant_id
contracts.tenant_id
domains.tenant_id
hosting_packages.tenant_id
tickets.tenant_id
documents.tenant_id

Nicht mandantenbezogene Tabellen können global sein, z. B.:

system_settings
module_registry
global_permissions

Anwendungsebene

Laravel soll sicherstellen, dass mandantenbezogene Daten nur im aktuellen Tenant-Kontext geladen werden.

Dafür vorgesehen:

  • Tenant Context
  • Eloquent Global Scopes
  • Policies
  • Tests gegen Tenant-Leaks

Tenant-Leak bedeutet:

Ein Benutzer oder Prozess sieht versehentlich Daten eines anderen Mandanten.

Datenbankebene

PostgreSQL Row Level Security soll als spätere zweite Schutzschicht vorbereitet werden.

V1 kann zunächst mit sauberem Tenant Scope in Laravel starten.

RLS sollte jedoch nicht durch Datenmodellentscheidungen blockiert werden.

Offene Punkte

Noch zu klären:

  • genaue Tenant-Tabelle
  • ob parent_tenant_id sofort angelegt wird
  • ob V1 technisch bereits echtes Multi-Tenant-Login erlaubt
  • wie Plattform-Admins mandantenübergreifend arbeiten dürfen
  • wie Tenant-Offboarding später funktioniert

Nicht entschieden

Diese ADR entscheidet noch nicht:

  • ob Hosting-Backoffice später SaaS oder nur self-hosted wird
  • ob einzelne Mandanten später eigene Datenbanken erhalten können
  • ob Resellerstrukturen bereits in V1 aktiv sichtbar sind

Verwandte ADRs

  • ADR 0005 — Datenbankwahl
  • ADR 0006 — Auth-Strategie
  • ADR 0009 — Core-Grenzen
  • ADR 0011 — GoBD-Verantwortlichkeit