Skip to content

Compliance & Audit

Cortina ist als technische Schutzmaßnahme im Sinne von DSGVO Art. 32 gebaut: Pseudonymisierung als ein klares, reproduzierbares Verfahren, das harte Garantien gibt — die im Code verdrahtet sind, nicht nur in einer Policy stehen.

Art. 32 verlangt „geeignete technische und organisatorische Maßnahmen” zur Sicherheit der Verarbeitung; Pseudonymisierung wird dort explizit als Beispiel genannt. Cortina implementiert Pseudonymisierung als reversible Mapping-Operation mit zwei harten Eigenschaften:

  1. Das Mapping verlässt nie die EU. Redis läuft auf Hetzner Falkenstein; Postgres auch.
  2. Das Mapping verlässt nie Redis. Originaltext landet nicht in Postgres, nicht in Audit-Logs, nicht in Logs zur Fehlersuche.

Cortina schreibt zu jedem Anonymize-Call einen Audit-Log-Eintrag. Der Eintrag enthält bewusst keinen Originaltext und keine Pseudonyme.

Was geschrieben wird:

FeldBeispielZweck
request_id01HZA… (UUIDv7)Korrelation mit Logs
tenant_idUUIDv5 deterministisch aus Tenant-NamePer-Tenant-Aggregationen
api_key_id(DB-Key-ID, nicht der Plaintext)Audit pro Key
client_ip_hashSHA256 der Client-IP mit API_KEY_SALTRate-Limit-Forensik ohne IP-Speicherung
endpoint/v1/anonymize
entities_count{"DE_IBAN": 1, "PERSON": 2}Aggregat — keine Werte
stages_filter[1, 2] oder nullWelcher ?stages=-Filter wirkte
audit_flags["context_llm_unavailable"]Welche degradierten Pfade liefen
re_id_score0.08 (nur intern, nicht in Public-API)Stage-4-Calibration
llm_token_counts{"stage3_in": 412, "stage3_out": 120, …}Cost-Tracking
created_atUTC

Was niemals geschrieben wird:

  • Originaltext — weder direkt noch fragmentiert.
  • Pseudonyme oder ihre Mappings.
  • LLM-Prompts oder LLM-Responses (auch nicht hashed).
  • Rohe IP-Adressen.

Diese Regel ist im Code als Schema-Constraint im audit_log-Payload-Builder verdrahtet, nicht nur Policy.

TUP AI GbR ist Auftragsverarbeiter im Sinne von Art. 28 DSGVO. Auf Anfrage stellen wir den AVV bereit. Sub-Prozessoren mit Region:

RolleAnbieterRegion
Hosting (Compute, DB, Cache)Hetzner Online GmbHFalkenstein / Helsinki
Stage-3 LLMAWS Bedrock (Claude family)eu-central-1 Frankfurt
Stage-4 LLMGoogle Cloud Vertex AI (Gemini family)europe-west3 Frankfurt

Die LLM-Aufrufe sind die einzigen Daten-Transfers außerhalb der reinen TUP-Infrastruktur. Beide Endpoints sind regional gepinnt; AWS verwendet für Bedrock in eu-central-1 ein regional inference profile, das das Routing auf EU-Endpoints beschränkt — Cross-Region-Routing ist nicht aktiv.

Alle Komponenten (FastAPI, Postgres, Redis) laufen in Deutschland (Hetzner Falkenstein); Backup-Replikate liegen in Helsinki (Hetzner Finland), das innerhalb der EU als gleichwertige Hosting-Region zählt.

Es gibt keine US-Datenflüsse außer den zwei oben genannten LLM-Calls, die ihrerseits an EU-pinnte Endpoints gehen. CDN, Static Assets, Logs, Metriken — alles EU.

Ein nicht-leeres audit_flags-Array in der Anonymize-Response ist ein Signal an den Caller, dass die Pipeline degradiert lief. Konkret:

FlagWas es bedeutet
context_llm_disabledStage 3 ist per Config aus. Keine Art.-9-Coverage.
context_llm_unavailableStage 3 wollte laufen, Provider war down. Keine Art.-9-Coverage.
adversarial_unavailableStage 4 down — Re-ID-Score nicht gegeben.
adversarial_invalid_outputStage 4 LLM hat zweimal nicht parsebare JSON geliefert.
re_id_risk_remainingStage 4 lief, ε wurde nicht erreicht. Output bleibt mit Restrisiko.
re_id_oscillationStage 3 ↔ 4 sind sich uneinig. Pipeline-Instabilität, ops-relevant.

Caller, die eine harte Garantie brauchen, sollten jedes nicht-leere audit_flags-Array als „degradierte Antwort” behandeln und die Anfrage entweder neu schicken oder den Output zusätzlich manuell prüfen.

Wenn Stage 3 deaktiviert ist (context_llm_disabled / context_llm_unavailable), fängt die Pipeline keine Nationalitäten, Religionen oder Veranstaltungsbezüge ab. Das ist eine bewusst doku- mentierte Lücke — wir advertisen die Pipeline ohne Stage 3 explizit nicht als Art.-9-vollständig. Telemetriegestützte Phase-3.1- Recognizer (deterministisch für eine geschlossene Demonym-Liste) sind Backlog.