# 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/explanation-session-management.md`
- `/docs/howto-anfragelimits.md`
- `/docs/tutorial-07-security-tenant-scope.md`
- `/docs/howto-rbac-permissions-playbook.md`
