# 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:

1. **Tenant-Health-Overview**: Anzahl aktive Tenants, Status (OK/Warning/Critical), letzte Sync-Zeiten
2. **Operations-KPIs**: Active/Queued/Failed operations (workspace-weit)
3. **Alert-Summary**: Aktive Alerts, undelivered, rules count
4. **Recent Activity**: Letzte 5 Audit-Log-Einträge (workspace-scoped)
5. **Needs Attention**: Failed operations, unacknowledged findings, overdue SLAs
6. **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

1. **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.

2. **Tenant ist operativer Kontext.** Tenant-scoped Seiten erfordern einen aktiven Tenant. Der Tenant-Kontext ist optional auf Workspace-Ebene und verpflichtend auf Tenant-Ebene.

3. **Jede Ebene hat genau einen klaren Home-Einstieg.** System → System Dashboard. Workspace → Workspace Dashboard. Tenant → Tenant Dashboard.

4. **Tenant-scoped Navigation erscheint NIE im Workspace-Panel.** Resources wie Policy, InventoryItem, BackupSchedule, Finding, ReviewPack gehören ausschließlich ins Tenant-Panel.

5. **Workspace-scoped Navigation erscheint NIE im Tenant-Panel.** Operations, Alerts, Audit Log, Workspace Settings, Workspace Management gehören ausschließlich ins Workspace-Panel.

6. **Settings/Admin sind immer untergeordnet zum Kernworkflow.** Settings-Navigationsgruppe steht am Ende der Sidebar, nie am Anfang.

7. **Brand-Logo führt zum kanonischen Home der aktuellen Ebene.** Workspace-Panel → `/admin`. Tenant-Panel → `/admin/t/{uuid}`.

8. **Switch workspace und Manage workspaces sind getrennte Konzepte.** "Switch workspace" wechselt den Kontext (via ChooseWorkspace). "Manage workspaces" ist eine Admin-Funktion (CRUD).

9. **Navigation ist NIE die Sicherheitsgrenze.** Jede Seite muss `canAccess()` implementieren, unabhängig von `shouldRegisterNavigation`. `shouldRegisterNavigation = false` ist eine UX-Entscheidung, keine Security-Maßnahme.

10. **Cross-Scope-Wechsel sind explizit.** Links, die den Scope wechseln (z.B. Tenant → Workspace), müssen visuell als solche erkennbar sein (Icon, Label, Farbe).

11. **Middleware erzeugt keine fachliche Navigation.** Die Navigation wird in der Panel-Konfiguration definiert, nicht dynamisch in Middleware gebaut.

12. **Resource-Discovery ist per Panel isoliert.** Jedes Panel discover Resources nur aus seinem eigenen Verzeichnis. Kein `discoverResources()` über Panel-Grenzen hinweg.

13. **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.

14. **URL-Semantik spiegelt Scope-Hierarchy wider.** `/admin/...` = Workspace-Level. `/admin/t/{uuid}/...` = Tenant-Level. `/system/...` = Platform-Level.

15. **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).
