112 lines
4.6 KiB
Markdown
112 lines
4.6 KiB
Markdown
<!-- status: canonical -->
|
|
<!-- lastReviewed: 2026-04-14 -->
|
|
|
|
# Compliance & AI-Audit
|
|
|
|
## Überblick
|
|
|
|
PORTA protokolliert jeden AI-Provider-Call in einem dedizierten **AI-Audit-Log**. Parallel existiert das bestehende **Security/GDPR-Audit-Log** für Zugriffs- und Sicherheitsereignisse. Beide Logs sind über die Compliance-Seite im Frontend einsehbar.
|
|
|
|
## Architektur
|
|
|
|
```
|
|
AI-Pipeline (mainServiceAi._createBillingCallback)
|
|
│
|
|
├──> serviceBilling.recordUsage() (Abrechnung)
|
|
└──> aiAuditLogger.logAiCall() (Compliance-Log)
|
|
│
|
|
└──> DB: poweron_app / Tabelle AiAuditLogEntry
|
|
```
|
|
|
|
## Backend-Komponenten
|
|
|
|
| Datei | Funktion |
|
|
|-------|----------|
|
|
| `modules/datamodels/datamodelAiAudit.py` | Pydantic-Model `AiAuditLogEntry` mit `@i18nModel` |
|
|
| `modules/shared/aiAuditLogger.py` | Singleton `aiAuditLogger` — schreibt und liest AI-Audit-Einträge |
|
|
| `modules/routes/routeAudit.py` | 4 API-Endpoints unter `/api/audit/` |
|
|
| `modules/shared/auditLogger.py` | Bestehendes Security/GDPR-Audit-Log (`AuditLogEntry`) |
|
|
|
|
### Datenmodell: AiAuditLogEntry
|
|
|
|
Kernfelder:
|
|
|
|
- **Kontext:** `userId`, `username`, `mandateId`, `featureInstanceId`, `featureCode`, `instanceLabel`
|
|
- **AI-Call:** `aiProvider`, `aiModel`, `operationType`, `tokensInput`, `tokensOutput`, `processingTimeMs`, `priceCHF`
|
|
- **Neutralisierung:** `neutralizationActive`, `neutralizationMappingsCount`
|
|
- **Content:** `contentStored`, `contentInputHash` (SHA-256), `contentInputPreview` / `contentOutputPreview` (200 Zeichen), `contentInputFull` / `contentOutputFull` (nur bei Mandant opt-in)
|
|
- **Status:** `success`, `errorMessage`
|
|
|
|
### AI-Audit-Logger API
|
|
|
|
| Methode | Beschreibung |
|
|
|---------|-------------|
|
|
| `logAiCall(userId, mandateId, aiProvider, aiModel, ...)` | Schreibt einen Eintrag |
|
|
| `getAiAuditLogs(mandateId, *, userId, featureInstanceId, ...)` | Paginierte Abfrage mit Filtern |
|
|
| `getAiAuditEntryContent(entryId, mandateId)` | Vollständiger Content eines Eintrags |
|
|
| `getAiAuditStats(mandateId, *, timeRangeDays, groupBy)` | Aggregierte Statistiken |
|
|
|
|
### Pipeline-Integration
|
|
|
|
In `mainServiceAi.py` wird der `_createBillingCallback` nach jedem erfolgreichen oder fehlerhaften AI-Call aufgerufen. Neben dem Billing-Eintrag schreibt er einen AI-Audit-Eintrag. Der Audit-Call ist in `try/except` gewrappt — Fehler im Audit-Logger brechen den AI-Call nicht ab.
|
|
|
|
## API-Endpoints
|
|
|
|
| Endpoint | Tab | Query-Parameter |
|
|
|----------|-----|-----------------|
|
|
| `GET /api/audit/ai-log` | A: AI-Datenfluss | `userId`, `featureInstanceId`, `aiModel`, `dateFrom`, `dateTo`, `limit`, `offset` |
|
|
| `GET /api/audit/ai-log/{entryId}/content` | A: Detail | — |
|
|
| `GET /api/audit/log` | B: Security/GDPR | `userId`, `category`, `action`, `dateFrom`, `dateTo`, `limit` |
|
|
| `GET /api/audit/stats` | C: Statistiken | `timeRange` (Tage), `groupBy` |
|
|
|
|
### RBAC
|
|
|
|
Alle Endpoints prüfen über `_requireAuditAccess`:
|
|
1. SysAdmin → Zugriff
|
|
2. `ui.system.complianceAudit` UI-Objekt mit `view`-Berechtigung → Zugriff
|
|
3. Sonst → HTTP 403
|
|
|
|
## Frontend
|
|
|
|
| Datei | Funktion |
|
|
|-------|----------|
|
|
| `pages/ComplianceAuditPage.tsx` | Hauptseite mit 3 Tabs |
|
|
| `pages/ComplianceAuditPage.module.css` | Styling (Dark-Mode via CSS-Variablen) |
|
|
| `config/pageRegistry.tsx` | Icon `FaShieldAlt` für `page.system.complianceAudit` |
|
|
| `App.tsx` | Route `/compliance-audit` |
|
|
|
|
### Tab A: AI-Datenfluss-Log
|
|
|
|
Tabelle mit Zeitpunkt, Benutzer, Feature, AI-Modell (Badge), Typ, Tokens (↑/↓), Kosten, Neutralisierung, Status. Pagination in 50er-Schritten.
|
|
|
|
### Tab B: Audit-Log
|
|
|
|
Tabelle mit Zeitpunkt, Benutzer, Kategorie (farbcodiert nach Typ), Aktion, Ressource, Details, Erfolg/Fehler, IP-Adresse.
|
|
|
|
### Tab C: Statistiken
|
|
|
|
Zeitraum-Selektor (7/30/90 Tage), KPI-Karten (Total Calls, Neutralisierungsquote, Modelle, Kosten), Charts via recharts (Line, Pie, Bar).
|
|
|
|
## Navigation
|
|
|
|
"Compliance & Audit" ist in der neuen Subgroup **"Übersichten"** unter "Meine Sicht" angeordnet, zusammen mit "Integrationen":
|
|
|
|
```
|
|
Meine Sicht
|
|
├── Übersicht (Home)
|
|
├── Übersichten
|
|
│ ├── Integrationen
|
|
│ └── Compliance & Audit ← neu
|
|
├── Basisdaten
|
|
│ ├── Verbindungen
|
|
│ ├── Dateien
|
|
│ └── Prompts
|
|
└── Nutzung
|
|
├── Abrechnung
|
|
├── Statistiken
|
|
└── ...
|
|
```
|
|
|
|
## Content-Speicherung (Opt-in)
|
|
|
|
Full-Content-Speicherung (Prompt + Response) ist im Datenmodell vorbereitet (`contentInputFull`, `contentOutputFull`, `contentStored`), aber standardmässig deaktiviert. Nur Metadaten + Previews (200 Zeichen) werden gespeichert. Die Aktivierung pro Mandant ist für eine spätere Phase vorgesehen.
|