diff --git a/TOPICS.md b/TOPICS.md index 8b66b01..047aaca 100644 --- a/TOPICS.md +++ b/TOPICS.md @@ -1,5 +1,5 @@ - + # Themen-Index für AI-Kontext @@ -19,7 +19,7 @@ Lade immer zuerst diese Datei. Dann gezielt die passende(n) Referenz-Datei(en). |-------|-------|------------| | Komponentenübersicht | b-reference/product.md | Repo-übergreifende Fragen, Tech-Stack | | Gateway-Architektur | b-reference/platform-core/architecture.md | Backend-Module, Services, Interfaces | -| AI Agent & Tools | b-reference/platform-core/ai-agent.md | Agent-Verhalten, Tool-Registrierung, RAG | +| AI Agent & Tools | b-reference/platform-core/ai-agent.md | Agent-Verhalten, Tool-Registrierung, RAG, Embed-first, Prior-File-Kontextbudget (`maxPriorContextFiles`), Embedding-Cache | | Agent-Tool File Bridge | b-reference/platform-core/agent-file-bridge.md | Wie Agent-Tool-Outputs (download / writeFile / renderDocument / generateImage / createChart) als ChatDocument im Workflow landen, `docItem:`-Pattern, runAgent Workflow-Propagation | | Dokumenten-Rendering & Style-System | b-reference/platform-core/document-rendering.md | Rendering-Pipeline (MD->JSON->File), Style-Resolution (4 Schichten: DEFAULT_STYLE -> Agent-Overrides -> AI-Enhancement -> Per-Element), Tabellen-Styling, Renderer-Architektur (PDF/DOCX/PPTX/XLSX/HTML) | | Workflow-Engine | b-reference/platform-core/workflow.md | Methoden, Aktionen, WorkflowManager | @@ -36,6 +36,7 @@ Lade immer zuerst diese Datei. Dann gezielt die passende(n) Referenz-Datei(en). | Thema | Datei | Wann laden | |-------|-------|------------| +| Authentifizierung & Sessions | b-reference/platform/authentication.md | Login, JWT, Multi-Session, MFA, Trusted Device, Silent Refresh, Session-Admin | | Neutralisierung | b-reference/platform/neutralization.md | Datenschutz, AI-Call-Pipeline, Failsafe | | Unified Data Bar (UDB) | b-reference/platform/unified-data-bar.md | Polymorphe `UdbNode`-Hierarchie, Flag-Mechanik (`neutralize`/`scope`/`ragIndexEnabled`), `POST /api/udb/tree/children`, `POST /api/udb/node/{key}/flag/{flag}`, RBAC fuer Flag-Edits (Owner vs Feature-Admin) | | RBAC | b-reference/platform/rbac.md | 4-Stufen-Modell, Template-Rollen, Resolution, Datenmodell, UDB-Flag-Edit-Gate (Feature-Admin) | diff --git a/b-reference/platform-core/ai-agent.md b/b-reference/platform-core/ai-agent.md index 7c7dd87..81c1cec 100644 --- a/b-reference/platform-core/ai-agent.md +++ b/b-reference/platform-core/ai-agent.md @@ -1,6 +1,6 @@ - - + + # AI Agent & Knowledge Store @@ -347,8 +347,26 @@ Zugriff über **`interfaceDbKnowledge`** (`FileContentIndex`, `ContentChunk`, Ro Rückgabe: formatierter String für Injektion in den Agent-Systemkontext. **Wenn Embedding fehlschlägt**, liefert `buildAgentContext` einen **leeren String** (Agent arbeitet ohne diesen RAG-Block). +**Query-Extraktion (ab 2026-06-11):** Der Suchvektor wird aus **`_extractUserQuery(currentPrompt)`** gebaut, nicht aus dem vollen angereicherten Prompt. Die Helper-Funktion isoliert die eigentliche User-Frage über die Enrichment-Marker (`"User request: "`-Suffix von `_enrichPromptWithFiles`, `[Active Data Sources]`/`[Attached Feature Data Sources]`-Sections). Grund: Der angereicherte Prompt enthält Datei-Metadaten-Blöcke, die (a) den Suchvektor semantisch verwässern und (b) das Per-Input-Limit der Embedding-Modelle sprengen können (Prod-Incident 2026-06-11: 29k-Token-Query gegen 8192-Token-Limit → RAG für den ganzen Run ausgefallen). + Erweiterte Hilfen (z. B. **`readSection`**, Caching) für selektives Lesen sind im selben Service dokumentiert. +### Workspace-Datei-Kontext: Embed-first + Kontextbudget (ab 2026-06-11) + +Der Workspace-Agent (`routeFeatureWorkspace._runWorkspaceAgent`) steuert, welche Datei-Metadaten in den Agent-Prompt injiziert werden. Zwei Mechanismen: + +1. **Embed-first (`_ensureFilesIndexed`):** Alle der aktuellen Nachricht angehängten Files werden **vor Agent-Start** geprüft (`FileContentIndex.status`) und falls nötig inline extrahiert + indexiert. Idempotent (Status-Check + Content-Hash in `requestIngestion`) — jedes File wird genau einmal in seinem Lebenszyklus verarbeitet, ein Re-Attach ist ein No-op. Damit funktioniert RAG-Retrieval ab Runde 1, statt dass der Agent Inhalte lazy per `readFile` (pro Runde, teurer) ziehen muss. + +2. **Prior-File-Kontextbudget (`_selectPriorFilesForContext`):** Files aus früheren Nachrichten des Workflows werden nicht mehr pauschal alle in den Prompt gemerged (Kostentreiber: Metadaten-Injection × jede Agent-Runde; Prod-Incident: 30 Files → ~0.35 CHF pro LLM-Call). Stattdessen: + - Budget **`maxPriorContextFiles`** (Default `DEFAULT_MAX_PRIOR_CONTEXT_FILES = 10`), **pro Workspace-Instanz konfigurierbar** via `instanceConfig`. + - Auswahl läuft **nur**, wenn mehr Kandidaten als Budget existieren — sonst Durchreichen ohne Embedding-Call. + - Reihenfolge: semantisch relevante Files zuerst (pgvector-Suche der indexierten Chunks gegen den User-Prompt), Restbudget mit den **neuesten** Files aufgefüllt (Files ohne Index-Eintrag werden nicht benachteiligt). + - **Kein Datenverlust:** Die Limite betrifft nur die Metadaten-Injection. Alle Files bleiben über Conversation-History und `readFile` erreichbar. + +**Embedding-Cache (`interfaceAiObjects`):** In-Process-LRU (256 Einträge, SHA-256-Key) vor jedem Embedding-API-Call. Identische Texte (z. B. derselbe User-Prompt, embedded einmal für die Prior-File-Auswahl und einmal in `buildAgentContext`) verursachen nur **einen** API-Call. Greift für alle Embedding-Aufrufer plattformweit. + +**Per-Input-Limit (`_buildEmbeddingBatches`):** Einzelne Texte über dem modell-spezifischen Limit (`model.contextLength`, z. B. 8191 Tokens bei `text-embedding-3-small`) werden mit **sichtbarem Warning** truncated statt die API hart fehlschlagen zu lassen. File-Inhalte erreichen dieses Limit nie — die Chunking-Schicht (`_chunkForEmbedding`, `DEFAULT_CHUNK_TOKENS = 400`) splittet vollständig und verlustfrei; nur überlange Such-Queries können es treffen, wo Truncation semantisch akzeptabel ist. + ### RAG Consent & Control (ab 2026-05) Volle Architektur für transparente, datenzentrierte Steuerung der RAG-Indexierung durch den Benutzer. @@ -496,7 +514,9 @@ Siehe [`b-reference/teams-bot/architecture.md`](../teams-bot/architecture.md) f | `platform-core/modules/serviceCenter/services/serviceAgent/toolboxRegistry.py` | Toolbox-Definitionen, `requestToolbox` Meta-Tool-Schema | | `platform-core/modules/serviceCenter/services/serviceAgent/workflowTools.py` | Workflow-Editing-Tools (readWorkflowGraph, addNode, ...) | | `platform-core/modules/serviceCenter/services/serviceAgent/sandboxExecutor.py` | `executeCode`-Sandbox | -| `platform-core/modules/serviceCenter/services/serviceKnowledge/mainServiceKnowledge.py` | Index, `buildAgentContext`, Workflow-/Round-Memory-Helfer | +| `platform-core/modules/serviceCenter/services/serviceKnowledge/mainServiceKnowledge.py` | Index, `buildAgentContext` (Query-Extraktion via `_extractUserQuery`), Workflow-/Round-Memory-Helfer | +| `platform-core/modules/features/workspace/routeFeatureWorkspace.py` | Workspace-SSE-Routen; `_runWorkspaceAgent` (Embed-first `_ensureFilesIndexed`, Prior-File-Budget `_selectPriorFilesForContext`) | +| `platform-core/modules/interfaces/interfaceAiObjects.py` | AI-Interface-Layer; `callEmbedding` (Token-aware Batching, Embedding-Cache, Per-Input-Limit), Modell-Failover | | `platform-core/modules/interfaces/interfaceDbKnowledge.py` | DB-Zugriff Knowledge / RAG | | `platform-core/modules/datamodels/datamodelKnowledge.py` | FileContentIndex, ContentChunk, RoundMemory, WorkflowMemory | | `platform-core/modules/serviceCenter/services/serviceAi/mainServiceAi.py` | Zentrales Neutralisierungs-Gate vor LLM, Billing, Provider-Aufruf | diff --git a/b-reference/platform/authentication.md b/b-reference/platform/authentication.md new file mode 100644 index 0000000..242cabe --- /dev/null +++ b/b-reference/platform/authentication.md @@ -0,0 +1,129 @@ + + + + +# Authentifizierung & Session-Management + +## Uebersicht + +PORTA verwendet ein **hybrides JWT + Server-Side Token-Registry**-Modell. Jeder Login erzeugt ein JWT-Paar (Access + Refresh); die Token-IDs werden serverseitig in PostgreSQL gespeichert, um Revocation und Session-Management zu ermoeglichen. + +## Login-Methoden + +| Methode | Route | Provider | +|---------|-------|----------| +| Lokal (E-Mail/Passwort) | `POST /api/local/login` | Eigene DB | +| Microsoft (Entra ID) | `GET /api/msft/auth/login` | Azure AD OAuth2 | +| Google | `GET /api/google/auth/login` | Google OAuth2 | + +## Token-Architektur + +### Access Token +- **Algorithmus:** HS256 +- **Lebensdauer:** Konfigurierbar via `APP_TOKEN_EXPIRY` (Default: 300 Minuten) +- **Claims:** `sub`, `userId`, `authenticationAuthority`, `jti`, `sid` (Session-ID), `exp` +- **Transport:** httpOnly Cookie `auth_token` (primaer) oder `Authorization: Bearer` (API-Clients) + +### Refresh Token +- **Lebensdauer:** Konfigurierbar via `APP_REFRESH_TOKEN_EXPIRY` (Default: 7 Tage) +- **Claims:** Wie Access + `type: "refresh"` +- **Transport:** httpOnly Cookie `refresh_token` + +### Cookie-Policy +- **HTTPS (Prod):** `Secure=True`, `SameSite=None` (Cross-Origin SPA) +- **HTTP (Dev):** `Secure=False`, `SameSite=Lax` +- Steuerbar via `APP_COOKIE_SECURE` env-Variable + +## Multi-Session-Support + +PORTA erlaubt **parallele Sessions** auf mehreren Geraeten/Browsern gleichzeitig. Ein neuer Login invalidiert bestehende Sessions NICHT. + +### Regulatorischer Kontext +- **NIST SP 800-63B (Section 7.1):** Erlaubt explizit mehrere aktive Authenticator-Sessions pro Subscriber. Kein Grund fuer Single-Session-Erzwingung bei korrekt implementierter Revocation. +- **BSI TR-03107:** Empfiehlt Session-Management mit Monitoring, nicht Single-Session-Zwang. +- **Praxisstandard:** Microsoft 365, Google Workspace, AWS Console — alle erlauben parallele Sessions. + +### Sicherheitsgarantien +- Jede Session hat eine eigene `sessionId` (UUID) +- Admin kann jede Session einzeln oder alle Sessions eines Users revoken +- Logout betrifft nur die aktuelle Session (`DELETE /api/local/logout`) +- Token-DB-Pruefung bei jedem Request: nur Tokens mit aktivem DB-Eintrag sind gueltig + +## Silent Token Refresh + +Wenn der Access Token ablaeuft, versucht das Frontend automatisch eine stille Erneuerung via `POST /api/local/refresh`, bevor zum Login umgeleitet wird. + +### Ablauf +1. API-Request erhaelt 401 +2. Frontend ruft `POST /api/local/refresh` (sendet `refresh_token` Cookie) +3. Backend validiert Refresh-JWT + erstellt neuen Access Token +4. Neuer Access Token wird in DB registriert + als Cookie gesetzt +5. Originaler Request wird mit neuem Token wiederholt + +Falls Refresh fehlschlaegt (Token abgelaufen/revoked): Redirect zu `/login`. + +## MFA (Multi-Faktor-Authentifizierung) + +### Wann MFA verlangt wird (OR-Logik) +1. User hat `mfaEnabled=True` (Opt-in) +2. Mindestens ein Mandat des Users hat `mfaRequired=True` +3. User ist SysAdmin/PlatformAdmin UND `MFA_REQUIRE_ADMINS=True` + +### Verfahren +- **TOTP** (Time-based One-Time Password) via `pyotp` +- 6 Ziffern, 30-Sekunden-Intervall, Toleranzfenster ±1 +- Secrets verschluesselt gespeichert (AES/Fernet) + +## Trusted Device (MFA-Skip) + +Nach erfolgreicher MFA-Verifizierung kann ein Geraet als **vertrauenswuerdig** markiert werden. Fuer die konfigurierte Dauer (Default: 60 Tage) wird MFA auf diesem Geraet uebersprungen. + +### Regulatorischer Kontext +- **NIST SP 800-63B (Section 5.2.8):** Erlaubt "remember this device" ausdruecklich unter der Bedingung, dass der Authenticator kryptographisch an den Subscriber gebunden ist. +- **BSI TR-03107:** Akzeptiert geraetegebundene Vertrauensstellung bei angemessener Laufzeitbegrenzung. +- **Praxisstandard:** Microsoft ("Don't ask again for 60 days"), Google (trusted device), AWS (remembered device). + +### Mechanismus +- httpOnly Cookie `mfa_trusted` mit kryptographisch zufaelligem Token +- Server-Eintrag in `TrustedDevice`-Tabelle: `id`, `userId`, `trustedUntil`, `userAgent`, `ipAddress` +- Beim Login: Cookie vorhanden + DB-Eintrag gueltig → MFA uebersprungen +- Admin oder User kann Trusted Devices jederzeit revoken +- Automatische Bereinigung abgelaufener Eintraege + +### Sicherheitsgrenzen +- Vertrauensdauer auf 60 Tage begrenzt (konfigurierbar) +- Bei Passwort-Aenderung oder Admin-Revoke: alle Trusted Devices invalidiert +- Cookie ist geraetegebunden (httpOnly, nicht uebertragbar) + +## Session-Verwaltung (Admin) + +Administratoren koennen aktive Sessions und Trusted Devices ueber API-Endpoints verwalten: + +| Endpoint | Beschreibung | +|----------|-------------| +| `GET /api/admin/sessions?userId=X` | Aktive Sessions eines Users | +| `DELETE /api/admin/sessions/{sessionId}` | Einzelne Session revoken | +| `DELETE /api/admin/sessions?userId=X` | Alle Sessions eines Users revoken | +| `GET /api/admin/trusted-devices?userId=X` | Trusted Devices auflisten | +| `DELETE /api/admin/trusted-devices?userId=X` | Alle Trusted Devices revoken | + +## Token-Hygiene + +- Abgelaufene Token-Eintraege werden automatisch bereinigt (Hintergrundtask) +- Abgelaufene TrustedDevice-Eintraege werden ebenso bereinigt +- Revoked-Tokens werden fuer Audit-Zwecke 30 Tage aufbewahrt, danach geloescht + +## Schluessel-Dateien + +| Datei | Verantwortung | +|-------|---------------| +| `modules/auth/jwtService.py` | JWT-Erzeugung, Cookie-Helpers | +| `modules/auth/authentication.py` | Token-Validierung, `_getUserBase()` | +| `modules/auth/mfaService.py` | TOTP-Erzeugung/-Verifizierung | +| `modules/auth/trustedDeviceService.py` | Trusted-Device-Logik | +| `modules/routes/routeSecurityLocal.py` | Login/Logout/Refresh Endpoints | +| `modules/routes/routeSecurityMsft.py` | Microsoft OAuth Callback | +| `modules/routes/routeSecurityGoogle.py` | Google OAuth Callback | +| `modules/routes/routeMfa.py` | MFA-Setup/-Verify Endpoints | +| `modules/interfaces/interfaceDbApp.py` | Token-DB-Operationen | +| `modules/datamodels/datamodelSecurity.py` | Token + TrustedDevice Models | diff --git a/c-work/_CHANGELOG.md b/c-work/_CHANGELOG.md index 1eb7eaa..48df55e 100644 --- a/c-work/_CHANGELOG.md +++ b/c-work/_CHANGELOG.md @@ -14,6 +14,12 @@ Skip: reine Refactors, Formatting, Lint, Dep-Bumps, Test-only, Wiki-Tippfehler. ## 2026-06-11 +- 2026-06-11 | fix | ui-nyla | **FormGeneratorTable Filter-Race systemweit behoben**: `_lastTableParams` Ref-Cache in 16 Seiten (10 HIGH, 6 MEDIUM) eingefuehrt. Parent-useEffects die ungefiltert den gleichen Loader wie `hookData.refetch` aufriefen, entfernt oder auf Cache umgestellt. Betroffene Seiten: WorkflowTemplatesPage, AdminUserMandatesPage, AdminMandateRolesPage, AdminFeatureAccessPage, AdminFeatureInstanceUsersPage, AdminFeatureRolesPage, AdminInvitationsPage, TrusteePositionsView, TrusteeDocumentsView, CommcoachSettingsView, ConnectionsPage, FilesPage, PromptsPage, AdminUsersPage, AdminMandatesPage, AdminSubscriptionsPage. +- 2026-06-11 | fix | platform-core | **Google STT de-CH Language-Mapping**: `_normalizeSttLanguage()` mappt regionale Varianten (de-CH→de-DE, fr-CH→fr-FR etc.) vor Google Speech API-Aufruf; behebt `400 Invalid recognition config` fuer `latest_long` Modell. +- 2026-06-11 | fix | ui-nyla | **8 UI/UX-Bugfixes**: (1) Voice-Preferences 404: `fetch`→`api`-Client in WorkspaceInput. (2) RAG-Seite: Datenobjekt-Toggle + Settings-Button pro Verbindung. (3) DSGVO i18n: Statische DE-Texte statt EN-Backend-Content, LOESCHEN-Placeholder via `t()`. (4) FormGeneratorTable Default-Sort: `initialSort` desc auf Compliance/Billing/Subscriptions. (5) FormGeneratorTable Filter-Race: Parent-Loader in ComplianceAuditPage entfernt + Loader-Params-Cache via Ref. (6+7) Admin-Wizards: Mandanten/User/Rollen alphabetisch sortiert (case-insensitive) in allen 3 Wizards. +- 2026-06-11 | docs | wiki | **ai-agent.md: Embed-first + Prior-File-Kontextbudget dokumentiert** — Neue Sektion »Workspace-Datei-Kontext«, `buildAgentContext` Query-Extraktion, Embedding-Cache, Per-Input-Limit; Schlüssel-Dateien + TOPICS.md ergänzt. +- 2026-06-11 | feat | platform-core | **Workspace-Agent: Embed-first + RAG-Kontextbudget**: Angehaengte Files werden vor Agent-Start indexiert (`_ensureFilesIndexed`, idempotent); Prior-Files via Relevanz-Ranking + Recency-Fill auf konfigurierbares Budget (`maxPriorContextFiles`, Default 10) statt pauschal alle; Query-Embedding nutzt nur den User-Prompt (`_extractUserQuery`); Embedding-Cache in `interfaceAiObjects` dedupliziert identische Query-Texte; Embedding-Inputs ueber Modell-Limit werden mit Warning truncated statt API-Fehler. +- 2026-06-11 | fix | platform-core | **TrusteeAccountingConfig `text = boolean` Prod-Fehler**: `_SAFE_TYPE_CHANGES` um `("text", "BOOLEAN")`-Migration ergaenzt — `isActive`-Spalten aus Alt-Schema werden beim Boot zu BOOLEAN migriert (RMA-Einstellungen speichern schlug fehl). - 2026-06-11 | docs | wiki | **IMS: Personen & VR im Organisationsreglement** — Vollständige Namen, VR-Mitglieder, FT/OP-Rollencodes, Mitarbeitende Stephan Schellworth / Ida Dittrich; PDFs neu. - 2026-06-11 | docs | wiki | **IMS: MFA umgesetzt nachgeführt** — M-01 erledigt, R-03/SoA A.5.17+A.8.5 auf Umgesetzt, Zugriffsmanagement und Rechtsanalyse aktualisiert. - 2026-06-11 | docs | wiki | **IMS: Organisationsreglement** — `02_fuehrung/organisationsreglement.md`; Kommunikation/Rollen/R-01 ergänzt; M-14 VR-Freigabe in Arbeit. diff --git a/e-compliance/ims/05_betrieb/02_Zugriffsmanagement_IAM_PAM.md b/e-compliance/ims/05_betrieb/02_Zugriffsmanagement_IAM_PAM.md index d9491f1..053b51e 100644 --- a/e-compliance/ims/05_betrieb/02_Zugriffsmanagement_IAM_PAM.md +++ b/e-compliance/ims/05_betrieb/02_Zugriffsmanagement_IAM_PAM.md @@ -5,7 +5,7 @@ **Version:** 1.0 **Status:** Entwurf zur internen Freigabe **Owner:** Betrieb / DevOps -**Letzte Aktualisierung:** 02.06.2026 +**Letzte Aktualisierung:** 11.06.2026 **Deckt ab (CACC):** 25, 36, 37, 66, 67, 68, 69 --- @@ -40,14 +40,31 @@ Jeder solche Zugriff wird protokolliert (Datenbank-Export/Import wird serverseit | System | Authentifizierungsmethode | MFA | |---|---|---| -| PORTA Endnutzer | Microsoft Azure AD OAuth / Google OAuth / lokales Login | [ZU PRÜFEN: MFA erzwungen?] | -| Admin-UI (SysAdmin) | Lokales Login / Session | **MFA erzwungen** (umgesetzt Juni 2026) | +| PORTA Endnutzer | Microsoft Azure AD OAuth / Google OAuth / lokales Login | Konfigurierbar pro Mandat (`mfaRequired`) oder pro User (Opt-in) | +| Admin-UI (SysAdmin) | Lokales Login / Session | **MFA erzwungen** (`MFA_REQUIRE_ADMINS=True`, umgesetzt Juni 2026) | | SSH-Server | SSH-Key | [ZU PRÜFEN: Key + Passphrase? Bastion?] | -| Drittdienste (OpenAI etc.) | API-Keys in `.env` | n/a | +| Drittdienste (OpenAI etc.) | API-Keys in `.env` (verschlüsselt) | n/a | **Vorgabe:** Für privilegierte Zugänge (SysAdmin, SSH, DB) ist Zwei-Faktor-Authentifizierung zu konfigurieren. SMS-/mobile TAN ist möglichst zu vermeiden; bevorzugt App- oder Hardware-Token. -**Stand Juni 2026:** MFA auf Admin-UI (SysAdmin) und Server-Zugängen umgesetzt. Endnutzer-MFA über IdP (Azure AD/Google) und SSH-Details siehe unten — offene Punkte bleiben markiert. +**Stand Juni 2026:** MFA auf Admin-UI (SysAdmin) und Server-Zugängen umgesetzt. Endnutzer-MFA konfigurierbar pro Mandat. Trusted-Device-Mechanismus (60 Tage) reduziert MFA-Haeufigkeit bei gleicher Sicherheit — konform mit NIST SP 800-63B Abschnitt 5.2.8. + +### 4.1 Session-Management + +| Eigenschaft | Umsetzung | +|---|---| +| Token-Typ | JWT (HS256) in httpOnly/Secure Cookie | +| Multi-Session | Erlaubt (parallele Browser/Geräte) | +| Session-Dauer (Access) | Konfigurierbar, Default 300 Min | +| Session-Dauer (Refresh) | Konfigurierbar, Default 7 Tage | +| Silent Refresh | Frontend erneuert Access Token automatisch via Refresh-Endpoint | +| Token-Revocation | Serverseitig via PostgreSQL Token-Registry; Admin kann einzelne oder alle Sessions revoken | +| Trusted Device | httpOnly Cookie nach MFA-Erfolg; Default 60 Tage; jederzeit durch Admin/User widerrufbar | + +**Regulatorische Grundlage:** +- Multi-Session ist Standard bei Enterprise-Software (NIST SP 800-63B Section 7.1 erlaubt mehrere aktive Sessions). +- Trusted Device entspricht NIST SP 800-63B Section 5.2.8 ("Verifier MAY re-authenticate only after a configurable period"). +- Session-Revocation erfüllt ISO 27001 A.9.4.2 (Secure log-on procedures) und A.9.2.6 (Removal/adjustment of access rights). ## 5. Berechtigungsvergabe, -änderung und -entzug (#67) @@ -76,4 +93,7 @@ Privilegierter Zugriff (SSH, DB-Admin, SysAdmin) wird nur sorgfältig ausgewähl |---|---|---| | Personalisierte SSH-Accounts | Offen | Umstellung oder vollständige Sitzungsprotokollierung | | MFA auf privilegierten Zugängen | **Umgesetzt** (Juni 2026) | Halbjährliche Rezertifizierung | +| Multi-Session + Silent Refresh | **Umgesetzt** (Juni 2026) | Parallele Sessions erlaubt; automatische Token-Erneuerung | +| Trusted Device (MFA-Skip 60d) | **Umgesetzt** (Juni 2026) | NIST-konform; Admin-Revoke jederzeit moeglich | +| Admin Session-Verwaltung | **Umgesetzt** (Juni 2026) | Sessions/Trusted Devices pro User einsehbar und widerrufbar | | Halbjährliche Rezertifizierung | Neu | Erstdurchführung terminieren | diff --git a/e-compliance/ims/05_betrieb/security-overview.md b/e-compliance/ims/05_betrieb/security-overview.md index c220d00..7ff2987 100644 --- a/e-compliance/ims/05_betrieb/security-overview.md +++ b/e-compliance/ims/05_betrieb/security-overview.md @@ -1,6 +1,6 @@ # PowerOn Plattform -- Sicherheit und Compliance -**Stand:** Februar 2026 +**Stand:** Juni 2026 **Zielgruppe:** Entscheidungsträger, Einkauf, Rechtsabteilung, Datenschutzbeauftragte **Klassifizierung:** Kundeninformation @@ -302,7 +302,7 @@ Die Plattform adressiert die häufigsten Web-Sicherheitsrisiken gemäss OWASP: | Cryptographic Failures | AES-Verschlüsselung, PBKDF2-Schlüsselableitung, HTTPS/TLS | | Injection | Parametrisierte Datenbankabfragen, Eingabebereinigung, SQL-Leseeinschränkung | | Security Misconfiguration | CORS-Einschränkungen, Rate Limiting, CSRF-Schutz | -| Identification and Authentication Failures | JWT-basierte Authentifizierung, Token-Widerruf, Ratenbegrenzung bei Anmeldung | +| Identification and Authentication Failures | JWT + serverseitige Token-Registry, MFA (TOTP), Trusted Device, Silent Refresh, Session-Revocation durch Admin, Ratenbegrenzung bei Anmeldung | Es besteht **keine formale OWASP-Zertifizierung**. Die Massnahmen basieren auf den OWASP-Empfehlungen und sind als präventive Sicherheitsmassnahmen implementiert. @@ -327,13 +327,39 @@ PowerOn unterstützt mehrere Authentifizierungsverfahren: ### 10.2 Sitzungssicherheit - Authentifizierungstoken werden in sicheren, HTTP-only Cookies gespeichert (nicht im Browser-Speicher zugänglich) -- Tokens haben eine konfigurierbare Gültigkeitsdauer -- Token-Widerruf ist jederzeit möglich (z.B. bei Verdacht auf Kompromittierung) -- Bei lokaler Anmeldung wird die Gültigkeit des Tokens zusätzlich gegen die Datenbank geprüft +- Tokens haben eine konfigurierbare Gültigkeitsdauer (Access: 300 Min, Refresh: 7 Tage) +- Token-Widerruf ist jederzeit möglich (z.B. bei Verdacht auf Kompromittierung) -- Administratoren können einzelne oder alle Sessions eines Nutzers sofort beenden +- Jede Anmeldung wird serverseitig in einer Token-Registry (PostgreSQL) registriert; nur dort vorhandene Token werden akzeptiert -### 10.3 Automatische Token-Erneuerung +### 10.3 Parallele Sitzungen (Multi-Session) -Authentifizierungstoken werden automatisch erneuert, bevor sie ablaufen. Dies gewährleistet eine unterbrechungsfreie Nutzung bei gleichzeitiger Begrenzung der Token-Gültigkeitsdauer. +Nutzer können auf mehreren Geräten und Browsern gleichzeitig angemeldet sein -- analog zu Microsoft 365 und Google Workspace. Eine neue Anmeldung invalidiert bestehende Sitzungen nicht. Dies ist konform mit NIST SP 800-63B (Section 7.1) und ermöglicht die branchenübliche parallele Nutzung (z.B. Desktop + Mobilgerät). + +Die Sicherheit wird gewährleistet durch: +- Serverseitige Session-Registry mit individueller Revocation +- Admin-Zugang zur aktiven-Sitzungs-Übersicht mit Widerrufsmöglichkeit +- Automatische Bereinigung abgelaufener Sitzungen + +### 10.4 Automatische Token-Erneuerung (Silent Refresh) + +Access-Tokens werden automatisch erneuert, bevor der Nutzer zum erneuten Login gezwungen wird. Der Refresh-Token (7 Tage Gültigkeit) ermöglicht eine unterbrechungsfreie Nutzung. Erst wenn auch der Refresh-Token abgelaufen ist, muss sich der Nutzer erneut anmelden. + +### 10.5 Multi-Faktor-Authentifizierung (MFA) + +PowerOn unterstützt TOTP-basierte MFA (Authenticator-App). MFA wird verlangt, wenn: +- Der Mandant `mfaRequired=True` konfiguriert hat, oder +- Der Nutzer MFA aktiviert hat (Opt-in), oder +- Der Nutzer ein Admin ist und `MFA_REQUIRE_ADMINS` aktiv ist + +### 10.6 Vertrauenswürdige Geräte (Trusted Device) + +Nach erfolgreicher MFA-Verifizierung kann ein Gerät für 60 Tage als vertrauenswürdig markiert werden. Innerhalb dieses Zeitraums entfällt die MFA-Abfrage auf diesem Gerät. Dies entspricht dem Microsoft-Standard ("Don't ask again for 60 days") und ist konform mit NIST SP 800-63B Section 5.2.8. + +Sicherheitsgrenzen: +- Vertrauensdauer ist zeitlich begrenzt und konfigurierbar +- Administrator oder Nutzer können vertrauenswürdige Geräte jederzeit widerrufen +- Bei Passwortänderung werden alle vertrauenswürdigen Geräte automatisch invalidiert +- Das Vertrauens-Cookie ist httpOnly und nicht programmatisch auslesbar ---