# DSFA — Datenschutz-Folgenabschätzung (Art. 35 DSGVO) Das DSFA-Modul implementiert die Datenschutz-Folgenabschätzung gemäß Art. 35 DSGVO. Es ist vollständig backend-persistent mit CRUD-Operationen, Audit-Log und Schnell-Statuswechsel. **Route:** `/sdk/dsfa` | **Backend:** `backend-compliance:8002` | **Migration:** `024_dsfa.sql` --- ## Übersicht | Checkpoint | Reviewer | Rechtsgrundlage | Status | |-----------|----------|-----------------|--------| | CP-DSFA (REQUIRED) | DSB | Art. 35 DSGVO | ✅ 100% | **Wann ist eine DSFA Pflicht?** Eine Datenschutz-Folgenabschätzung ist nach Art. 35 Abs. 1 DSGVO zwingend erforderlich, wenn eine Verarbeitungstätigkeit voraussichtlich ein **hohes Risiko** für die Rechte und Freiheiten natürlicher Personen mit sich bringt. Typische Fälle: - Automatisierte Entscheidungen / Profiling (Art. 35 Abs. 3a) - Umfangreiche Verarbeitung besonderer Kategorien (Art. 9/10 DSGVO) - Systematische Überwachung öffentlicher Bereiche (Art. 35 Abs. 3c) - KI-basierte Systeme im Hochrisiko-Bereich (EU AI Act) --- ## Funktionen - **CRUD-Operationen:** Anlegen, Lesen, Aktualisieren, Löschen von DSFA-Datensätzen - **Status-Workflow:** `draft` → `in-review` → `approved` / `needs-update` - **Risikostufen:** `low` / `medium` / `high` / `critical` - **Datenkategorien:** Mehrfachauswahl der verarbeiteten Datenkategorien (JSONB) - **Empfänger:** Dokumentation der Datenempfänger (JSONB) - **Schutzmaßnahmen:** Erfassung technischer und organisatorischer Maßnahmen (JSONB) - **Schnell-Statuswechsel:** PATCH-Endpoint für Status-Übergang ohne vollständiges Update - **Genehmigungsdokumentation:** `approved_by` + `approved_at` bei Status `approved` - **Audit-Log:** Nachvollziehbare Protokollierung aller Aktionen (CREATE / UPDATE / DELETE / STATUS_CHANGE) - **Statistiken:** Zähler nach Status und Risiko-Level - **Filter:** Liste filterbar nach `status`, `risk_level` - **Löschung:** DSGVO-Art.-17-konforme Löschung inkl. Audit-Log-Eintrag --- ## API-Endpoints | Methode | Pfad | Beschreibung | |---------|------|--------------| | `GET` | `/api/v1/dsfa` | Liste (Filter: tenant_id, status, risk_level, skip, limit) | | `POST` | `/api/v1/dsfa` | Neue DSFA anlegen → HTTP 201 | | `GET` | `/api/v1/dsfa/stats` | Statistiken nach Status und Risiko | | `GET` | `/api/v1/dsfa/audit-log` | Audit-Trail (limit, offset) | | `GET` | `/api/v1/dsfa/{id}` | Einzelne DSFA abrufen | | `PUT` | `/api/v1/dsfa/{id}` | DSFA vollständig aktualisieren | | `DELETE` | `/api/v1/dsfa/{id}` | DSFA löschen (Art. 17 DSGVO) | | `PATCH` | `/api/v1/dsfa/{id}/status` | Schnell-Statuswechsel | !!! info "Proxy-Route (Frontend)" Das Admin-Frontend ruft die Endpoints über den Next.js-Proxy auf: `/api/sdk/v1/dsfa/**` → `backend-compliance:8002/api/v1/dsfa/**` ### Query-Parameter (GET /api/v1/dsfa) | Parameter | Typ | Default | Beschreibung | |-----------|-----|---------|--------------| | `tenant_id` | string | `default` | Mandanten-ID | | `status` | string | — | Filter: draft, in-review, approved, needs-update | | `risk_level` | string | — | Filter: low, medium, high, critical | | `skip` | integer | 0 | Offset für Pagination | | `limit` | integer | 100 | Max. Einträge (max. 500) | ### Validierung Folgende Felder werden gegen erlaubte Werte geprüft (HTTP 422 bei Verstoß): | Feld | Erlaubte Werte | |------|----------------| | `status` | `draft`, `in-review`, `approved`, `needs-update` | | `risk_level` | `low`, `medium`, `high`, `critical` | --- ## Datenmodell ### DSFA-Objekt (Response) ```json { "id": "uuid", "tenant_id": "default", "title": "DSFA - Bewerber-Management-System", "description": "Datenschutz-Folgenabschätzung für KI-gestütztes Bewerber-Screening", "status": "in-review", "risk_level": "high", "processing_activity": "Automatisierte Bewertung von Bewerbungsunterlagen", "data_categories": ["Kontaktdaten", "Beruflicher Werdegang", "Qualifikationen"], "recipients": ["HR-Abteilung", "Fachabteilungen"], "measures": ["Verschlüsselung", "Zugriffskontrolle", "Menschliche Prüfung"], "approved_by": null, "approved_at": null, "created_by": "system", "created_at": "2026-03-04T10:00:00", "updated_at": "2026-03-04T10:00:00" } ``` ### Create-Request (POST) ```json { "title": "DSFA - Video-Überwachung Büro", "description": "Datenschutz-Folgenabschätzung für Videoüberwachung", "status": "draft", "risk_level": "medium", "processing_activity": "Videoüberwachung zu Sicherheitszwecken", "data_categories": ["Bilddaten", "Bewegungsdaten"], "recipients": ["Sicherheitsdienst"], "measures": ["Löschfristen", "Zugangsbeschränkung", "Hinweisschilder"], "created_by": "admin" } ``` ### Status-Update-Request (PATCH /{id}/status) ```json { "status": "approved", "approved_by": "DSB Müller" } ``` ### Stats-Response (GET /stats) ```json { "total": 5, "by_status": { "draft": 2, "in-review": 1, "approved": 2 }, "by_risk_level": { "low": 1, "medium": 2, "high": 2 }, "draft_count": 2, "in_review_count": 1, "approved_count": 2, "needs_update_count": 0 } ``` --- ## Status-Workflow ```mermaid stateDiagram-v2 [*] --> draft: Neu anlegen draft --> in-review: Zur Prüfung einreichen in-review --> approved: Genehmigen (approved_by pflichtend) in-review --> needs-update: Überarbeitung erforderlich needs-update --> in-review: Erneut einreichen approved --> needs-update: Erneut prüfen ``` Der Statuswechsel kann über den `PATCH /{id}/status`-Endpoint vorgenommen werden. Bei Status `approved` wird `approved_at` automatisch auf den aktuellen Zeitstempel gesetzt. --- ## DB-Tabellen | Tabelle | Modus | Migration | Beschreibung | |---------|-------|-----------|--------------| | `compliance_dsfas` | read/write | 024_dsfa.sql | DSFA-Datensätze mit JSONB-Feldern | | `compliance_dsfa_audit_log` | write | 024_dsfa.sql | Audit-Trail aller Aktionen | ### Schema: compliance_dsfas ```sql CREATE TABLE compliance_dsfas ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), tenant_id VARCHAR(255) NOT NULL, title VARCHAR(500) NOT NULL, description TEXT DEFAULT '', status VARCHAR(50) NOT NULL DEFAULT 'draft', risk_level VARCHAR(50) NOT NULL DEFAULT 'low', processing_activity VARCHAR(500) DEFAULT '', data_categories JSONB DEFAULT '[]', recipients JSONB DEFAULT '[]', measures JSONB DEFAULT '[]', approved_by VARCHAR(255), approved_at TIMESTAMPTZ, created_by VARCHAR(255) DEFAULT 'system', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); ``` --- ## Datei-Übersicht | Datei | Beschreibung | |-------|--------------| | `backend-compliance/migrations/024_dsfa.sql` | DB-Migration | | `backend-compliance/compliance/api/dsfa_routes.py` | FastAPI-Router (8 Endpoints) | | `admin-compliance/app/api/sdk/v1/dsfa/[[...path]]/route.ts` | Next.js Proxy | | `admin-compliance/app/sdk/dsfa/page.tsx` | Frontend (vollständig API-verdrahtet) | | `backend-compliance/tests/test_dsfa_routes.py` | 52 Unit-Tests | --- ## Tests ```bash # DSFA-Tests (52 Tests) cd backend-compliance && python3 -m pytest tests/test_dsfa_routes.py -v # Vollständiger Lauf python3 -m pytest tests/ -v --ignore=tests/test_company_profile_routes.py # → 680 Tests, alle grün ``` **Test-Klassen:** | Klasse | Tests | Thema | |--------|-------|-------| | `TestDSFACreate` | 6 | Schema-Defaults, Pflichtfelder, Arrays | | `TestDSFAUpdate` | 5 | Partial update, exclude_none | | `TestDSFAStatusUpdate` | 4 | Status + approved_by | | `TestGetTenantId` | 4 | Tenant-ID Fallback | | `TestDsfaToResponse` | 9 | Helper: null-safety, JSONB, ISO-Datum | | `TestValidStatusValues` | 6 | Erlaubte/verbotene Status-Werte | | `TestValidRiskLevels` | 6 | Erlaubte/verbotene Risiko-Stufen | | `TestDSFAStatsResponse` | 5 | Felder, Typen, Zähler | | `TestAuditLogEntry` | 4 | Schema, Null-Felder | | `TestDSFARouterConfig` | 3 | Prefix, Tags, Registrierung | --- ## Compliance-Kontext Die DSFA ist ein **REQUIRED**-Modul (Checkpoint CP-DSFA) — Bestandteil der Dokumentationsphase zusammen mit VVT (CP-VVT), Löschfristen (CP-LOSCH) und Einwilligungen (CP-CONS). Eine abgeschlossene DSFA liefert Evidence für: - **TOM-Modul:** Schutzmaßnahmen aus DSFA.measures → TOM-Einträge - **Audit Checklist:** DSFA-Abschluss ist Prüfpunkt im Audit - **Obligations:** Verpflichtung zur DSFA nach Art. 35 DSGVO - **VVT:** `dpia_required`-Flag in Verarbeitungstätigkeiten verweist auf DSFA-Einträge ```mermaid graph LR VVT["VVT (Art. 30)"] -->|dpia_required| DSFA["DSFA (Art. 35)"] DSFA --> TOM["TOM (Art. 32)"] DSFA --> Audit["Audit Checklist"] DSFA --> Obligation["Obligations"] ``` --- ## Section 8: KI-Anwendungsfälle Section 8 ist ein optionaler modularer Anhang zur DSFA für KI-spezifische Verarbeitungen. Jedes KI-System erhält ein eigenes Modul mit 7 Tabs. ### KI-Modul-Typen | Typ | Icon | Typische Risiken | |-----|------|-----------------| | `chatbot_nlp` | 💬 | Datenpersistenz, Fehlinformation | | `recommendation` | 🎯 | Profiling, Verhaltensmanipulation | | `adm_scoring` | ⚖️ | Art. 22 DSGVO, Diskriminierung | | `video_image` | 📹 | Systematische Überwachung | | `biometrics` | 👁️ | Art. 9 DSGVO, Unwiderruflichkeit | | `iot_sensors` | 📡 | Lückenlose Überwachung | | `generative_ai` | 🤖 | Halluzinationen, Datenleckage | | `custom` | ⚙️ | Variabel | ### Art. 22 DSGVO Assessment Für ADM/Scoring-Module wird automatisch ein Art.-22-Panel eingeblendet: - Toggle: Automatisierte Entscheidung mit Rechtswirkung? - Ausnahmetatbestand (Art. 22 Abs. 2 lit. a/b/c) - Schutzmaßnahmen-Checklist (Menschliche Überprüfung Pflicht!) ### AI Act Risikoklassen | Klasse | Label | Anforderungen | |--------|-------|---------------| | `unacceptable` | Unannehmbares Risiko | VERBOTEN | | `high_risk` | Hochrisiko | Art. 9-15 AI Act | | `limited` | Begrenztes Risiko | Transparenz Art. 52 AI Act | | `minimal` | Minimales Risiko | Keine spezifischen AI-Act-Anforderungen | ### `ai_use_case_modules` JSONB-Schema ```json [ { "id": "uuid", "use_case_type": "generative_ai", "name": "GPT-Assistent Kundenservice", "model_description": "LLM-basierter Chatbot mit RAG...", "model_type": "GPT-4o", "provider": "OpenAI", "third_country_transfer": true, "provider_country": "USA", "input_data_categories": ["Anfragetexte", "Kundennummer"], "output_data_categories": ["Antworttext", "Intent-Klassifikation"], "involves_special_categories": false, "data_subjects": ["Kunden", "Interessenten"], "processing_purpose": "Automatisierte Beantwortung von Kundenanfragen", "legal_basis": "Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung)", "art22_assessment": { "applies": false, "safeguards": [] }, "risk_criteria": [ { "id": "adm_profiling", "applies": false, "severity": "high" }, { "id": "systematic_monitoring", "applies": false, "severity": "high" } ], "ai_act_risk_class": "limited", "ai_act_justification": "Chatbot mit Transparenzpflicht nach Art. 52 AI Act", "risks": [], "mitigations": [], "privacy_by_design_measures": [ { "category": "data_minimisation", "description": "Nur notwendige Daten", "implemented": true } ], "review_triggers": [ { "type": "model_update", "description": "Modell-Update", "monitoring_interval": "monatlich" } ] } ] ``` ### Migration ```bash # Migration 028 ausführen (auf Mac Mini) ssh macmini "/usr/local/bin/docker exec bp-compliance-backend python3 -c \" import sys; sys.path.insert(0, '/app') from compliance.database import engine from sqlalchemy import text sql = ''' ALTER TABLE compliance.compliance_dsfas ADD COLUMN IF NOT EXISTS ai_use_case_modules JSONB DEFAULT '[]'::jsonb, ADD COLUMN IF NOT EXISTS section_8_complete BOOLEAN DEFAULT FALSE; ''' with engine.connect() as conn: conn.execute(text(sql)) conn.commit() print('Migration 028 OK') \"" ``` --- ## RAG-Corpus bp_dsfa_corpus DSFA-spezifische Rechtsdokumente sind im Corpus `bp_dsfa_corpus` indexiert. ### Ingest-Script ```bash # Auf Mac Mini ausführen ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh" # Nur Text-Dokumente (ohne Download) ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh --only-text" ``` ### Bundesland-Behörden (16 Bundesländer + BfDI) | ID | Bundesland | Behörde | |----|-----------|---------| | `bfdi` | Bund | Bundesbeauftragte für den Datenschutz (BfDI) | | `bw` | Baden-Württemberg | LfDI BW | | `by` | Bayern | LDA Bayern | | `be` | Berlin | BlnBDI | | `bb` | Brandenburg | LDA Brandenburg | | `hb` | Bremen | LfDI Bremen | | `hh` | Hamburg | HmbBfDI | | `he` | Hessen | HBDI | | `mv` | Mecklenburg-Vorpommern | LfDI MV | | `ni` | Niedersachsen | LfD Niedersachsen | | `nw` | Nordrhein-Westfalen | LDI NRW | | `rp` | Rheinland-Pfalz | LfDI RLP | | `sl` | Saarland | UfD Saarland | | `sn` | Sachsen | SDTB | | `st` | Sachsen-Anhalt | LfD Sachsen-Anhalt | | `sh` | Schleswig-Holstein | ULD | | `th` | Thüringen | TLfDI | ### Suche im Corpus ```bash curl -sk -X POST 'https://localhost:8097/api/v1/search' \ -H 'Content-Type: application/json' \ -d '{"query":"DSFA Muss-Liste NRW","collection":"bp_dsfa_corpus","limit":5}' ```