wiki/b-reference/platform/audit.md
ValueOn AG 788b63907a upd
2026-04-14 10:27:48 +02:00

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.