Zum Inhalt springen

AA_TENANT

Status: Entwurf · Spec-Kandidat: ja

Zweck

Mandant. Sichtbarkeits- und Datenisolations-Grenze für alle fachlichen Tabellen (DDM_ENTITY_TYPE, DDM_ENTITY, DDM_ENTITY_RELATION, RBAC-Scope, Audit, Outbox). Erfüllt FR-203 als Pflicht-Säule, statt es nachträglich anzubauen.

Strategie V1 vs. V2

  • V1: Genau ein Default-Tenant (key='public'), per Seed-Insert beim Initial-Migrate angelegt. Alle tenant_id-Spalten sind NOT NULL und referenzieren diesen einen Tenant. Service-Layer setzt tenant_id automatisch — fachliche Codebasis muss sich nicht um Tenants kümmern. Code muss aber bereits jetzt tenant_id aus dem Request-Kontext lesen (statt fest public zu codieren), damit V2 keine Codeänderung erfordert.
  • V2: Weitere Tenants werden angelegt. Service-Layer löst Tenant aus Auth-Kontext auf — OIDC-Claim tenant_id als Primärquelle, optionaler X-Tenant-Id-Header für Multi-Tenant-User (Validierung gegen AA_PRINCIPAL_ROLE). Subdomain-Routing ist explizit nicht vorgesehen. Detail siehe Autorisierung.
  • V3 optional: Postgres-RLS pro tenant_id als zusätzliche Verteidigungslinie (siehe Offene Punkte).

Felder

FeldTypPflichtHinweise
iduuidjaPK
keytextjaglobal eindeutig, Format ^[a-z][a-z0-9_]*$
nametextjamenschenlesbarer Name
descriptiontextnein
is_activebooleanjadefault true, deaktivierte Tenants nehmen keine neuen Mutationen mehr an
metadatajsonbjadefault '{}'
created_at / updated_at / created_by / updated_byStandardfelder
deleted_at / deleted_bySoft Delete

Constraints

  • tenant_key_format_chk, tenant_metadata_is_object_chk
  • Unique key

Trigger

  • trg_tenant_set_updated_at

Indizes

  • ix_tenant_key (partial, aktiv)

Verhalten

  • Cross-Tenant ist verboten. DDM_ENTITY_RELATION-Trigger erzwingt, dass tenant_id der Beziehung mit den tenant_ids der Endpunkte übereinstimmt. Kein Customer aus Tenant A darf eine Beziehung zu Service aus Tenant B haben.
  • Hard-Delete eines Tenants ist nicht durch Datenmodell vorgesehen. Stilllegung erfolgt über is_active=false und Soft-Delete der Inhalte.
  • AA_AUDIT_LOG.tenant_id ist nullable, weil tenant-übergreifende Aktionen (Anlage eines neuen Tenants, Plattform-Admin-Operationen) auditiert werden.

Permission-Modell

Mit acl_scope='tenant' lassen sich Rollen und ACL-Einträge auf einen Tenant einschränken (scope_tenant_id). Beispiel: User X ist editor nur in Tenant acme, reader in Tenant globex. Auflösung wie üblich über mdm.v_effective_permission.

Tenant-Onboarding (Default-Provisionierung)

Beim Anlegen eines AA_TENANT ist genau eine Funktion verbindlich auszuführen — in derselben Transaktion wie der INSERT auf AA_TENANT:

mdm.fn_provision_tenant_defaults(tenant_id uuid)

Sie instanziiert pro Tenant das Default-Set (siehe AA_ROLE):

  1. Default-Rollen (administrator, owner, steward, metadata_admin, editor, reader, auditor, exporter) als AA_ROLE-Zeilen mit tenant_id=<neu> und is_system=true.
  2. Default-AA_ROLE_PERMISSION-Zuweisungen je Rolle (Permissions selbst sind global tenant-übergreifend, die Zuweisung trägt scope_tenant_id).
  3. Optional: leerer System-Group-Stub (für IdP-Group-Mapping aus OP-27), falls vom Default-Set vorgesehen.

Die Funktion ist idempotent (ON CONFLICT (tenant_id, key) DO NOTHING) — sie kann bei Default-Set-Updates erneut über alle Tenants ausgeführt werden, um neu hinzugekommene Default-Rollen nachzuziehen, ohne Tenant-Customizings (is_system=false) zu berühren.

V1: Beim Initial-Migrate wird fn_provision_tenant_defaults einmal für den public-Tenant aufgerufen. V2+: jedes Anlegen eines weiteren Tenants ruft die Funktion automatisch.

Verwandte Dokumente