# Security-Modell Das Boilerplate trennt Browser, Backend und Identity Provider strikt. Der Browser bekommt keine OIDC-Tokens. Das Backend ist fuer Authentifizierung, Autorisierung, CSRF und Session-Verwaltung verbindlich. ## OIDC Der Login nutzt Authorization Code Flow mit PKCE: 1. Browser ruft `/api/auth/login` auf. 2. Backend erzeugt `state`, `nonce`, `code_verifier` und leitet zum IdP weiter. 3. IdP ruft `/api/auth/callback` mit `code` und `state` auf. 4. Backend tauscht den Code gegen Tokens. 5. Backend validiert ID Token, Issuer, Audience, Nonce und Algorithmus. 6. Backend laedt optional UserInfo. 7. Backend legt oder aktualisiert den lokalen Benutzer. 8. Backend erzeugt eine serverseitige Session. Erlaubte Signaturalgorithmen werden ueber `OIDC_ALLOWED_ALGORITHMS` gesetzt. `none` ist explizit verboten. ## Sessions Sessions liegen in MySQL. Das Session-Cookie enthaelt keine Tokens oder Benutzerdaten, sondern nur eine signierte Session-ID. Gespeichert werden unter anderem: - verschluesselte OIDC-Tokens - Hash des CSRF-Tokens - Ablaufzeiten fuer Idle Timeout und absolutes Timeout - User-Agent und IP fuer Anzeige und Audit-Kontext - Revocation-Zeitpunkt Die Token-Verschluesselung nutzt `SESSION_ENCRYPTION_KEY`. Cookie-Signaturen nutzen `SESSION_SECRET`. Beide Werte muessen in Produktion echte Secrets sein. ## CSRF Schreibende Methoden `POST`, `PUT`, `PATCH` und `DELETE` brauchen ein gueltiges CSRF-Token. Das Frontend liest das CSRF-Cookie und sendet es als `X-CSRF-Token`. Das Backend vergleicht nur den Hash gegen die Session. Public Routes sind vom CSRF-Guard ausgenommen, sofern sie mit `@Public()` markiert sind. ## Rollen und Permissions Permissions werden in `apps/backend/src/roles/permissions.ts` definiert. Rollen sind Datenbankdaten und referenzieren diese Permissions. Benutzer haben keine direkten Permissions. Backend-Controller schuetzen Endpunkte mit: ```ts @RequirePermissions(Permission.ItemsRead) ``` Angular nutzt Permissions nur fuer Navigation und Darstellung. Eine versteckte Schaltflaeche ist keine Sicherheitsgrenze. ## Benutzerstatus Deaktivierte Benutzer werden trotz erfolgreichem IdP-Login abgewiesen. Aktive Sessions deaktivierter Benutzer werden beim Session-Resolve unbrauchbar gemacht. ## Cookies und Proxy In Produktion sollte TLS vor der Anwendung terminiert werden, zum Beispiel mit Nginx. Setze `TRUST_PROXY=true`, wenn die Anwendung hinter einem vertrauenswuerdigen Reverse Proxy laeuft und korrekte Forwarded Header benoetigt. `APP_BASE_URL` muss die externe URL der Anwendung enthalten, weil daraus die OIDC Callback URL gebaut wird. ## Logging und Redaction Das Backend redigiert sensible Werte in Standard-HTTP-Logs: - `Authorization` - `Cookie` - `X-CSRF-Token` - `Set-Cookie` - Access-, Refresh- und ID-Tokens Neue Logs duerfen keine Secrets, Tokens, Session-IDs oder vollstaendige Cookies enthalten. Fuer Auditing sollten fachliche IDs und Request IDs verwendet werden. ## Swagger `SWAGGER_ENABLED` ist in Produktion standardmaessig `false`. Wenn Swagger in Produktion aktiviert wird, sollte der Zugriff ueber Netzwerkregeln oder Reverse Proxy zusaetzlich eingeschraenkt werden. ## Rate Limiting Das konfigurierte Rate Limiting ist fuer eine einzelne Containerinstanz ohne Redis ausgelegt. Die Zaehler liegen im Prozessspeicher. Bei horizontaler Skalierung muss ein gemeinsamer Store eingefuehrt oder der Schutz an den Reverse Proxy verlagert werden. Es gibt zwei fruehe Ebenen: - Globales IP-Limit fuer alle Requests, bevor Guards und Controller laufen. - Strengeres IP-Limit fuer sensible Endpunkte, ebenfalls bevor Session-Resolve und fachliche Datenbankzugriffe laufen. Sensible Endpunkte werden mit `@SensitiveRateLimit()` markiert. Dazu gehoeren Login, OIDC Callback, Logout, Session-Revoke sowie Benutzer- und Rollenverwaltung. Bei Ueberschreitung antwortet die API mit HTTP 429, `RATE_LIMIT_EXCEEDED`, `Retry-After` und `X-RateLimit-*` Headern. Ein zusaetzliches Benutzer-Limit waere technisch moeglich, wuerde in diesem Projekt aber erst nach dem serverseitigen Session-Resolve greifen. Fuer die geforderte fruehe Lastreduktion ist deshalb das globale IP-Limit die verbindliche Schutzschicht.