119 lines
5.5 KiB
Markdown
119 lines
5.5 KiB
Markdown
# Konfiguration
|
|
|
|
Die Runtime-Konfiguration wird ueber Umgebungsvariablen geladen und mit Zod in
|
|
`apps/backend/src/config/env.ts` validiert. `.env.example` ist die Referenz fuer
|
|
lokale Entwicklung und Deployment-Vorlagen.
|
|
|
|
## Allgemein
|
|
|
|
| Variable | Bedeutung |
|
|
| ------------------- | -------------------------------------------------------------------------- |
|
|
| `NODE_ENV` | `development`, `test` oder `production` |
|
|
| `PORT` | HTTP-Port des Backends |
|
|
| `APP_BASE_URL` | Externe Basis-URL der App; Grundlage fuer OIDC Callback |
|
|
| `FRONTEND_BASE_URL` | Frontend-Origin fuer Redirects und CORS; faellt auf `APP_BASE_URL` zurueck |
|
|
| `TRUST_PROXY` | Express Trust Proxy, wenn hinter Reverse Proxy |
|
|
|
|
## Datenbank
|
|
|
|
| Variable | Bedeutung |
|
|
| ------------------- | --------------------------- |
|
|
| `DATABASE_HOST` | MySQL Host |
|
|
| `DATABASE_PORT` | MySQL Port, Standard `3306` |
|
|
| `DATABASE_NAME` | Datenbankname |
|
|
| `DATABASE_USER` | Datenbankbenutzer |
|
|
| `DATABASE_PASSWORD` | Datenbankpasswort |
|
|
| `DATABASE_SSL` | TLS fuer MySQL-Verbindung |
|
|
|
|
Die Datenbank muss MySQL 8 und `utf8mb4` unterstuetzen. Migrationen werden
|
|
separat ausgefuehrt.
|
|
|
|
## OIDC
|
|
|
|
| Variable | Bedeutung |
|
|
| ------------------------- | ------------------------------------------------------- |
|
|
| `OIDC_ISSUER` | Exakter Issuer des Providers |
|
|
| `OIDC_CLIENT_ID` | Client ID |
|
|
| `OIDC_CLIENT_SECRET` | Client Secret |
|
|
| `OIDC_SCOPES` | Scopes, typischerweise `openid profile email` |
|
|
| `OIDC_LOGOUT_URL` | Optionale IdP-Logout-URL, falls Discovery keine liefert |
|
|
| `OIDC_ALLOWED_ALGORITHMS` | Erlaubte ID-Token-Signaturalgorithmen, z. B. `RS256` |
|
|
| `OIDC_HTTP_TIMEOUT_MS` | Timeout fuer IdP-HTTP-Requests |
|
|
|
|
Der Callback ist immer:
|
|
|
|
```text
|
|
<APP_BASE_URL>/api/auth/callback
|
|
```
|
|
|
|
Beim App-Logout wird zuerst die lokale Session widerrufen. Danach leitet die App
|
|
zum OIDC `end_session_endpoint` aus Discovery weiter. Wenn der Provider diesen
|
|
Endpoint nicht publiziert, kann `OIDC_LOGOUT_URL` gesetzt werden. Die App sendet
|
|
`client_id`, `post_logout_redirect_uri` und, falls vorhanden, `id_token_hint`.
|
|
|
|
## Sessions und CSRF
|
|
|
|
| Variable | Bedeutung |
|
|
| ---------------------------------- | --------------------------------------------------------- |
|
|
| `SESSION_COOKIE_NAME` | Name des signierten Session-Cookies |
|
|
| `SESSION_IDLE_TIMEOUT_SECONDS` | Inaktivitaetsablauf |
|
|
| `SESSION_ABSOLUTE_TIMEOUT_SECONDS` | Absoluter Ablauf unabhaengig von Aktivitaet |
|
|
| `SESSION_SECRET` | Secret fuer Cookie-Signatur, mindestens 32 Zeichen |
|
|
| `SESSION_ENCRYPTION_KEY` | Secret fuer Token-Verschluesselung, mindestens 32 Zeichen |
|
|
| `CSRF_HEADER_NAME` | Header fuer CSRF-Token, Standard `X-CSRF-Token` |
|
|
|
|
In Produktion duerfen diese Secrets keine Beispielwerte enthalten. Die
|
|
Konfiguration bricht bei offensichtlichen Platzhaltern ab.
|
|
|
|
## CORS, Logging, Swagger und Rate Limits
|
|
|
|
| Variable | Bedeutung |
|
|
| ------------------------------------- | ---------------------------------------- |
|
|
| `CORS_ORIGINS` | Kommagetrennte erlaubte Origins |
|
|
| `LOG_LEVEL` | Pino Log Level |
|
|
| `SWAGGER_ENABLED` | Swagger UI und JSON aktivieren |
|
|
| `RATE_LIMIT_WINDOW_SECONDS` | Globales IP-Zeitfenster |
|
|
| `RATE_LIMIT_MAX_REQUESTS` | Globale Requests pro IP und Zeitfenster |
|
|
| `RATE_LIMIT_SENSITIVE_WINDOW_SECONDS` | Zeitfenster fuer sensible Endpunkte |
|
|
| `RATE_LIMIT_SENSITIVE_MAX_REQUESTS` | Requests pro IP auf sensiblen Endpunkten |
|
|
|
|
`SWAGGER_ENABLED` sollte in Produktion nur bewusst aktiviert werden. Das
|
|
eingebaute Rate Limiting ist In-Memory, pro Prozess und nicht fuer horizontale
|
|
Skalierung koordiniert. Es ist fuer genau eine Containerinstanz ausgelegt.
|
|
|
|
## Beispiel fuer Produktion
|
|
|
|
```env
|
|
NODE_ENV=production
|
|
PORT=3000
|
|
APP_BASE_URL=https://business.example.com
|
|
FRONTEND_BASE_URL=https://business.example.com
|
|
TRUST_PROXY=true
|
|
DATABASE_HOST=mysql.internal
|
|
DATABASE_PORT=3306
|
|
DATABASE_NAME=business_app
|
|
DATABASE_USER=business_app
|
|
DATABASE_PASSWORD=<secret>
|
|
DATABASE_SSL=true
|
|
OIDC_ISSUER=https://idp.example.com/realms/internal
|
|
OIDC_CLIENT_ID=business-app
|
|
OIDC_CLIENT_SECRET=<secret>
|
|
OIDC_SCOPES=openid profile email
|
|
OIDC_LOGOUT_URL=https://idp.example.com/realms/internal/protocol/openid-connect/logout
|
|
OIDC_ALLOWED_ALGORITHMS=RS256
|
|
OIDC_HTTP_TIMEOUT_MS=5000
|
|
SESSION_COOKIE_NAME=app_session
|
|
SESSION_IDLE_TIMEOUT_SECONDS=28800
|
|
SESSION_ABSOLUTE_TIMEOUT_SECONDS=604800
|
|
SESSION_SECRET=<secret>
|
|
SESSION_ENCRYPTION_KEY=<secret>
|
|
CORS_ORIGINS=https://business.example.com
|
|
CSRF_HEADER_NAME=X-CSRF-Token
|
|
LOG_LEVEL=info
|
|
SWAGGER_ENABLED=false
|
|
RATE_LIMIT_WINDOW_SECONDS=60
|
|
RATE_LIMIT_MAX_REQUESTS=300
|
|
RATE_LIMIT_SENSITIVE_WINDOW_SECONDS=60
|
|
RATE_LIMIT_SENSITIVE_MAX_REQUESTS=10
|
|
```
|