Healthcare PHI/PII Compliance Patterns
Patterns zum Schutz von Patientendaten, klinischen Daten und Finanzdaten in Gesundheitsanwendungen. Anwendbar auf HIPAA (USA), DISHA (Indien), DSGVO (EU) und allgemeinen Datenschutz im Gesundheitswesen.
Wann verwenden
- Beim Erstellen einer Funktion, die Patientenakten berührt
- Bei der Implementierung von Zugriffskontrolle oder Authentifizierung für klinische Systeme
- Beim Entwerfen von Datenbankschemata für Gesundheitsdaten
- Beim Erstellen von APIs, die Patienten- oder klinische Daten zurückgeben
- Bei der Implementierung von Audit-Trails oder Protokollierung
- Beim Überprüfen von Code auf Datenexpositionsschwachstellen
- Beim Einrichten von Row-Level Security (RLS) für Multi-Tenant-Gesundheitssysteme
Wie es funktioniert
Der Datenschutz im Gesundheitswesen arbeitet auf drei Ebenen: Klassifikation (was ist sensibel), Zugriffskontrolle (wer kann es sehen) und Audit (wer hat es gesehen).
Datenklassifikation
PHI (Protected Health Information) — alle Daten, die einen Patienten identifizieren können UND sich auf seine Gesundheit beziehen: Patientenname, Geburtsdatum, Adresse, Telefon, E-Mail, nationale ID-Nummern (SSN, Aadhaar, NHS-Nummer), Krankenaktennummern, Diagnosen, Medikamente, Laborergebnisse, Bildgebung, Versicherungspolicen- und Schadensdetails, Termin- und Aufnahmerekorde oder jede Kombination der genannten.
PII (Nicht-patientenbezogene sensible Daten) in Gesundheitssystemen: persönliche Details von Klinikern/Personal, Arzt-Honorarstrukturen und Auszahlungsbeträge, Mitarbeitergehälter und Bankdaten, Zahlungsinformationen von Lieferanten.
Zugriffskontrolle: Row-Level Security
ALTER TABLE patients ENABLE ROW LEVEL SECURITY;
-- Zugriff auf Einrichtung beschränken
CREATE POLICY "staff_read_own_facility"
ON patients FOR SELECT TO authenticated
USING (facility_id IN (
SELECT facility_id FROM staff_assignments
WHERE user_id = auth.uid() AND role IN ('doctor','nurse','lab_tech','admin')
));
-- Audit-Log: Nur-Einfügen (manipulationssicher)
CREATE POLICY "audit_insert_only" ON audit_log FOR INSERT
TO authenticated WITH CHECK (user_id = auth.uid());
CREATE POLICY "audit_no_modify" ON audit_log FOR UPDATE USING (false);
CREATE POLICY "audit_no_delete" ON audit_log FOR DELETE USING (false);
Audit-Trail
Jeder PHI-Zugriff oder jede PHI-Änderung muss protokolliert werden:
interface AuditEntry {
timestamp: string;
user_id: string;
patient_id: string;
action: 'create' | 'read' | 'update' | 'delete' | 'print' | 'export';
resource_type: string;
resource_id: string;
changes?: { before: object; after: object };
ip_address: string;
session_id: string;
}
Häufige Leckvektoren
Fehlermeldungen: Niemals patientenidentifizierende Daten in Fehlermeldungen einbeziehen, die an den Client gesendet werden. Details nur serverseitig protokollieren.
Konsolenausgabe: Niemals vollständige Patientenobjekte protokollieren. Undurchsichtige interne Datensatz-IDs (UUIDs) verwenden – keine medizinischen Aktennummern, nationalen IDs oder Namen.
URL-Parameter: Niemals patientenidentifizierende Daten in Query-Strings oder Pfadsegmenten platzieren, die in Logs oder dem Browserverlauf auftauchen könnten. Nur undurchsichtige UUIDs verwenden.
Browser-Speicher: Niemals PHI in localStorage oder sessionStorage speichern. PHI nur im Arbeitsspeicher halten, bei Bedarf abrufen.
Service-Rollen-Schlüssel: Niemals den service_role-Schlüssel im clientseitigen Code verwenden. Immer den anon/publishable Schlüssel verwenden und RLS den Zugriff erzwingen lassen.
Logs und Überwachung: Niemals vollständige Patientenakten protokollieren. Nur undurchsichtige Datensatz-IDs verwenden (keine medizinischen Aktennummern). Stack-Traces bereinigen, bevor sie an Fehlerverfolgungsdienste gesendet werden.
Datenbank-Schema-Kennzeichnung
PHI/PII-Spalten auf Schemaebene markieren:
COMMENT ON COLUMN patients.name IS 'PHI: patienten_name';
COMMENT ON COLUMN patients.dob IS 'PHI: geburtsdatum';
COMMENT ON COLUMN patients.aadhaar IS 'PHI: national_id';
COMMENT ON COLUMN doctor_payouts.amount IS 'PII: finanziell';
Bereitstellungs-Checkliste
Vor jeder Bereitstellung:
- Kein PHI in Fehlermeldungen oder Stack-Traces
- Kein PHI in console.log/console.error
- Kein PHI in URL-Parametern
- Kein PHI im Browser-Speicher
- Kein service_role-Schlüssel im Client-Code
- RLS auf allen PHI/PII-Tabellen aktiviert
- Audit-Trail für alle Datenänderungen
- Sitzungstimeout konfiguriert
- API-Authentifizierung an allen PHI-Endpunkten
- Datenisolation zwischen Einrichtungen verifiziert
Beispiele
Beispiel 1: Sichere vs. unsichere Fehlerbehandlung
// SCHLECHT – gibt PHI im Fehler preis
throw new Error(`Patient ${patient.name} nicht in ${patient.facility} gefunden`);
// GUT – generischer Fehler, Details serverseitig mit undurchsichtigen IDs protokolliert
logger.error('Patientensuche fehlgeschlagen', { recordId: patient.id, facilityId });
throw new Error('Datensatz nicht gefunden');
Beispiel 2: RLS-Richtlinie für Multi-Facility-Isolation
-- Arzt in Einrichtung A kann keine Patienten von Einrichtung B sehen
CREATE POLICY "facility_isolation"
ON patients FOR SELECT TO authenticated
USING (facility_id IN (
SELECT facility_id FROM staff_assignments WHERE user_id = auth.uid()
));
-- Test: als arzt-einrichtung-a anmelden, Patienten von Einrichtung b abfragen
-- Erwartet: 0 Zeilen zurückgegeben
Beispiel 3: Sicheres Logging
// SCHLECHT – protokolliert identifizierbare Patientendaten
console.log('Verarbeite Patient:', patient);
// GUT – protokolliert nur undurchsichtige interne Datensatz-ID
console.log('Verarbeite Datensatz:', patient.id);
// Hinweis: selbst patient.id sollte eine undurchsichtige UUID sein, keine medizinische Aktennummer