# 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, Schnell-Statuswechsel und einem vollständigen 8-Section-Schema (Migration 030: 62 DB-Spalten). **Route:** `/sdk/dsfa` | **Backend:** `backend-compliance:8002` | **Migrationen:** `024`, `028`, `030` --- ## Ü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 - **8-Section-Formular:** Vollständiges Schema für alle DSFA-Phasen (Sections 0–8) - **Status-Workflow:** `draft` → `in-review` → `approved` / `needs-update` - **Risikostufen:** `low` / `medium` / `high` / `critical` - **Datenkategorien, Empfänger, Schutzmaßnahmen:** JSONB-Arrays - **Risiken & Mitigationen:** Strukturierte JSONB-Arrays mit Risiko-IDs - **DSB-Konsultation:** `dpo_consulted`, `dpo_opinion`, `dpo_approved` - **Behörden-Konsultation:** `authority_consulted`, `authority_reference`, `authority_decision` - **WP248-Kriterien:** `wp248_criteria_met`, `threshold_analysis` - **Section-Progress:** `section_progress` JSONB für Fortschrittsanzeige - **KI-Anwendungsfälle (Section 8):** `ai_use_case_modules` JSONB mit AI-Act-Bewertung - **Bundesland-Kontext:** `federal_state`, `authority_resource_id` - **Schnell-Statuswechsel:** PATCH-Endpoint für Status-Übergang ohne vollständiges Update - **Genehmigungsdokumentation:** `approved_by` + `approved_at` bei Status `approved` - **Audit-Log:** Protokollierung aller Aktionen (CREATE / UPDATE / DELETE / STATUS_CHANGE) - **Statistiken:** Zähler nach Status und Risiko-Level --- ## 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 aktualisieren (alle Sections) | | `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 | Feld | Erlaubte Werte | |------|----------------| | `status` | `draft`, `in-review`, `approved`, `needs-update` | | `risk_level` | `low`, `medium`, `high`, `critical` | --- ## Datenmodell ### DSFA-Objekt (Response) — vollständig ```json { "id": "uuid", "tenant_id": "default", "title": "DSFA - Bewerber-Management-System", "description": "DSFA für KI-gestütztes Bewerber-Screening", "status": "in-review", "risk_level": "high", "processing_activity": "Automatisierte Bewertung von Bewerbungsunterlagen", "data_categories": ["Kontaktdaten", "Beruflicher Werdegang"], "recipients": ["HR-Abteilung"], "measures": ["Verschlüsselung", "Menschliche Prüfung"], "approved_by": null, "approved_at": null, "created_by": "admin", "created_at": "2026-03-05T10:00:00", "updated_at": "2026-03-05T10:00:00", "processing_description": "Automatisierte Vorauswahl von Bewerbungen mittels KI", "processing_purpose": "Effizienzsteigerung im Recruitingprozess", "legal_basis": "Art. 6 Abs. 1b DSGVO", "legal_basis_details": "Vertragsanbahnung auf Antrag der betroffenen Person", "necessity_assessment": "Die Verarbeitung ist für den Bewerbungsprozess notwendig", "proportionality_assessment": "Datenerhebung beschränkt auf Bewerbungsunterlagen", "data_minimization": "Nur für Auswahlentscheidung notwendige Daten", "alternatives_considered": "Manuelle Sichtung aller Bewerbungen nicht skalierbar", "retention_justification": "Löschung nach 6 Monaten gem. § 26 BDSG", "involves_ai": true, "overall_risk_level": "high", "risk_score": 7, "dpo_consulted": true, "dpo_consulted_at": "2026-03-01T09:00:00", "dpo_name": "Dr. Müller", "dpo_opinion": "DSFA erforderlich, Maßnahmen ausreichend", "dpo_approved": true, "authority_consulted": false, "authority_consulted_at": null, "authority_reference": null, "authority_decision": null, "version": 1, "previous_version_id": null, "conclusion": "DSFA abgeschlossen — verbleibendes Risiko akzeptabel", "federal_state": "Bayern", "authority_resource_id": "muss_liste_by", "submitted_for_review_at": "2026-03-04T14:00:00", "submitted_by": "admin", "data_subjects": ["Bewerber"], "affected_rights": ["Recht auf Information", "Widerspruchsrecht"], "triggered_rule_codes": ["R-ADM", "R-PROF"], "ai_trigger_ids": ["ai_adm_scoring"], "wp248_criteria_met": ["K1", "K2", "K8"], "art35_abs3_triggered": ["Art35Abs3a"], "tom_references": ["TOM-ENC-01", "TOM-ACC-03"], "risks": [ { "id": "R1", "title": "Diskriminierung durch KI-Entscheidung", "likelihood": "medium", "impact": "high", "residual_risk": "medium" } ], "mitigations": [ { "id": "M1", "measure": "Menschliche Endentscheidung bei allen Ablehnungen", "risk_ref": "R1", "implemented": true } ], "stakeholder_consultations": [], "review_triggers": [ {"trigger": "model_update", "description": "Bei Modell-Update", "monitoring_interval": "quarterly"} ], "review_comments": [], "ai_use_case_modules": [], "section_8_complete": false, "threshold_analysis": { "wp248_criteria_count": 3, "dsfa_required": true, "justification": "≥2 WP248-Kriterien erfüllt" }, "consultation_requirement": { "required": false, "reason": "Risiko durch Maßnahmen ausreichend reduziert" }, "review_schedule": { "next_review": "2027-03-01", "frequency": "annual", "responsible": "DSB" }, "section_progress": { "section_0": true, "section_1": true, "section_2": true, "section_3": true, "section_4": false, "section_5": false, "section_6": true, "section_7": false, "section_8": false }, "metadata": {} } ``` ### Minimaler Create-Request (POST) ```json { "title": "DSFA - Video-Überwachung Büro", "status": "draft", "risk_level": "medium", "processing_activity": "Videoüberwachung zu Sicherheitszwecken", "data_categories": ["Bilddaten", "Bewegungsdaten"], "created_by": "admin" } ``` ### Section-Update (PUT /{id}) Alle Felder sind optional — es werden nur gesendete Felder aktualisiert: ```json { "processing_description": "Verarbeitung von Kundendaten zur Risikoanalyse", "legal_basis": "Art. 6 Abs. 1f DSGVO", "dpo_consulted": true, "dpo_name": "Dr. Müller", "risks": [ {"id": "R1", "title": "Datenpanne", "likelihood": "low", "impact": "high"} ], "section_progress": {"section_1": true, "section_6": true} } ``` ### Status-Update (PATCH /{id}/status) ```json { "status": "approved", "approved_by": "DSB Müller" } ``` --- ## 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 ``` --- ## DB-Tabellen | Tabelle | Migration | Beschreibung | |---------|-----------|--------------| | `compliance_dsfas` | 024, 028, 030 | DSFA-Datensätze (62 Spalten) | | `compliance_dsfa_audit_log` | 024 | Audit-Trail aller Aktionen | ### Migrations-Übersicht | Migration | Inhalt | |-----------|--------| | `024_dsfa.sql` | Basistabelle: 15 Kernfelder, Audit-Log-Tabelle | | `028_dsfa_ai_use_cases.sql` | `ai_use_case_modules` JSONB, `section_8_complete` | | `030_dsfa_full_schema.sql` | +45 Felder: alle Sections 1–7, JSONB-Arrays, Versionierung | ### Schema: compliance_dsfas (Stand Migration 030) ```sql -- Basisfelder (Migration 024) id, tenant_id, title, description, status, risk_level, processing_activity, data_categories, recipients, measures, approved_by, approved_at, created_by, created_at, updated_at -- Section 1 (Migration 030) processing_description, processing_purpose, legal_basis, legal_basis_details -- Section 2 (Migration 030) necessity_assessment, proportionality_assessment, data_minimization, alternatives_considered, retention_justification -- Section 3 (Migration 030) involves_ai, overall_risk_level, risk_score -- Section 6 (Migration 030) dpo_consulted, dpo_consulted_at, dpo_name, dpo_opinion, dpo_approved, authority_consulted, authority_consulted_at, authority_reference, authority_decision -- Versionierung & Metadaten (Migration 030) version, previous_version_id, conclusion, federal_state, authority_resource_id, submitted_for_review_at, submitted_by -- JSONB Arrays (Migration 030) data_subjects, affected_rights, triggered_rule_codes, ai_trigger_ids, wp248_criteria_met, art35_abs3_triggered, tom_references, risks, mitigations, stakeholder_consultations, review_triggers, review_comments -- JSONB Objekte (Migration 030) threshold_analysis, consultation_requirement, review_schedule, section_progress, metadata -- Section 8 / KI (Migration 028) ai_use_case_modules, section_8_complete ``` --- ## Datei-Übersicht | Datei | Beschreibung | |-------|--------------| | `backend-compliance/migrations/024_dsfa.sql` | Basistabelle + Audit-Log | | `backend-compliance/migrations/028_dsfa_ai_use_cases.sql` | Section-8-Felder | | `backend-compliance/migrations/030_dsfa_full_schema.sql` | Vollständiges Schema (+45 Spalten) | | `backend-compliance/compliance/api/dsfa_routes.py` | FastAPI-Router (8 Endpoints, 60+ Felder) | | `admin-compliance/app/api/sdk/v1/dsfa/[[...path]]/route.ts` | Next.js Proxy | | `admin-compliance/app/(sdk)/sdk/dsfa/[id]/page.tsx` | 8-Section-Editor | | `backend-compliance/tests/test_dsfa_routes.py` | 101 Unit-Tests | --- ## Tests ```bash # DSFA-Tests (101 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 ``` **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 | | `TestDSFARouterConfig` | 3 | Prefix, Tags, Registrierung | | `TestDSFAStatsResponse` | 5 | Felder, Typen, Zähler | | `TestAuditLogEntry` | 4 | Schema, Null-Felder | | `TestAIUseCaseModules` | 22 | Section 8: KI-Module, Art22, AI-Act-Klassen | | `TestDSFAFullSchema` | 27 | Migration-030-Felder, Pydantic + Response | --- ## 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 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 | Anforderungen | |--------|---------------| | `unacceptable` | VERBOTEN (Art. 5 AI Act) | | `high_risk` | Strenge Auflagen: Art. 9–15 AI Act | | `limited` | Transparenzpflicht Art. 52 AI Act | | `minimal` | 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"], "involves_special_categories": false, "data_subjects": ["Kunden"], "processing_purpose": "Automatisierte Beantwortung von Kundenanfragen", "legal_basis": "Art. 6 Abs. 1b DSGVO", "art22_assessment": { "applies": false, "safeguards": [] }, "risk_criteria": [ { "id": "adm_profiling", "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" } ] } ] ``` --- ## RAG-Corpus bp_dsfa_corpus DSFA-spezifische Rechtsdokumente aller 16 Bundesländer + BfDI sind im Corpus `bp_dsfa_corpus` indexiert. ### Ingest-Script ```bash # Vollständiger Ingest inkl. PDF-Downloads (auf Mac Mini) ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh" # Nur Text-Dokumente, ohne PDF-Download-Versuch ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh --only-text" # Ohne erneute Downloads (bereits heruntergeladene PDFs nutzen) ssh macmini "~/Projekte/breakpilot-compliance/scripts/ingest-dsfa-bundesland.sh --skip-download" ``` **Ablauf des Scripts:** 1. Text-Zusammenfassungen erstellen (immer, als Fallback) 2. PDFs von 16 direkten Behörden-URLs herunterladen (curl, max. 30s/URL) 3. Für jeden Ingest: PDF bevorzugen → Text-Fallback wenn PDF fehlt/fehlgeschlagen 4. Verifikation: Testsuche im Corpus **Behörden mit direkten PDF-URLs (10 von 17):** | Key | Behörde | Dokument | |-----|---------|----------| | `bfdi_public` | BfDI Bund | Art.-35-Verarbeitungsliste | | `bw_privat` | LfDI BW | Nicht-öffentlicher Bereich | | `be_public` / `be_privat` | BlnBDI | Öffentlich + Nicht-öffentlich | | `bb_public` / `bb_privat` | LDA Brandenburg | Beide Bereiche | | `hb_public` / `hb_privat` | LfDI Bremen | Beide Bereiche | | `hh_public` / `hh_privat` | HmbBfDI | Beide Bereiche | | `mv_public` | LfDI MV | Öffentlicher Bereich | | `ni_public` / `ni_privat` | LfD Niedersachsen | Beide Bereiche | | `sl_privat` | UfD Saarland | Nicht-öffentlicher Bereich | | `st_public` / `st_privat` | LfD Sachsen-Anhalt | Beide Bereiche | **Behörden mit Text-Zusammenfassungen** (BY, NW, HE, RP, SN, SH, TH + WP248): Generiert aus DSK-Positionspapieren und öffentlichen Orientierungshilfen. ### Bundesland-Behörden (vollständig) | 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}' ```