Files
aza/AzA march 2026/security/handovers/STEP_9_BACKUP_RECOVERY.md
2026-03-25 22:03:39 +01:00

234 lines
7.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# STEP 9 Backup, Recovery & Löschkonzept
## Ziel
Sicherstellung von Datenverlustminimierung, Wiederherstellbarkeit
und Erfüllung der DSG-Löschpflichten.
---
## 1. Datenübersicht
### 1.1 Medizinische / Personenbezogene Daten
| Datei / Speicher | Format | Inhalt | Sensibilität |
|---|---|---|---|
| `kg_diktat_user_profile.json` | JSON | Arztname, Fachgebiet, Passwort-Hash, TOTP-Secret | HOCH |
| `kg_diktat_ablage/KG/` | Dateien | Krankengeschichten | HOCH |
| `kg_diktat_ablage/Briefe/` | Dateien | Arztbriefe | HOCH |
| `kg_diktat_ablage/Rezepte/` | Dateien | Rezepte | HOCH |
| `kg_diktat_ablage/Kostengutsprachen/` | Dateien | Kostengutsprachen | HOCH |
| `kg_diktat_ablage/Diktat/` | Dateien | Diktattexte | HOCH |
| `kg_diktat_notes.json` | JSON | Notizen (ev. Patientenbezug) | MITTEL |
| `kg_diktat_todos.json` | JSON | Aufgaben (ev. Patientenbezug) | MITTEL |
| `kg_diktat_todo_inbox.json` | JSON | Eingehende Aufgaben | MITTEL |
| `kg_diktat_medwork_contacts.json` | JSON | Praxiskontakte | MITTEL |
| `aza_email_contacts.json` | JSON | E-Mail-Kontakte | MITTEL |
| `aza_medwork_messages.json` | JSON | Nachrichten | MITTEL |
| `workforce_planner.db` | SQLite | Mitarbeiter, Abwesenheiten, Audit-Log | MITTEL |
### 1.2 Konfigurationsdaten (nicht personenbezogen)
| Datei | Inhalt |
|---|---|
| `kg_diktat_config.txt` | Grundeinstellungen |
| `kg_diktat_signature.txt` | Arzt-Signatur |
| `kg_diktat_korrekturen.json` | Auto-Korrekturen |
| `kg_diktat_textbloecke.json` | Textbausteine |
| `kg_diktat_autotext.json` | Autotext-Vorlagen |
| `kg_diktat_soap_presets.json` | SOAP-Profile |
| `kg_diktat_brief_presets.json` | Brief-Profile |
| `aza_email_config.json` | E-Mail-Konfiguration (ohne Passwort) |
| Diverse `*_window.txt` | Fensterpositionen / UI-State |
### 1.3 Cloud-Daten
| Dienst | Daten | Speicherort |
|---|---|---|
| Supabase | Synchronisierte Praxisdaten | AWS eu-central-1 |
| OpenAI API | Keine persistente Speicherung (API-Modus, max. 30 Tage) | USA |
---
## 2. Backup-Konzept
### 2.1 Implementierung
Neues Skript: **`aza_backup.py`**
```
python aza_backup.py backup # Backup erstellen
python aza_backup.py list # Backups auflisten
python aza_backup.py verify <f> # Integrität prüfen
python aza_backup.py restore <f> # Wiederherstellen
python aza_backup.py cleanup # Alte Backups entfernen
```
### 2.2 Was wird gesichert
- Alle medizinischen JSON-Dateien (17 Dateien)
- Alle Konfigurationsdateien (12 Dateien)
- Alle UI-State-Dateien (11 Dateien)
- Komplettes Ablage-Verzeichnis (KG, Briefe, Rezepte, etc.)
- Lernmodus-Export
- Workforce-Planner-Datenbank (SQLite)
### 2.3 Backup-Parameter
| Parameter | Wert | Konfiguration |
|---|---|---|
| Format | ZIP (Deflate, Level 9) | Fest |
| Intervall | Täglich empfohlen | Manuell oder Cron/Task Scheduler |
| Aufbewahrung | 90 Tage (Standard) | `AZA_BACKUP_KEEP_DAYS` |
| Zielverzeichnis | `./backups/` | `AZA_BACKUP_DIR` |
| Integrität | SHA-256 pro Datei + Manifest | Automatisch |
| Benennung | `aza_backup_YYYY-MM-DD_HH-MM-SS.zip` | Automatisch |
### 2.4 Verschlüsselung
- **Transport:** ZIP-Dateien können auf verschlüsseltem Medium gespeichert werden
- **Empfehlung:** Backup-Zielverzeichnis auf BitLocker-verschlüsseltem
Laufwerk oder verschlüsseltem NAS ablegen
- **ZIP-eigene Verschlüsselung:** Nicht implementiert (Python-zipfile
unterstützt kein starkes AES; Laufwerksverschlüsselung wird empfohlen)
### 2.5 Offsite-Kopie
- Backup-Verzeichnis (`AZA_BACKUP_DIR`) kann auf externes Medium
oder Netzlaufwerk zeigen
- Empfohlen: Regelmässige Kopie auf externes verschlüsseltes Medium
- Keine automatische Cloud-Sicherung implementiert
### 2.6 Automatisierung (Windows Task Scheduler)
```
schtasks /create /tn "AZA_Backup" /tr "python C:\...\aza_backup.py backup" /sc daily /st 22:00
```
---
## 3. Recovery-Konzept
### 3.1 Recovery Point Objective (RPO)
| Szenario | RPO |
|---|---|
| Tägliches Backup | Max. 24 Stunden Datenverlust |
| Stündliches Backup (optional) | Max. 1 Stunde |
### 3.2 Recovery Time Objective (RTO)
| Szenario | RTO |
|---|---|
| Einzelne Datei | < 5 Minuten |
| Komplettes System | < 30 Minuten |
### 3.3 Restore-Anleitung
#### Schritt 1: Verfügbare Backups anzeigen
```
python aza_backup.py list
```
#### Schritt 2: Backup-Integrität prüfen
```
python aza_backup.py verify backups/aza_backup_YYYY-MM-DD_HH-MM-SS.zip
```
#### Schritt 3: Dry-Run (was wird wiederhergestellt?)
```
python aza_backup.py restore backups/aza_backup_YYYY-MM-DD_HH-MM-SS.zip --dry-run
```
#### Schritt 4: Tatsächliche Wiederherstellung
```
python aza_backup.py restore backups/aza_backup_YYYY-MM-DD_HH-MM-SS.zip
```
**Sicherheitsmechanismus:** Vor dem Restore wird automatisch eine
Pre-Restore-Sicherung der aktuellen Daten erstellt (in `backups/.pre_restore_*/`),
sodass der Restore rückgängig gemacht werden kann.
### 3.4 Test-Ergebnisse (22.02.2026)
| Test | Ergebnis |
|---|---|
| Backup erstellen | PASS 44 Dateien, 0.06 MB |
| Backup verifizieren (SHA-256) | PASS alle Checksummen korrekt |
| Restore Dry-Run | PASS 44 Dateien korrekt aufgelistet |
| Backup auflisten | PASS Datum, Grösse, Name korrekt |
| Löschung Dry-Run | PASS Warnung zu Backups korrekt |
---
## 4. Löschkonzept
### 4.1 Löschfristen
| Datenkategorie | Aufbewahrungsfrist | Rechtsgrundlage |
|---|---|---|
| Krankengeschichten | 1020 Jahre (kantonal) | Kantonale Gesundheitsgesetze |
| Arztbriefe | 1020 Jahre | Kantonale Gesundheitsgesetze |
| Rezepte | 10 Jahre | OR Art. 958f |
| Mitarbeiterdaten | Anstellungsdauer + 5 Jahre | OR Art. 128 |
| E-Mail-Kontakte | Bis Löschung durch Benutzer | DSG Art. 6 |
| Backups | 90 Tage (konfigurierbar) | Intern |
### 4.2 Technische Umsetzung
#### Automatische Backup-Bereinigung
```
python aza_backup.py cleanup
```
Entfernt Backups älter als `AZA_BACKUP_KEEP_DAYS` (Standard: 90 Tage).
#### Patientendaten löschen (Recht auf Vergessenwerden)
```
# Dry-Run (nur prüfen, was gelöscht wird)
python aza_backup.py delete-patient "Nachname Vorname"
# Tatsächliche Löschung
python aza_backup.py delete-patient "Nachname Vorname" --execute
```
### 4.3 Lösch-Workflow
1. **Antrag:** Patient stellt Löschanfrage (schriftlich empfohlen)
2. **Prüfung:** Arzt prüft, ob gesetzliche Aufbewahrungspflicht besteht
3. **Dry-Run:** `delete-patient --dry-run` zeigt betroffene Dateien
4. **Dokumentation:** Löschanfrage und Ergebnis im Audit-Log festhalten
5. **Ausführung:** `delete-patient --execute`
6. **Backups:** Bestehende Backups enthalten noch Daten nach Ablauf
der Aufbewahrungsfrist (90 Tage) werden diese automatisch entfernt
7. **Cloud:** Supabase-Daten manuell löschen (aktuell kein API-Endpunkt)
### 4.4 Einschränkungen
- Löschung in bestehenden Backups nur durch Warten auf Ablauf
oder manuelles Löschen der betroffenen Backups
- Supabase-Cloud-Daten müssen manuell gelöscht werden
- OpenAI-API-Daten werden gemäss OpenAI nach max. 30 Tagen gelöscht
- Namensbasierte Suche funktioniert nur bei Dateinamen / JSON-Inhalt
mit Patientenname
---
## 5. Geänderte / Neue Dateien
| Datei | Aktion |
|---|---|
| `aza_backup.py` | NEU Backup, Verify, Restore, Cleanup, Löschung |
| `backups/` | NEU Backup-Verzeichnis (automatisch erstellt) |
---
## 6. Risiken
| Risiko | Bewertung | Massnahme |
|---|---|---|
| Kein automatischer Backup-Schedule | MITTEL | Task Scheduler einrichten |
| ZIP nicht AES-verschlüsselt | MITTEL | Laufwerksverschlüsselung nutzen |
| Keine Offsite-Kopie konfiguriert | HOCH | `AZA_BACKUP_DIR` auf NAS setzen |
| Supabase-Löschung manuell | MITTEL | API-Endpunkt implementieren |
| Namensbasierte Löschung unvollständig | NIEDRIG | Erweiterte Suche implementieren |
| Kein inkrementelles Backup | NIEDRIG | Bei Datenwachstum nachrüsten |