4.6 KiB
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:
- SysAdmin → Zugriff
ui.system.complianceAuditUI-Objekt mitview-Berechtigung → Zugriff- 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.