# Sicherheitsmodell Letzte Aktualisierung: 2026-03-06 ## Ziel Kurze, verbindliche Übersicht der Sicherheitsmechanik für Web und API. ## Sicherheitskette pro Request 1. Firewall/Request-Grenze 2. Authentifizierung 3. Permission-Check 4. Tenant-Scope-Check 5. Endpoint-spezifische Regeln (z. B. Exporte, Media, Audit) Kein Layer allein reicht aus. ## Public vs. Protected - Public-Routen kommen aus `config/routes.php` (`public => true`). - Zusätzlich sind Präfixe technisch immer public (`branding/`, `flash/`, `auth/microsoft/`, `api/`) in `lib/Http/AccessControl.php`. - Alles andere erfordert Login. API-Sonderfall: - `pages/api/v1/auth/login().php` nutzt `ApiBootstrap::init(false)` (public Login-Endpunkt). - Geschützte API-Endpunkte nutzen `ApiBootstrap::init()`. ## Auth und Login - Web-Login ist session-basiert (`pages/auth/login().php`). - Remember-Me-Autologin läuft früh in `web/index.php`. - Multi-Tenant-Login wählt Tenant-Kontext serverseitig. - Microsoft-SSO läuft über OIDC (`auth/microsoft/start` + `auth/microsoft/callback`) mit `state`, `nonce`, PKCE und ID-Token-Validierung. ## Permission und Tenant-Scope - Rechte werden serverseitig geprüft (`PermissionService` + Policies). - UI-Sichtbarkeit wird ebenfalls serverseitig vorbereitet (`UiAccessService` + `$viewAuth`), nicht im Template selbst entschieden. - Globaler Scope-Bypass ist explizit: `tenant.scope.global`. - Beispiel für harte Feature-Gates: - `users.access_pdf` - `custom_fields.manage`, `custom_fields.edit_values` - `tenants.sso_manage` - `api_audit.view` ## API-Schutz - Zentrale API-Rate-Limits laufen in `lib/Http/ApiBootstrap.php`. - API-Audit läuft zentral über `ApiAuditService`: - loggt Metadaten (Pfad, Status, Dauer, Kontext) - redigiert sensible Query-Parameter - speichert keine Request-/Response-Bodies ## Edge-Hardening (Nginx) - Security-Header werden zentral im Nginx gesetzt. - Baseline: - `X-Content-Type-Options: nosniff` - `X-Frame-Options: SAMEORIGIN` - `Referrer-Policy: strict-origin-when-cross-origin` - `Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=()` - `X-Permitted-Cross-Domain-Policies: none` - Produktion ergänzt: - `Strict-Transport-Security: max-age=31536000` - Lokale Entwicklung setzt bewusst kein HSTS, um HTTP-/localhost-Workflows nicht zu beeinflussen. ## System-Audit (fachliche Aktionen) - Separater Audit-Stream: `system_audit_log` (unabhängig von `api_audit_log`). - Scope V2: - Web: Auth-Events + Admin-Write-Aktionen. - API: selektive `api.request`-Events (Write-Requests, `>=500`, Security-Endpunkte bei `>=400`). - Scheduler: `scheduler.run` (Runner-Zusammenfassung) und `scheduler.job.run` (pro Joblauf). - CLI: `cli.command` für zentrale Betriebsbefehle (z. B. `bin/doctor.php`). - Privacy-Default: - keine Request-/Response-Bodies - keine Klartext-Secrets/Passwörter/Tokens/E-Mails - IP/User-Agent nur gehasht (HMAC) - Globaler Schalter über Settings: - `system_audit_enabled` (hard-off: keine neuen Events) - `system_audit_retention_days` (Retention/Purge) - RBAC: - `system_audit.view` - `system_audit.purge` ## Schreibschutz - Web-Schreibaktionen laufen mit CSRF-Token. - Kritische Actions sind POST-only + serverseitige Validierung. - API nutzt Bearer-Auth und eigenes Schutzmodell (kein Form-CSRF). ## Betriebschecks - Permission-Set und Rollen regelmäßig prüfen. - Tenant-Entzug/Scope-Verhalten testen. - Rate-Limits und `429`-Verhalten bei Login/API testen. - Audit-Streams bewusst getrennt nutzen: - `system_audit_log`: fachliche/sicherheitsrelevante Ereignisse (summary-level) - `api_audit_log`: API-Request-Telemetrie (Status, Dauer, Pfad) - `import_audit_runs`, `user_lifecycle_audit_log`, `scheduled_job_runs`: Domänen-/Betriebsdetails - Audit-Retention prüfen: - API-Audit: 90 Tage - Import-Audit: 90 Tage - User-Lifecycle-Audit: 365 Tage - System-Audit: konfigurierbar (Default 365 Tage) ## Vertiefung - `/docs/howto-anfragelimits.md` - `/docs/tutorial-07-security-tenant-scope.md` - `/docs/howto-rbac-permissions-playbook.md`