Skip to content

ADR-0053: Rollenkatalog und Systemadmin-Impersonation

  • Status: accepted
  • Datum: 2026-09-03
  • Phase: Multi-Tenant / Auth
  • Bezug: ADR-0051, ADR-0052
  • Ändert: ADR-0051 (kein role=system_admin; Sysadmin mit Org-Kontext = Org-Writer), ADR-0052 (Org-Admin sieht nicht alle Projekte)

Kontext

Rollen und Rechte waren hart verdrahtete Capability-Flags aus role + is_system_admin. Gewünscht sind vier Kernrollen (Systemadmin, Organisationsadmin, Mitarbeiter, Kunde), ein pflegbarer Permission-Katalog, Org-eigene Zusatzrollen und ein Systemadmin, der ohne Impersonation keine Projekte/Schemata/Daten sieht.

Entscheidung

  1. Permission-Katalog in der Control-DB (permissions, app_roles, role_permissions). Scope system vs org.
  2. Builtin-Rollen: system_admin (platform, tenant_id null); pro Tenant org_admin, staff, customer. Org-Admins dürfen Org-Rollen anlegen und Org-Permissions zuweisen.
  3. app_users.role speichert den Role-Code; is_system_admin bleibt synchron für Queries. Fachrollen authority / foreman entfallen (Migration → staff).
  4. Systemadmin ohne Impersonation: nur System-Permissions. X-Tenant-Id allein gewährt keine Org-Data-Rechte.
  5. Impersonation: POST /auth/impersonate / DELETE /auth/impersonate — Systemadmin agiert als Org-Admin einer Orga (Session-Flag).
  6. Projektzugriff: Org-Admin (manage_projects) sieht und verwaltet alle Org-Projekte. Mitarbeiter/Kunden brauchen weiterhin project_members für Datenzugriff.
  7. Bootstrap: Systemadmin (LINETRA_BOOTSTRAP_ADMIN_*) und Org-Admin (LINETRA_BOOTSTRAP_ORG_ADMIN_*) sind getrennte Konten; Bootstrap-Orga heißt standardmäßig Nasarek GIS.

Begründung

Getrennte System-/Org-Ebenen verhindern, dass Plattformoperatoren Fachdaten sehen, und erlauben Org-Admins lokale Rechte ohne Casbin. Impersonation ist der bewusste Übergang in den Org-Kontext.

Folgen

  • Settings → Berechtigungen (System- vs. Org-Sektion).
  • Breaking: Altrollen-Codes und Sysadmin-mit-Tenant-als-Writer.
  • Publish-Flag an Datensätzen fehlt noch; Permissions view_published_records / view_unpublished_records sind Caps für spätere Filter.