41 KiB
Enterprise Architecture Audit — TenantPilot / TenantAtlas
Date: 2026-03-09
Auditor role: Senior Enterprise SaaS Architect, UX/IA Auditor, Security/RBAC Reviewer
Stack: Laravel 12, Filament v5, Livewire v4, PostgreSQL, Tailwind v4
Scope: Panel Architecture, Navigation, Scope Enforcement, RBAC, Routing, IA
1. Executive Assessment
Gesamturteil: Teilweise enterprise-tauglich — strukturell problematisch in Scope-Modell und Panelarchitektur
Die Anwendung hat ein starkes RBAC-Fundament (Capability-first, role-to-capability maps, resolver services, policies) und ein funktionierendes Multi-Tenant-Modell. Die Kernfunktionen (Inventory, Backups, Governance, Monitoring) sind fachlich sinnvoll aufgebaut.
Jedoch: Die Panel-Architektur, Navigation und Scope-Trennung weisen strukturelle Defizite auf, die in einem Enterprise-Kontext zu Verwirrung, Scope-Leaks und Sicherheitslücken führen können.
Die 5 schwersten strukturellen Probleme
| # | Problem | Severity |
|---|---|---|
| S1 | Kein Workspace-Home/Overview-Einstieg. /admin redirected sofort zu /admin/t/{uuid} (Tenant-Dashboard). Es gibt keinen eigenständigen Workspace-Kontext mit eigener Landing, eigenem Dashboard, eigener Sidebar. Der Workspace ist nur eine Session-Variable, kein eigenständiger UI-Kontext. |
P0 |
| S2 | Cross-Scope-Navigation im Tenant-Panel. Die Monitoring-Gruppe (Runs → /admin/operations, Alerts → /admin/alerts, Audit Log → /admin/audit-log) verlinkt im Tenant-Panel auf Admin-Panel-Routen. User verlassen den Tenant-Kontext ohne expliziten Hinweis. Dashboard-KPIs verlinken ebenfalls nach /admin/operations. |
P0 |
| S3 | Doppelte Resource-Discovery und panelübergreifende Registrierung. Beide Panels (Admin + Tenant) rufen discoverResources(in: app_path('Filament/Resources')) auf. Die Admin-Panel-Provider registriert zusätzlich explizit Ressourcen wie PolicyResource, InventoryItemResource — die tenant-scoped sind und im Admin-Panel nichts zu suchen haben. AlertsCluster steuert Registrierung über shouldRegisterNavigation() nur per Panel-ID-Check, nicht per Scope-Check. |
P1 |
| S4 | Fehlende canAccess()-Guards auf kritischen Seiten. AuditLog, Operations und andere Seiten haben keine canAccess()-Methode. Sie sind über URL direkt erreichbar, auch wenn shouldRegisterNavigation = false die Navigation versteckt. Navigation ist nicht die Sicherheitsgrenze — aber hier wird es so behandelt. |
P1 |
| S5 | Middleware kompensiert fehlende Panelarchitektur. EnsureFilamentTenantSelected (270+ LOC) baut dynamisch Navigation, löst Scope auf, und erstellt eine "Workspace-Level"-Navigation inline per NavigationBuilder. Das ist Sonderlogik, die eine fehlende saubere Workspace-Panel-Architektur kompensiert. |
P1 |
Die 5 wichtigsten Korrekturen
| # | Korrektur | Priorität | Aufwand |
|---|---|---|---|
| K1 | Workspace-Panel als eigenständiges Panel mit eigenem Home/Dashboard einführen | P0 | Groß |
| K2 | Cross-Scope-Links im Tenant-Panel eliminieren oder als Scope-Wechsel kenntlich machen | P0 | Mittel |
| K3 | Resource-Discovery per Panel isolieren (Tenant-Resources nur im Tenant-Panel, Workspace-Resources nur im Workspace-Panel) | P1 | Mittel |
| K4 | canAccess() auf allen Seiten implementieren (Zero-Trust-Regel) |
P1 | Klein |
| K5 | EnsureFilamentTenantSelected-Middleware refactoren: Navigation-Build-Logik in Panel-Konfiguration verlagern |
P1 | Mittel |
2. Current State Map
2.1 Panel Architecture (3 Panels)
┌──────────────────────────────────────────────────────────┐
│ System Panel (path: /system) │
│ Guard: platform | Auth: PlatformCapabilities │
│ Home: System Dashboard (Control Tower) │
│ Scope: Platform-wide operations, break-glass, directory │
│ Isolation: ✅ Separate session cookie, separate guard │
└──────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Admin Panel (path: /admin) — DEFAULT PANEL │
│ Guard: web | Tenancy: NONE │
│ Home: Redirect to Tenant Dashboard or ChooseWorkspace │
│ Scope: Hybrid (workspace + monitoring + settings + some │
│ tenant resources registered here too) │
│ Resources: 10 explicit + auto-discovered = ~17 total │
│ Problem: No stable workspace-level home or sidebar │
└──────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Tenant Panel (path: /admin/t) │
│ Guard: web | Tenancy: Tenant::class (slugAttribute: │
│ external_id) │
│ Home: TenantDashboard │
│ Scope: Tenant-scoped operations (inventory, backups, │
│ compliance, drift, restore, review packs) │
│ Problem: Monitoring nav links to /admin/* routes │
│ Discovery: discoverResources + discoverPages + widgets │
└──────────────────────────────────────────────────────────┘
2.2 Navigation Map
Tenant Panel Sidebar (current state in browser)
Dashboard → /admin/t/{uuid} ✅ Tenant-scoped
─────────────────
Inventory
Items → /admin/t/{uuid}/inventory ✅ Tenant-scoped
Policies → /admin/t/{uuid}/policies ✅ Tenant-scoped
Policy Versions → /admin/t/{uuid}/policy-versions ✅
─────────────────
Backups & Restore
Backup Schedules → /admin/t/{uuid}/backup-schedules ✅
Backup Sets → /admin/t/{uuid}/backup-sets ✅
Restore Runs → /admin/t/{uuid}/restore-runs ✅
─────────────────
Directory
Groups → /admin/t/{uuid}/entra-groups ✅
─────────────────
Governance
Findings → /admin/t/{uuid}/findings ✅
Baseline Compare → /admin/t/{uuid}/baseline-compare-landing ✅
─────────────────
Monitoring ⚠️ CROSS-SCOPE GROUP
Runs → /admin/operations ❌ Admin-Panel-Route!
Alerts → /admin/alerts ❌ Admin-Panel-Route!
Audit Log → /admin/audit-log ❌ Admin-Panel-Route!
─────────────────
Reporting
Review Packs → /admin/t/{uuid}/review-packs ✅
Admin Panel Navigation (when no tenant selected — built by middleware)
Settings
Manage workspaces → /admin/workspaces
Monitoring
Operations → /admin/operations
Alert targets → /admin/alert-destinations
Alert rules → /admin/alert-rules
Alert deliveries → /admin/alert-deliveries
Alerts → /admin/alerts
Audit Log → /admin/audit-log
Admin Panel Navigation (when tenant IS selected — full navigation includes both)
(Full tenant resources + workspace resources mixed together)
Settings
Manage workspaces → /admin/workspaces
Integrations → /admin/provider-connections
Settings → /admin/settings/workspace
(+ TenantResource, etc.)
Monitoring
Operations → /admin/operations
Audit Log → /admin/audit-log
Tenant-scoped resources (Policies, Inventory, etc.) also visible
2.3 Scope-Wechsel und Rückwege
Login → EnsureWorkspaceSelected middleware:
├─ 1 Workspace → auto-select → WorkspaceRedirectResolver:
│ ├─ 0 Tenants → ManagedTenantsLanding (/admin/w/{ws}/managed-tenants)
│ ├─ 1 Tenant → TenantDashboard (/admin/t/{uuid})
│ └─ N Tenants → ChooseTenant (/admin/choose-tenant)
└─ N Workspaces → ChooseWorkspace (/admin/choose-workspace)
Workspace wechseln:
Context-Bar → Workspace dropdown → "Switch workspace" → ChooseWorkspace?choose=1
✅ Expliziter Wechsel
Tenant wechseln:
Context-Bar → Tenant dropdown → Select tenant (POST)
Context-Bar → "Clear tenant context"
Filament tenant menu (in Tenant Panel) → Searchable tenant menu
✅ Expliziter Wechsel
Rückweg Tenant → Workspace:
❌ Kein direkter "Back to Workspace" Button
⚠️ Nur indirekt: Context-Bar → Switch workspace
⚠️ Oder: Monitoring-Links → navigieren implizit zum Admin-Panel
⚠️ Brand-Logo auf Tenant-Panel führt zum Tenant-Dashboard, nicht zum Workspace-Home
3. Findings Table
| ID | Kategorie | Severity | Ort / Screen | Datei / Klasse / Route | Symptom | Technische Ursache | Risiko | Empfohlene Korrektur |
|---|---|---|---|---|---|---|---|---|
| F01 | Scope-Modell | Critical | /admin (Home) |
routes/web.php L43-66, WorkspaceRedirectResolver |
/admin hat keine eigene Seite, redirected immer auf Tenant-Dashboard oder ChooseWorkspace |
Admin-Panel hat kein Dashboard/Home. Route-Handler ist ein Redirect-Closure. | Kein Workspace-Level-Einstieg. Admin-Nutzer sehen nie einen Workspace-Überblick. | Workspace-Home-Page mit KPIs (Tenants, Operations, Health) einführen |
| F02 | IA/Navigation | Critical | Tenant-Panel Sidebar → Monitoring | TenantPanelProvider L51-63 |
"Runs", "Alerts", "Audit Log" verlinken auf /admin/operations, /admin/alerts, /admin/audit-log |
NavigationItem::make() im TenantPanelProvider nutzt Admin-Panel-Routen + hardcoded URLs |
Stiller Scope-Wechsel. User verlässt Tenant-Kontext ohne Warnung. URL ändert sich von /admin/t/{uuid}/... zu /admin/.... |
Monitoring-Links entweder tenant-scoped machen oder als Cross-Scope-Links kennzeichnen + auf Workspace-Panel verlagern |
| F03 | Scope-Modell | Critical | Tenant Dashboard KPIs | Dashboard Widgets | "Active operations" + "Inventory active" verlinken auf /admin/operations (Admin-Panel) |
Dashboard-Widget-Links nutzen Admin-Routen | Scope-Falle: User klickt im Tenant-Dashboard und landet auf workspace-weiter Operations-Seite ohne Kontext | KPI-Links auf tenant-gefilterte Views lenken |
| F04 | Security | High | /admin/audit-log |
AuditLog.php |
Seite hat kein canAccess(), nur shouldRegisterNavigation = false |
Kein Authorization-Guard auf Page-Ebene | Jeder authentifizierte User kann Audit-Log über URL aufrufen — Verletzung des Least-Privilege-Prinzips | canAccess() mit AUDIT_VIEW Capability implementieren |
| F05 | Security | High | /admin/operations |
Operations.php |
Seite hat kein canAccess(), nur isDiscovered = false |
Kein Authorization-Guard auf Page-Ebene | Jeder authentifizierte Workspace-Member kann Operations-Seite aufrufen | canAccess() implementieren (Workspace-Membership reicht als Minimum) |
| F06 | Registrierung | High | Admin + Tenant Panel | AdminPanelProvider L143-154, TenantPanelProvider L46-48 |
Beide Panels entdecken Resources aus demselben Verzeichnis (app/Filament/Resources) |
discoverResources(in: app_path('Filament/Resources')) in beiden Panels |
Tenant-scoped Resources (Policy, Inventory, BackupSchedule, etc.) erscheinen potenziell in beiden Panels. $isScopedToTenant verhindert teilweise Daten-Leaks, aber Navigation ist dennoch inkonsistent |
Resource-Discovery per Panel isolieren: Tenant-Resources in app/Filament/Tenant/Resources, Workspace-Resources in app/Filament/Admin/Resources |
| F07 | IA | High | Admin Panel Settings-Gruppe | AdminPanelProvider L59-110 |
Settings-Gruppe enthält: "Manage workspaces" + "Integrations" + "Settings" — wirkt wie der primäre Navigationsbereich, obwohl es sekundär sein sollte | NavigationItem-Registrierung im PanelProvider mit statischer Sortierung | Settings/Admin sind prominent, operative Bereiche (nur Monitoring) wirken nachrangig | Settings ans Ende der Navigation verschieben, operative Bereiche nach oben |
| F08 | Scope-Modell | High | Workspace-Level-Navigation | EnsureFilamentTenantSelected L172-258 |
Wenn kein Tenant gewählt ist, wird eine "Workspace-Level"-Navigation per NavigationBuilder inline in der Middleware gebaut |
Middleware kompensiert fehlendes Workspace-Panel | Fragile Sonderlogik, schwer wartbar, Navigation-Änderungen erfordern Middleware-Änderung statt Panel-Konfiguration | Workspace-Panel als eigenständiges Panel konfigurieren |
| F09 | IA/UX | Medium | Brand-Logo (beide Panels) | AdminPanelProvider L56 + TenantPanelProvider L29 |
Brand-Logo auf Tenant-Panel führt zum aktuellen Tenant-Dashboard (/admin/t/{uuid}). Im Admin-Panel führt es zu /admin (→ Redirect auf Tenant-Dashboard). Es gibt keinen Weg per Logo zum Workspace-Home. |
Filament-Default: brandLogo verlinkt auf Panel-Home. Admin-Panel hat kein Home → Redirect. |
Nutzer können nie per Logo "nach oben" zum Workspace navigieren | Brand-Logo im Workspace-Panel auf Workspace-Home, im Tenant-Panel auf Tenant-Dashboard verlinken. Cross-Level-Navigation über Context-Bar. |
| F10 | Routing | Medium | /admin/operations/{run} |
routes/web.php L149-163 |
Operations-Detail-Seite ist workspace-scoped, aber über Admin-Panel geroutet mit eigener Middleware-Kette | Custom Route statt Filament-Resource-Page | Deep-Links zu Operations-Runs (z.B. aus Notifications) funktionieren, aber verlassen den Tenant-Kontext | OK als Workspace-Level-Seite, aber muss klar als solche erkennbar sein |
| F11 | RBAC | Medium | AlertsCluster |
AlertsCluster.php |
shouldRegisterNavigation() prüft nur Panel-ID (=== 'admin'), nicht Capabilities |
Visibility-Check basiert auf Panel-Name, nicht auf Authorization | Cluster erscheint für alle Admin-Panel-Nutzer, egal ob sie ALERTS_VIEW haben |
shouldRegisterNavigation() soll zusätzlich ALERTS_VIEW Capability prüfen |
| F12 | Routing | Medium | url(fn (): string => url('/admin/alerts')) |
TenantPanelProvider L55 |
Hardcoded URL statt Named Route | url() statt route() |
Brüchig bei URL-Änderungen, kein Laravel-Standard | Named Route verwenden |
| F13 | IA | Medium | Tenant Panel Sidebar | TenantPanelProvider + Resource discovery | "Directory > Groups" ist einziger Eintrag unter "Directory" | Natürliches Wachstumslimit | Einelementige Navigationsgruppe wirkt unformful | Entweder "Directory" wachsen lassen oder "Groups" in eine bestehende Gruppe integrieren |
| F14 | Registration | Low | InventoryCluster |
InventoryCluster.php |
Kein shouldRegisterNavigation() Override — erscheint potenziell in beiden Panels |
Fehlende Panel-Gate-Logik im Cluster | Cluster könnte in falschen Panels sichtbar werden | shouldRegisterNavigation() mit Panel-ID-Check hinzufügen (wie AlertsCluster) |
| F15 | UX | Low | Context-Bar | context-bar.blade.php |
Workspace-Dropdown hat nur eine Option: "Switch workspace". Kein Shortcut zu Workspace-Overview/Dashboard. | Dropdown-Inhalt minimal | Nutzer müssen den Workspace erst wechseln und dann navigieren statt direkt zum Workspace-Home zu gelangen | "Workspace overview" Link im Dropdown ergänzen |
4. Structural Mismatches
4.1 UI-Modell vs Code-Modell
| Aspekt | UI suggeriert | Code implementiert | Mismatch |
|---|---|---|---|
| Monitoring (Runs/Alerts/AuditLog) | Tenant-scoped Monitoring (erscheint in Tenant-Sidebar) | Workspace-scoped Seiten auf Admin-Panel-Routen | Kritisch: Scope-Illusion |
| Dashboard KPIs | Tenant-spezifische Metriken | "Active operations" und "Inventory active" verlinken auf workspace-weite /admin/operations |
Scope-Mismatch |
| "Settings" Navigationsgruppe | Nebenbereich für Konfiguration | Enthält Workspace-Management + Integrations (=Kernfunktionalität für Admins) | IA-Inversion |
| Brand-Logo | "Navigiere zum Home" | Tenant-Panel: OK (→ Tenant-Dashboard). Admin-Panel: Redirect-Loop zu Tenant. | Fehlender Workspace-Home |
4.2 Scope-Modell vs Routing
| Aspekt | Scope-Modell sagt | Routing implementiert | Mismatch |
|---|---|---|---|
| Workspace-Ebene | Eigener Kontext mit eigenem Home | Kein eigenes Home, kein eigenes Dashboard, nur Redirect | Kritisch |
| Monitoring-Seiten | Workspace-scoped | Routen unter /admin/* mit panel:admin Middleware, obwohl Admin-Panel kein Tenancy hat |
Middleware-Sonderlogik statt Panel-Architektur |
Operations-View (/admin/operations/{run}) |
Workspace-scoped Detail | Custom Route mit eigener Middleware-Kette, nicht als Filament Page/Resource registriert | Parallel-Routing neben Filament |
4.3 Navigation vs RBAC
| Aspekt | Navigation zeigt | RBAC prüft | Mismatch |
|---|---|---|---|
| Audit Log | In Sidebar sichtbar (via NavigationItem in Middleware) | Kein canAccess() auf der Page |
Visible-and-accessible-without-authorization |
| Operations | In Sidebar sichtbar (via NavigationItem) | Kein canAccess() auf der Page |
Hidden-from-nav-but-accessible-by-url |
| AlertsCluster | Prüft Panel-ID, nicht Capability | AlertRulePolicy prüft ALERTS_VIEW | Visibility ≠ Authorization |
| Operations im Tenant-Panel | Kein Visibility-Check | OperationRunPolicy prüft Membership | Immer sichtbar, auch für Readonly-User |
4.4 Filament-Defaults vs Produktmodell
| Filament-Default | Produktmodell erfordert | Aktueller Zustand |
|---|---|---|
discoverResources() ohne Panel-Scoping |
Resources per Panel isoliert | Beide Panels discovern dieselben Resources |
| Default Panel Home = Dashboard | Workspace-Home ≠ Tenant-Dashboard | Admin-Panel hat kein Home → Redirect auf Tenant-Panel |
Panel brandLogo verlinkt auf Panel-Home |
Brand-Logo → kontextbezogenes Home | Admin-Panel Home redirected sofort weg |
| NavigationItem-Sichtbarkeit = Filament Discovery | RBAC-gesteuerte Sichtbarkeit | Middleware baut Navigation dynamisch |
| Cluster shouldRegisterNavigation = true | Per-Panel und per-Capability | Nur Panel-ID Check in AlertsCluster |
4.5 Middleware als Architektur-Kompensation
| Middleware | Kompensiert | Eigentlich nötig |
|---|---|---|
EnsureFilamentTenantSelected (270+ LOC) |
Fehlende Workspace-Panel-Architektur + fehlende Navigation-Trennung | Eigenständiges Workspace-Panel mit eigener Navigation |
EnsureWorkspaceSelected (180+ LOC) |
Fehlender Workspace-Home-Einstieg | Workspace-Home als Default-Landing |
isWorkspaceOptionalPath() mit Regex |
Fehlende saubere Route-Trennung | Workspace-Panel-Routen, die per Middleware-Kette klar sind |
configureNavigationForRequest() |
Fehlende stabile Workspace-Navigation | Workspace-Panel mit eigener Navigation-Konfiguration |
5. Target Enterprise Architecture
5.1 Drei-Panel-Modell (Zielzustand)
┌═══════════════════════════════════════════════════════════┐
║ SYSTEM PANEL (path: /system) ║
║ Guard: platform | Session: Separate ║
║ Purpose: Break-glass, platform ops, directory, access ║
║ Home: System Dashboard (Control Tower) ║
║ Audience: Platform operators ║
║ Status: ✅ Gut isoliert, gut geschützt ║
╚═══════════════════════════════════════════════════════════╝
┌═══════════════════════════════════════════════════════════┐
║ WORKSPACE PANEL (path: /admin) — DEFAULT PANEL ║
║ Guard: web | Tenancy: NONE ║
║ Purpose: Workspace-level administration, cross-tenant ║
║ monitoring, alerts, integrations, onboarding, settings ║
║ Home: WorkspaceDashboard (Tenant-Health, Operations KPIs,║
║ Recent Activity, Alerts Summary) ║
║ Brand-Logo → /admin (Workspace-Home) ║
╠───────────────────────────────────────────────────────────╣
║ NAVIGATION GROUPS: ║
║ ║
║ [Dashboard] Workspace-Home ║
║ ║
║ [Tenants] Tenant-Übersicht ║
║ (Onboarding, Tenant-Status, ║
║ → deep link to Tenant-Panel) ║
║ ║
║ [Monitoring] Operations ║
║ Alerts (Overview, Rules, Targets, ║
║ Deliveries) ║
║ Audit Log ║
║ ║
║ [Governance] Baseline Profiles ║
║ Baseline Snapshots ║
║ ║
║ [Settings] Workspace Settings ║
║ Integrations ║
║ Members ║
║ Manage Workspaces ║
╚═══════════════════════════════════════════════════════════╝
┌═══════════════════════════════════════════════════════════┐
║ TENANT PANEL (path: /admin/t) ║
║ Guard: web | Tenancy: Tenant::class ║
║ Purpose: Tenant-specific operations ║
║ Home: TenantDashboard ║
║ Brand-Logo → /admin/t/{uuid} (Tenant-Dashboard) ║
╠───────────────────────────────────────────────────────────╣
║ NAVIGATION GROUPS: ║
║ ║
║ [Dashboard] Tenant-Dashboard ║
║ ║
║ [Inventory] Items / Coverage ║
║ Policies ║
║ Policy Versions ║
║ ║
║ [Backups & Restore] Backup Schedules ║
║ Backup Sets ║
║ Restore Runs ║
║ ║
║ [Governance] Findings ║
║ Baseline Compare ║
║ ║
║ [Directory] Groups ║
║ ║
║ [Reporting] Review Packs ║
║ ║
║ ──────────────────────────────── ║
║ ⬆ Back to Workspace (Cross-Scope-Link, deutlich ║
║ gekennzeichnet → /admin) ║
╚═══════════════════════════════════════════════════════════╝
5.2 Workspace-Home/Dashboard — Empfehlung
Das Workspace-Dashboard soll zeigen:
- Tenant-Health-Overview: Anzahl aktive Tenants, Status (OK/Warning/Critical), letzte Sync-Zeiten
- Operations-KPIs: Active/Queued/Failed operations (workspace-weit)
- Alert-Summary: Aktive Alerts, undelivered, rules count
- Recent Activity: Letzte 5 Audit-Log-Einträge (workspace-scoped)
- Needs Attention: Failed operations, unacknowledged findings, overdue SLAs
- Quick Actions: "Onboard tenant", "View operations", "Open tenant" (per Tenant-Link)
5.3 Brand-Logo-Verhalten
| Panel | Logo-Target | Begründung |
|---|---|---|
| System | /system |
Bleibt im System-Kontext |
| Workspace | /admin |
Workspace-Home (neues Dashboard) |
| Tenant | /admin/t/{uuid} |
Tenant-Dashboard (aktuell korrekt) |
5.4 Cross-Scope-Navigation
| Richtung | Mechanismus | UI-Hinweis |
|---|---|---|
| Workspace → Tenant | Tenant-Liste im Workspace-Dashboard oder Sidebar → "Open in Tenant Panel" | Deutliches Icon (z.B. external-link) + Farb/Style-Unterscheidung |
| Tenant → Workspace | Expliziter "Back to Workspace" Link in Tenant-Sidebar (unten) + Context-Bar | Pfeil-Icon + Label "⬆ Workspace" |
| Workspace → System | Nur für Platform-Admins über User-Menü oder separate URL | Nicht in normaler Navigation |
| Tenant → Tenant | Filament Tenant-Menü (searchable, bereits vorhanden) | ✅ Bereits gut gelöst |
5.5 Kanonische Routen
| Route | Scope | Zweck |
|---|---|---|
/admin |
Workspace | Workspace-Home/Dashboard |
/admin/tenants |
Workspace | Tenant-Übersicht (aktuell TenantResource) |
/admin/operations |
Workspace | Operations-Monitoring |
/admin/alerts |
Workspace | Alert-Overview |
/admin/audit-log |
Workspace | Audit-Log |
/admin/settings/workspace |
Workspace | Workspace-Settings |
/admin/workspaces |
Workspace | Workspace-Management (cross-workspace) |
/admin/choose-workspace |
Tenantless | Workspace-Selektor |
/admin/choose-tenant |
Workspace | Tenant-Selektor |
/admin/t/{uuid} |
Tenant | Tenant-Dashboard |
/admin/t/{uuid}/inventory |
Tenant | Inventar |
/admin/t/{uuid}/policies |
Tenant | Policies |
/admin/t/{uuid}/findings |
Tenant | Findings |
/admin/t/{uuid}/backup-sets |
Tenant | Backup Sets |
/system |
Platform | System Control Tower |
6. Navigation & Scope Principles
Verbindliche Architekturregeln
-
Workspace ist primärer Kontext. Jeder authentifizierte User befindet sich immer in genau einem Workspace. Der Workspace wird über Session persistiert und in der Context-Bar angezeigt.
-
Tenant ist operativer Kontext. Tenant-scoped Seiten erfordern einen aktiven Tenant. Der Tenant-Kontext ist optional auf Workspace-Ebene und verpflichtend auf Tenant-Ebene.
-
Jede Ebene hat genau einen klaren Home-Einstieg. System → System Dashboard. Workspace → Workspace Dashboard. Tenant → Tenant Dashboard.
-
Tenant-scoped Navigation erscheint NIE im Workspace-Panel. Resources wie Policy, InventoryItem, BackupSchedule, Finding, ReviewPack gehören ausschließlich ins Tenant-Panel.
-
Workspace-scoped Navigation erscheint NIE im Tenant-Panel. Operations, Alerts, Audit Log, Workspace Settings, Workspace Management gehören ausschließlich ins Workspace-Panel.
-
Settings/Admin sind immer untergeordnet zum Kernworkflow. Settings-Navigationsgruppe steht am Ende der Sidebar, nie am Anfang.
-
Brand-Logo führt zum kanonischen Home der aktuellen Ebene. Workspace-Panel →
/admin. Tenant-Panel →/admin/t/{uuid}. -
Switch workspace und Manage workspaces sind getrennte Konzepte. "Switch workspace" wechselt den Kontext (via ChooseWorkspace). "Manage workspaces" ist eine Admin-Funktion (CRUD).
-
Navigation ist NIE die Sicherheitsgrenze. Jede Seite muss
canAccess()implementieren, unabhängig vonshouldRegisterNavigation.shouldRegisterNavigation = falseist eine UX-Entscheidung, keine Security-Maßnahme. -
Cross-Scope-Wechsel sind explizit. Links, die den Scope wechseln (z.B. Tenant → Workspace), müssen visuell als solche erkennbar sein (Icon, Label, Farbe).
-
Middleware erzeugt keine fachliche Navigation. Die Navigation wird in der Panel-Konfiguration definiert, nicht dynamisch in Middleware gebaut.
-
Resource-Discovery ist per Panel isoliert. Jedes Panel discover Resources nur aus seinem eigenen Verzeichnis. Kein
discoverResources()über Panel-Grenzen hinweg. -
Alle Filament-Defaults müssen explizit bestätigt oder überschrieben werden. Default-Home, Default-Discovery, Default-Logo-Verhalten dürfen nicht stillschweigend das Produktmodell dominieren.
-
URL-Semantik spiegelt Scope-Hierarchy wider.
/admin/...= Workspace-Level./admin/t/{uuid}/...= Tenant-Level./system/...= Platform-Level. -
Polling und Heavy Assets werden capability-gated und interval-kontrolliert. Workspace-Widgets die workspace-weite Queries machen, dürfen nicht unkontrolliert pollen.
7. Recommendations
7.1 Quick Wins (sofort umsetzbar, geringes Risiko)
| # | Empfehlung | Nutzen | Risiko | Aufwand | Abhängigkeiten |
|---|---|---|---|---|---|
| QW1 | canAccess() auf AuditLog.php und Operations.php implementieren |
Security-Lücke schließen | Keins | 30min | Keine |
| QW2 | shouldRegisterNavigation() in InventoryCluster auf Panel-ID + Capability gaten |
Verhindert Cross-Panel-Sichtbarkeit | Keins | 15min | Keine |
| QW3 | Hardcoded URL url('/admin/alerts') durch Named Route ersetzen |
Routing-Stabilität | Keins | 5min | Keine |
| QW4 | Workspace-Overview-Link in Context-Bar-Dropdown ergänzen | Orientierung verbessern | Keins | 30min | Keine |
| QW5 | Dashboard KPI-Links (Active operations, Inventory active) tenant-filtern | Scope-Konsistenz | Keins | 1h | Keine |
Aktion: Sofort implementieren.
7.2 Mittlere Refactors
| # | Empfehlung | Nutzen | Risiko | Aufwand | Abhängigkeiten |
|---|---|---|---|---|---|
| MR1 | Monitoring-NavigationItems aus TenantPanelProvider entfernen | Eliminiert Cross-Scope-Navigation | Mittel (ändert Tenant-Panel UX) | 2h | Workspace-Panel muss Monitoring übernehmen |
| MR2 | "Back to Workspace"-Link in Tenant-Panel-Sidebar einführen | Bidirektionale Navigation | Gering | 1h | Workspace-Panel muss existieren mit Home |
| MR3 | Resource-Discovery per Panel isolieren (Verzeichnistrennung) | Eliminiert Cross-Panel-Registrierung | Mittel (Dateiumzug) | 4h | Tests müssen angepasst werden |
| MR4 | EnsureFilamentTenantSelected::configureNavigationForRequest() in Panel-Konfiguration verlagern |
Architectural Debt tilgen | Mittel | 4h | Workspace-Panel existiert |
| MR5 | AlertsCluster shouldRegisterNavigation() um Capability-Check erweitern |
RBAC-Konsistenz | Gering | 30min | Keine |
Aktion: Als Spec schreiben, nach Quick Wins umsetzen.
7.3 Größere Strukturänderungen
| # | Empfehlung | Nutzen | Risiko | Aufwand | Abhängigkeiten |
|---|---|---|---|---|---|
| GA1 | Workspace-Home/Dashboard als eigenständige Page im Admin-Panel einführen | Löst F01, F09, ermöglicht eigenständigen Workspace-Kontext | Mittel (Redirect-Logik muss angepasst werden) | 8-16h | Widget-Entwicklung, UX-Design |
| GA2 | Monitoring-Navigation komplett in Workspace-Panel verlagern | Löst F02, F03, eliminiert Cross-Scope-Links | Hoch (ändert gesamte Monitoring-UX) | 16-24h | GA1, MR1 |
| GA3 | Resource-Verzeichnisstruktur nach Panel aufteilen (Filament/Admin/Resources, Filament/Tenant/Resources) |
Löst F06, verhindert künftige Cross-Panel-Registrierung | Mittel (viele Dateien bewegen) | 4-8h | Tests anpassen |
| GA4 | EnsureFilamentTenantSelected Middleware refactoren: Pure scope-validation, keine Navigation-Logik |
Löst F08, S5, reduziert Middleware-Komplexität | Mittel | 8-16h | GA1, GA2 |
Aktion: In Constitution/Product-Principles verankern, als Specs planen.
8. Spec Backlog Proposal
Spec 120: Workspace Home & Dashboard
Titel: Workspace-Level Dashboard als eigenständiger Einstieg
Ziel: Einen stabilen, informativen Workspace-Home-Einstieg schaffen, der Nutzern cross-tenant Überblick, Operations-Status und Quick Actions bietet.
Problem: /admin hat kein Dashboard/Home, redirected sofort auf Tenant-Dashboard. Kein Workspace-Level-Überblick existiert. Die Brand-Logo-Navigation ist sinnlos.
Scope: WorkspaceDashboard Page, Widgets (Tenant Health, Operations KPIs, Alerts Summary, Recent Activity, Needs Attention), Redirect-Logik anpassen, Brand-Logo-Target korrigieren.
Non-goals: Keine Änderung der Tenant-Panel-Navigation. Kein neues Panel.
Priorität: P0
Risiken: Widget-Queries müssen workspace-scoped und performant sein.
Abhängigkeiten: Keine.
Reihenfolge: 1 (Enabler für alle weiteren Specs)
Spec 121: Monitoring Scope Separation & Cross-Scope Navigation Cleanup
Titel: Monitoring-Navigation aus Tenant-Panel entfernen, Workspace-Monitoring stärken
Ziel: Monitoring (Operations, Alerts, Audit Log) gehört eindeutig zum Workspace-Panel. Im Tenant-Panel sollen keine Cross-Scope-Links zu Admin-Routen existieren.
Problem: Monitoring-Gruppe im Tenant-Panel verlinkt auf /admin/*-Routen. User verlassen den Tenant-Kontext ohne Warnung. Dashboard-KPIs verlinken ebenfalls cross-scope.
Scope: NavigationItems aus TenantPanelProvider entfernen. Monitoring-Navigation im Admin-Panel stärken. Dashboard-KPIs auf tenant-scoped Views lenken. "Back to Workspace"-Link in Tenant-Panel einführen.
Non-goals: Kein tenant-scoped Monitoring (das kommt ggf. später).
Priorität: P0
Risiken: Nutzer verlieren temporär Monitoring-Zugang im Tenant-Panel. Mitigation: "Back to Workspace → Monitoring" als expliziter Weg.
Abhängigkeiten: Spec 120 (Workspace-Home existiert als Rückweg-Ziel).
Reihenfolge: 2
Spec 122: Resource Discovery Panel Isolation
Titel: Filament Resource-Discovery per Panel isolieren
Ziel: Jedes Panel entdeckt nur Resources, die zu seinem Scope gehören. Keine Cross-Panel-Registrierung.
Problem: Beide Panels rufen discoverResources(in: app_path('Filament/Resources')) auf. Tenant-scoped Resources erscheinen im Admin-Panel. AdminPanelProvider registriert explizit tenant-scoped Resources (Policy, Inventory).
Scope: Verzeichnisstruktur umbauen: app/Filament/Admin/Resources/ + app/Filament/Tenant/Resources/. Discovery-Paths in Providern anpassen. Tests aktualisieren.
Non-goals: Keine Funktionsänderung an Resources selbst. Kein neues Panel.
Priorität: P1
Risiken: Viele Dateien bewegen → Import-Pfade und Namespaces anpassen. Tests müssen grün bleiben.
Abhängigkeiten: Keine (kann parallel zu 120/121 laufen).
Reihenfolge: 3 (parallel möglich)
Spec 123: Page-Level Authorization Zero-Trust Enforcement
Titel: canAccess() auf allen Filament-Pages als Pflicht-Guard
Ziel: Jede Filament-Page muss eine canAccess()-Methode haben, die authorization durchführt. shouldRegisterNavigation = false ist keine Security-Maßnahme.
Problem: AuditLog, Operations und weitere Pages haben kein canAccess(). Sie sind über URL direkt erreichbar.
Scope: Alle Pages auditieren. Fehlende canAccess() ergänzen. Archunit-ähnliche Regel als Test (jede Page-Klasse muss canAccess() definieren).
Non-goals: Keine Policy-Änderungen. Keine neuen Capabilities.
Priorität: P1
Risiken: Gering. Falsche canAccess()-Logik könnte Zugang sperren → Tests.
Abhängigkeiten: Keine.
Reihenfolge: 2 (parallel zu Spec 121)
Spec 124: Middleware Navigation Extraction
Titel: Navigation-Logik aus EnsureFilamentTenantSelected in Panel-Konfiguration verlagern
Ziel: Die 270-LOC-Middleware soll reine Scope-Validation machen. Navigation-Build-Logik gehört in Panel-Konfiguration.
Problem: configureNavigationForRequest() baut inline eine "Workspace-Level"-Navigation per NavigationBuilder. Das ist fragile Sonderlogik.
Scope: Navigation-Konfiguration in Admin-Panel-Provider verlagern. Middleware auf Scope-Validation reduzieren. Tests für beide Aspekte separat.
Non-goals: Kein neues Panel. Keine Funktionsänderung.
Priorität: P1
Risiken: Mittel. Navigation-Verhalten muss identisch bleiben.
Abhängigkeiten: Spec 120 (Workspace-Home als Landing-Ziel), Spec 121 (Monitoring-Navigation bereinigt).
Reihenfolge: 4
Spec 125: Context-Bar & Scope-Indicator Enhancement
Titel: Context-Bar um Workspace-Home-Link, Scope-Indicator und Back-to-Workspace erweitern
Ziel: Nutzer sollen jederzeit wissen, auf welcher Ebene sie sich befinden, und explizit zwischen Ebenen wechseln können.
Problem: Kein Workspace-Home-Link in Context-Bar. Kein visueller Scope-Indicator (Workspace vs Tenant). "Back to Workspace" nur indirekt möglich.
Scope: Context-Bar-Dropdown erweitern: "Workspace overview" Link. Scope-Badge in Topbar (Workspace | Tenant). "Back to Workspace ↑" im Tenant-Panel.
Non-goals: Keine Breadcrumbs-Überarbeitung.
Priorität: P2
Risiken: Gering. UX-Änderung, kein Security-Impact.
Abhängigkeiten: Spec 120 (Workspace-Home existiert).
Reihenfolge: 5
Spec 126: Navigation & RBAC Alignment Enforcement
Titel: Navigation-Sichtbarkeit an Capabilities koppeln (Cluster, NavigationItems, Resources)
Ziel: Jeder NavigationItem und Cluster soll seine Sichtbarkeit an Capabilities koppeln, nicht nur an Panel-ID.
Problem: AlertsCluster prüft nur Panel-ID. NavigationItems im AdminPanelProvider sind nicht alle capability-gated. InventoryCluster hat keinen Visibility-Check.
Scope: Alle Clusters und NavigationItems mit Capability-Checks ausstatten. Architectural Test: "Jeder NavigationItem muss eine visible()-Closure haben, die Capabilities prüft."
Non-goals: Keine neuen Capabilities definieren.
Priorität: P2
Risiken: Gering. Könnte Navigation für Nutzer mit eingeschränkten Rechten ändern → gezieltes Testing.
Abhängigkeiten: Keine.
Reihenfolge: 5 (parallel zu Spec 125)
Empfohlene Reihenfolge:
1. Spec 120 (Workspace Home) ← Enabler [P0]
2. Spec 121 (Monitoring Scope) + Spec 123 (canAccess Zero Trust) [P0/P1, parallel]
3. Spec 122 (Resource Discovery Isolation) [P1, parallel]
4. Spec 124 (Middleware Extraction) [P1, after 120+121]
5. Spec 125 (Context-Bar) + Spec 126 (RBAC Alignment) [P2, parallel]
Quick Wins (QW1–QW5) werden sofort vor allen Specs implementiert.
Appendix: Discovery-Overlap-Analyse
Beide Panels discovern aus app/Filament/Resources:
| Resource | $tenantOwnershipRelationshipName |
Admin-Panel (should be) | Tenant-Panel (should be) | Aktuell in |
|---|---|---|---|---|
| PolicyResource | tenant |
❌ Nein | ✅ Ja | Beide |
| InventoryItemResource | tenant |
❌ Nein | ✅ Ja | Beide |
| BackupScheduleResource | tenant |
❌ Nein | ✅ Ja | Beide |
| BackupSetResource | tenant |
❌ Nein | ✅ Ja | Beide |
| RestoreRunResource | tenant |
❌ Nein | ✅ Ja | Beide |
| FindingResource | tenant |
❌ Nein | ✅ Ja | Beide |
| ReviewPackResource | tenant |
❌ Nein | ✅ Ja | Beide |
| PolicyVersionResource | tenant |
❌ Nein | ✅ Ja | Beide |
| EntraGroupResource | none | ❌ Nein | ✅ Ja | Beide |
| TenantResource | none | ✅ Ja | ❌ Nein | Beide (explizit) |
| OperationRunResource | none | ✅ Ja | ❌ Nein | Beide |
| AlertRuleResource | none | ✅ Ja | ❌ Nein | Beide |
| AlertDestinationResource | none | ✅ Ja | ❌ Nein | Beide |
| AlertDeliveryResource | none | ✅ Ja | ❌ Nein | Beide |
| ProviderConnectionResource | none | ✅ Ja | ❌ Nein | Admin (explicit) |
| WorkspaceResource | none | ✅ Ja | ❌ Nein | Admin (explicit, not discovered) |
| BaselineProfileResource | none | ✅ Ja | ❌ Nein | Admin (explicit, not discovered) |
| BaselineSnapshotResource | none | ✅ Ja | ❌ Nein | Admin (explicit, not discovered) |
Ergebnis: 9 tenant-scoped Resources werden aktuell in beiden Panels discovert. Filament's Tenancy-System filtert die Daten korrekt per $tenantOwnershipRelationshipName, aber die Resources erscheinen trotzdem in der Navigation des Admin-Panels (wenn auch teilweise ohne Daten).