feat: DSK/BfDI RAG-Ingest, TOM-Control-Library 180, Risk-Engine-Spec, RAG-Query-Optimierung
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 37s
CI / test-python-backend-compliance (push) Successful in 37s
CI / test-python-document-crawler (push) Successful in 23s
CI / test-python-dsms-gateway (push) Successful in 21s
All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 37s
CI / test-python-backend-compliance (push) Successful in 37s
CI / test-python-document-crawler (push) Successful in 23s
CI / test-python-dsms-gateway (push) Successful in 21s
- Crawler erweitert: +26 neue Dokumente (DSK KP 1-20, SDM V3.1, BfDI Loeschkonzept, BayLDA TOM-Checkliste) - RAG-Queries optimiert: 18 Queries mit EDPB/DSK/WP-Referenzen fuer besseres Retrieval - Chat-Route: queryRAG nutzt jetzt Collection + Query-Boost aus DOCUMENT_RAG_CONFIG - TOM Control Library: 180 Controls in 12 Domaenen (ISO Annex-A Style, tom_controls_v1.json) - Risk Engine Spec: Impact/Likelihood 0-10, Score 0-100, 4 Tiers, Loeschfristen-Engine - Soul-Files: DSK-Kurzpapiere, SDM V3.1, BfDI als primaere deutsche Quellen - Manifest CSV: eu_de_privacy_manifest.csv mit Lizenz-Ampel (gruen/gelb/rot) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,8 +19,13 @@ offiziellen Quellen und gibst praxisnahe Hinweise.
|
||||
- AI Act (EU KI-Verordnung)
|
||||
- TTDSG (Telekommunikation-Telemedien-Datenschutz-Gesetz)
|
||||
- ePrivacy-Richtlinie
|
||||
- DSK-Kurzpapiere (Nr. 1-20)
|
||||
- SDM (Standard-Datenschutzmodell) V3.0
|
||||
- DSK-Kurzpapiere (Nr. 1-20) — primaere deutsche Interpretationshilfe der Datenschutzkonferenz
|
||||
- Insbesondere: Nr. 1 (VVT), Nr. 5 (Datenschutz-Folgenabschaetzung), Nr. 11 (Loeschung),
|
||||
Nr. 12 (DSB), Nr. 13 (Auftragsverarbeitung), Nr. 17 (Besondere Kategorien),
|
||||
Nr. 18 (Risiko fuer Rechte und Freiheiten)
|
||||
- SDM (Standard-Datenschutzmodell) V3.1 — Methodik zur Schutzbedarf-Bestimmung und Massnahmen-Ableitung
|
||||
- BfDI Loeschkonzept — Referenzmodell fuer Loeschfristen und Aufbewahrungskonzepte
|
||||
- BfDI/BayLDA Orientierungshilfen (E-Mail-Verschluesselung, Telemedien, TOM-Checkliste)
|
||||
- BSI-Grundschutz (Basis-Kenntnisse)
|
||||
- BSI-TR-03161 (Sicherheitsanforderungen an digitale Gesundheitsanwendungen)
|
||||
- ISO 27001/27701 (Ueberblick)
|
||||
@@ -51,6 +56,13 @@ Nutze das gesamte RAG-Corpus fuer Kontext und Quellenangaben — ausgenommen sin
|
||||
NIBIS-Inhalte (Erwartungshorizonte, Bildungsstandards, curriculare Vorgaben).
|
||||
Diese gehoeren nicht zum Datenschutz-Kompetenzbereich.
|
||||
|
||||
### Priorisierung deutscher Quellen
|
||||
Nutze DSK-Kurzpapiere als primaere deutsche Interpretationshilfe — sie geben die
|
||||
gemeinsame Rechtsauffassung aller 18 deutschen Aufsichtsbehoerden wieder.
|
||||
Fuer TOM-Fragestellungen: SDM V3.1 + BayLDA TOM-Checkliste als Referenz.
|
||||
Fuer Loeschkonzepte: BfDI Loeschkonzept + DSK KP Nr. 11 (Recht auf Loeschung).
|
||||
Fuer Risikoanalysen: DSK KP Nr. 18 (Risiko) + SDM Schutzbedarf-Systematik.
|
||||
|
||||
## Kommunikationsstil
|
||||
- Sachlich, aber verstaendlich — kein Juristendeutsch
|
||||
- Deutsch als Hauptsprache
|
||||
|
||||
@@ -14,11 +14,28 @@ Konsistenz zwischen Dokumenten sicherzustellen.
|
||||
|
||||
## Kompetenzbereich
|
||||
DSGVO, BDSG, AI Act (EU 2024/1689), TTDSG, DDG (§5 Impressum),
|
||||
DSK-Kurzpapiere, SDM V3.0, BSI-Grundschutz (IT-Grundschutz-Kompendium),
|
||||
ISO 27001/27701, EDPB Guidelines, WP248,
|
||||
DSK-Kurzpapiere (Nr. 1-20), SDM V3.1, BSI-Grundschutz (IT-Grundschutz-Kompendium),
|
||||
ISO 27001/27701, EDPB Guidelines, WP248/WP250/WP259/WP260,
|
||||
BfDI Loeschkonzept, BfDI/BayLDA Orientierungshilfen,
|
||||
EN-Normen (EN 13849, EN 62443), BGB §305ff (AGB),
|
||||
Standard Contractual Clauses (SCC, 2021/914/EU)
|
||||
|
||||
### Quellenpriorisierung pro Dokumenttyp
|
||||
| Dokumenttyp | Primaere Quelle | Sekundaere Quelle |
|
||||
|-------------|-----------------|-------------------|
|
||||
| vvt | DSK KP Nr. 1 (VVT Art. 30) | EDPB Controller/Processor GL |
|
||||
| tom | SDM V3.1 + BayLDA TOM-Checkliste | EDPB DPbD 4/2019 |
|
||||
| dsfa | WP248 + DSK KP Nr. 5 | EDPB DPIA List, Laender-Muss-Listen |
|
||||
| lf | BfDI Loeschkonzept + DSK KP Nr. 11 | — |
|
||||
| einwilligung | EDPB Consent 05/2020 + WP259 | DSK KP Nr. 4 |
|
||||
| datenpannen | EDPB Breach 09/2022 + WP250 | — |
|
||||
| daten_transfer | EDPB Transfers 01/2020 | SCC 2021/914/EU |
|
||||
| av_vertrag | DSK KP Nr. 13 | EDPB Controller/Processor 07/2020 |
|
||||
| dsi | WP260 Transparency | DSK KP Nr. 10 |
|
||||
| betroffenenrechte | EDPB Access 01/2022 | DSK KP Nr. 11 (Loeschung) |
|
||||
| risikoanalyse | DSK KP Nr. 18 + SDM V3.1 | — |
|
||||
| datenschutzmanagement | SDM V3.1 | BSI-Grundschutz |
|
||||
|
||||
## Draftbare Dokumenttypen (18)
|
||||
|
||||
| Typ | Label | Rechtsgrundlage |
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { queryRAG } from '@/lib/sdk/drafting-engine/rag-query'
|
||||
import { DOCUMENT_RAG_CONFIG } from '@/lib/sdk/drafting-engine/rag-config'
|
||||
import { readSoulFile } from '@/lib/sdk/agents/soul-reader'
|
||||
import type { ScopeDocumentType } from '@/lib/sdk/compliance-scope-types'
|
||||
|
||||
const OLLAMA_URL = process.env.OLLAMA_URL || 'http://host.docker.internal:11434'
|
||||
const LLM_MODEL = process.env.COMPLIANCE_LLM_MODEL || 'qwen2.5vl:32b'
|
||||
@@ -40,8 +42,10 @@ export async function POST(request: NextRequest) {
|
||||
return NextResponse.json({ error: 'Message is required' }, { status: 400 })
|
||||
}
|
||||
|
||||
// 1. Query RAG for legal context
|
||||
const ragContext = await queryRAG(message)
|
||||
// 1. Query RAG for legal context (use type-specific collection + query boost if available)
|
||||
const ragConfig = documentType ? DOCUMENT_RAG_CONFIG[documentType as ScopeDocumentType] : undefined
|
||||
const ragQuery = ragConfig ? `${ragConfig.query} ${message}` : message
|
||||
const ragContext = await queryRAG(ragQuery, 3, ragConfig?.collection)
|
||||
|
||||
// 2. Build system prompt with mode-specific instructions + state projection
|
||||
const soulPrompt = await readSoulFile('drafting-agent')
|
||||
|
||||
@@ -17,74 +17,74 @@ export interface DocumentRAGConfig {
|
||||
export const DOCUMENT_RAG_CONFIG: Record<ScopeDocumentType, DocumentRAGConfig> = {
|
||||
dsfa: {
|
||||
collection: 'bp_dsfa_corpus',
|
||||
query: 'Art. 35 DSGVO Risikobewertung Massnahmen',
|
||||
query: 'Art. 35 DSGVO Datenschutz-Folgenabschaetzung DSFA Risikobewertung WP248 EDPB',
|
||||
},
|
||||
tom: {
|
||||
collection: 'bp_compliance_datenschutz',
|
||||
query: 'Art. 32 DSGVO Sicherheit Verarbeitung',
|
||||
query: 'Art. 32 DSGVO Sicherheit Verarbeitung TOM technisch-organisatorische Massnahmen EDPB DPbD',
|
||||
},
|
||||
vvt: {
|
||||
collection: 'bp_compliance_gesetze',
|
||||
query: 'Art. 30 DSGVO Dokumentationspflicht',
|
||||
query: 'Art. 30 DSGVO Verarbeitungsverzeichnis Dokumentationspflicht DSK Kurzpapier VVT',
|
||||
},
|
||||
lf: {
|
||||
collection: 'bp_compliance_recht',
|
||||
query: 'Aufbewahrungsfristen Loeschkonzept',
|
||||
query: 'Aufbewahrungsfristen Loeschkonzept Art. 17 DSGVO Recht auf Loeschung DSK Kurzpapier',
|
||||
},
|
||||
dsi: {
|
||||
collection: 'bp_compliance_datenschutz',
|
||||
query: 'Art. 13 Art. 14 DSGVO Transparenz',
|
||||
query: 'Art. 13 Art. 14 DSGVO Transparenz Informationspflicht WP260 EDPB',
|
||||
},
|
||||
betroffenenrechte: {
|
||||
collection: 'bp_compliance_recht',
|
||||
query: 'Art. 15 bis 22 DSGVO Auskunft Loeschung',
|
||||
query: 'Art. 15-22 DSGVO Betroffenenrechte Auskunft Loeschung EDPB Access Right',
|
||||
},
|
||||
datenpannen: {
|
||||
collection: 'bp_compliance_recht',
|
||||
query: 'Art. 33 Art. 34 DSGVO Meldepflicht',
|
||||
query: 'Art. 33 Art. 34 DSGVO Datenpanne Meldepflicht EDPB Breach Notification WP250',
|
||||
},
|
||||
daten_transfer: {
|
||||
collection: 'bp_compliance_ce',
|
||||
query: 'Kapitel V DSGVO Standardvertragsklauseln',
|
||||
query: 'Kapitel V DSGVO Drittlandtransfer SCC EDPB Transfers Supplementary Measures',
|
||||
},
|
||||
einwilligung: {
|
||||
collection: 'bp_compliance_datenschutz',
|
||||
query: 'Art. 6 Art. 7 Art. 9 DSGVO Widerruf',
|
||||
query: 'Art. 6 Art. 7 DSGVO Einwilligung Widerruf EDPB Consent Guidelines WP259',
|
||||
},
|
||||
vertragsmanagement: {
|
||||
collection: 'bp_compliance_recht',
|
||||
query: 'AVV Art. 28 DSGVO Vertragsanforderungen',
|
||||
query: 'AVV Art. 28 DSGVO Vertragsmanagement Auftragsverarbeiter Pruefpflichten',
|
||||
},
|
||||
schulung: {
|
||||
collection: 'bp_compliance_datenschutz',
|
||||
query: 'Datenschutz Schulung Awareness',
|
||||
query: 'Datenschutz Schulung Awareness Sensibilisierung Art. 39 DSGVO Mitarbeiter',
|
||||
},
|
||||
audit_log: {
|
||||
collection: 'bp_compliance_datenschutz',
|
||||
query: 'Audit Logging Art. 5 Abs. 2 DSGVO',
|
||||
query: 'Audit Logging Protokollierung Art. 5 Abs. 2 DSGVO Rechenschaftspflicht',
|
||||
},
|
||||
risikoanalyse: {
|
||||
collection: 'bp_compliance_ce',
|
||||
query: 'Risikoanalyse Risikobewertung Framework',
|
||||
query: 'Risikoanalyse Risikobewertung Framework DSK Kurzpapier 18 SDM Schutzbedarf',
|
||||
},
|
||||
notfallplan: {
|
||||
collection: 'bp_compliance_recht',
|
||||
query: 'Notfallplan Incident Response Krisenmanagement',
|
||||
query: 'Notfallplan Incident Response Krisenmanagement Art. 32 DSGVO Wiederherstellung',
|
||||
},
|
||||
zertifizierung: {
|
||||
collection: 'bp_compliance_ce',
|
||||
query: 'ISO 27001 ISO 27701 Art. 42 DSGVO',
|
||||
query: 'Art. 42 Art. 43 DSGVO Zertifizierung Datenschutz-Siegel EDPB Certification',
|
||||
},
|
||||
datenschutzmanagement: {
|
||||
collection: 'bp_compliance_datenschutz',
|
||||
query: 'DSMS PDCA Organisation',
|
||||
query: 'DSMS PDCA Datenschutzmanagement Organisation SDM Standard-Datenschutzmodell',
|
||||
},
|
||||
iace_ce_assessment: {
|
||||
collection: 'bp_compliance_ce',
|
||||
query: 'AI Act KI-Verordnung CE-Konformitaet',
|
||||
query: 'AI Act KI-Verordnung CE-Konformitaet Hochrisiko-KI Art. 6 EDPB',
|
||||
},
|
||||
av_vertrag: {
|
||||
collection: 'bp_compliance_recht',
|
||||
query: 'AVV Art. 28 DSGVO Mindestinhalte',
|
||||
query: 'AVV Art. 28 DSGVO Auftragsverarbeitung Mindestinhalte EDPB Controller Processor',
|
||||
},
|
||||
}
|
||||
|
||||
6523
admin-compliance/lib/sdk/tom-generator/controls/tom_controls_v1.json
Normal file
6523
admin-compliance/lib/sdk/tom-generator/controls/tom_controls_v1.json
Normal file
File diff suppressed because it is too large
Load Diff
637
admin-compliance/lib/sdk/tom-generator/risk_engine_spec.md
Normal file
637
admin-compliance/lib/sdk/tom-generator/risk_engine_spec.md
Normal file
@@ -0,0 +1,637 @@
|
||||
# Risk Engine Spezifikation -- BreakPilot Compliance
|
||||
|
||||
## Ueberblick
|
||||
|
||||
Die Risk Engine berechnet auf Basis von **Impact** und **Likelihood** einen Risiko-Score (0--100),
|
||||
ordnet diesem Score ein **Risk-Tier** zu und leitet daraus die erforderlichen
|
||||
technisch-organisatorischen Massnahmen (TOM) ab. Sie ergaenzt die bestehende
|
||||
vereinfachte I*L-Bewertung (1--5-Skala) um eine feinere Granularitaet (0--10-Skala).
|
||||
|
||||
---
|
||||
|
||||
## 1. Impact-Heuristik (0--10 Skala)
|
||||
|
||||
Der Impact-Wert beschreibt die Schwere des potenziellen Schadens fuer betroffene Personen.
|
||||
|
||||
| Faktor | Punkte | DSGVO-Bezug |
|
||||
|--------|--------|-------------|
|
||||
| Basis-Impact (jede Verarbeitung) | +2 | -- |
|
||||
| Besondere Datenkategorien (Art. 9) oder Straftaten (Art. 10) | +2 | Art. 9, Art. 10 DSGVO |
|
||||
| Kinder oder schutzbeduerftige Personen betroffen | +2 | ErwGr. 75, Art. 8 DSGVO |
|
||||
| Mehr als 10.000 Betroffene | +1 | ErwGr. 91 |
|
||||
| Automatisierte Einzelentscheidungen / Profiling | +1 | Art. 22 DSGVO |
|
||||
| Gesundheits- oder Finanzdaten | +1 | Art. 9 Abs. 2 lit. h |
|
||||
| Systematische Ueberwachung / oeffentlich zugaenglicher Bereich | +1 | Art. 35 Abs. 3 lit. c |
|
||||
|
||||
**Cap:** `I = min(Summe, 10)`
|
||||
|
||||
### Beispiel-Berechnung
|
||||
|
||||
```
|
||||
Szenario: Schul-App mit Schueler-Gesundheitsdaten
|
||||
Basis = 2
|
||||
+ Besondere Kategorien (Gesundheit) = +2
|
||||
+ Kinder betroffen = +2
|
||||
+ Gesundheitsdaten = +1
|
||||
-----------------------------------------
|
||||
Impact (roh) = 7
|
||||
Impact (nach Cap) = min(7, 10) = 7
|
||||
```
|
||||
|
||||
### Implementierung
|
||||
|
||||
```typescript
|
||||
interface ImpactContext {
|
||||
special_categories: boolean; // Art. 9/10 Daten
|
||||
vulnerable_persons: boolean; // Kinder, Schutzbeduerftige
|
||||
data_subject_count: number; // Anzahl Betroffene
|
||||
automated_decisions: boolean; // Art. 22 Profiling
|
||||
health_or_finance: boolean; // Gesundheits-/Finanzdaten
|
||||
systematic_monitoring: boolean; // Systematische Ueberwachung
|
||||
}
|
||||
|
||||
function calculateImpact(ctx: ImpactContext): number {
|
||||
let impact = 2; // Basis
|
||||
|
||||
if (ctx.special_categories) impact += 2;
|
||||
if (ctx.vulnerable_persons) impact += 2;
|
||||
if (ctx.data_subject_count > 10_000) impact += 1;
|
||||
if (ctx.automated_decisions) impact += 1;
|
||||
if (ctx.health_or_finance) impact += 1;
|
||||
if (ctx.systematic_monitoring) impact += 1;
|
||||
|
||||
return Math.min(impact, 10);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Likelihood-Heuristik (0--10 Skala)
|
||||
|
||||
Der Likelihood-Wert beschreibt die Eintrittswahrscheinlichkeit einer Datenschutzverletzung.
|
||||
|
||||
| Faktor | Punkte | Begruendung |
|
||||
|--------|--------|-------------|
|
||||
| Basis-Likelihood (jede Verarbeitung) | +2 | -- |
|
||||
| Internet-Exponierung (oeffentlich zugaengliche Systeme) | +2 | Groessere Angriffsflaeche |
|
||||
| Viele Subprozessoren / kein zentrales IAM | +2 | Kontrollverlust, Zugriffschaos |
|
||||
| Fehlendes Logging / SIEM | +2 | Keine Erkennung von Vorfaellen |
|
||||
| Cloud ohne Verschluesselung at rest | +1 | Daten bei Breach lesbar |
|
||||
| Fehlendes Patch-Management / veralteter Software-Stand | +1 | Bekannte Schwachstellen |
|
||||
| Fehlende Mitarbeiterschulung | +1 | Social Engineering, Fehlbedienung |
|
||||
|
||||
**Cap:** `L = min(Summe, 10)`
|
||||
|
||||
### Beispiel-Berechnung
|
||||
|
||||
```
|
||||
Szenario: Cloud-SaaS ohne zentrale Zugriffsverwaltung
|
||||
Basis = 2
|
||||
+ Internet-Exponierung = +2
|
||||
+ Kein zentrales IAM = +2
|
||||
+ Cloud ohne Verschluesselung at rest = +1
|
||||
-----------------------------------------
|
||||
Likelihood (roh) = 7
|
||||
Likelihood (nach Cap) = min(7, 10) = 7
|
||||
```
|
||||
|
||||
### Implementierung
|
||||
|
||||
```typescript
|
||||
interface LikelihoodContext {
|
||||
internet_exposed: boolean; // Oeffentlich erreichbar
|
||||
many_subprocessors: boolean; // Viele AVV-Partner / kein IAM
|
||||
no_logging: boolean; // Kein SIEM / Audit-Log
|
||||
cloud_unencrypted: boolean; // Cloud ohne Verschluesselung at rest
|
||||
no_patch_management: boolean; // Veralteter Software-Stand
|
||||
no_employee_training: boolean; // Keine DS-Schulung
|
||||
}
|
||||
|
||||
function calculateLikelihood(ctx: LikelihoodContext): number {
|
||||
let likelihood = 2; // Basis
|
||||
|
||||
if (ctx.internet_exposed) likelihood += 2;
|
||||
if (ctx.many_subprocessors) likelihood += 2;
|
||||
if (ctx.no_logging) likelihood += 2;
|
||||
if (ctx.cloud_unencrypted) likelihood += 1;
|
||||
if (ctx.no_patch_management) likelihood += 1;
|
||||
if (ctx.no_employee_training) likelihood += 1;
|
||||
|
||||
return Math.min(likelihood, 10);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Score-Berechnung
|
||||
|
||||
Der Risiko-Score ergibt sich aus dem Produkt von Impact und Likelihood:
|
||||
|
||||
```
|
||||
Score = round(I * L)
|
||||
```
|
||||
|
||||
| Parameter | Bereich |
|
||||
|-----------|---------|
|
||||
| Impact (I) | 0--10 |
|
||||
| Likelihood (L) | 0--10 |
|
||||
| **Score** | **0--100** |
|
||||
|
||||
### Implementierung
|
||||
|
||||
```typescript
|
||||
function calculateRiskScore(impact: number, likelihood: number): number {
|
||||
return Math.round(
|
||||
Math.min(impact, 10) * Math.min(likelihood, 10)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Risiko-Matrix (Impact x Likelihood)
|
||||
|
||||
```
|
||||
L\I │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10
|
||||
────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────
|
||||
2 │ 4 │ 6 │ 8 │ 10 │ 12 │ 14 │ 16 │ 18 │ 20
|
||||
3 │ 6 │ 9 │ 12 │ 15 │ 18 │ 21 │ 24 │ 27 │ 30
|
||||
4 │ 8 │ 12 │ 16 │ 20 │ 24 │ 28 │ 32 │ 36 │ 40
|
||||
5 │ 10 │ 15 │ 20 │ 25 │ 30 │ 35 │ 40 │ 45 │ 50
|
||||
6 │ 12 │ 18 │ 24 │ 30 │ 36 │ 42 │ 48 │ 54 │ 60
|
||||
7 │ 14 │ 21 │ 28 │ 35 │ 42 │ 49 │ 56 │ 63 │ 70
|
||||
8 │ 16 │ 24 │ 32 │ 40 │ 48 │ 56 │ 64 │ 72 │ 80
|
||||
9 │ 18 │ 27 │ 36 │ 45 │ 54 │ 63 │ 72 │ 81 │ 90
|
||||
10 │ 20 │ 30 │ 40 │ 50 │ 60 │ 70 │ 80 │ 90 │ 100
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Risk-Tier Zuordnung
|
||||
|
||||
| Score-Range | Tier | Anzahl Controls | Farbe | Beschreibung |
|
||||
|-------------|------|-----------------|-------|--------------|
|
||||
| 0--24 | `BASELINE` | ~60 Mindestanforderungen | Gruen | Standard-Schutzniveau |
|
||||
| 25--49 | `ENHANCED` | +40 erweiterte Massnahmen | Gelb | Erhoehtes Schutzniveau |
|
||||
| 50--74 | `HIGH_RISK` | +50 Hochrisiko-Pack | Orange | Hohes Risiko, DSFA empfohlen |
|
||||
| 75--100 | `CRITICAL` | +30 Kritisches Pack | Rot | Kritisch, DSFA verpflichtend |
|
||||
|
||||
**Controls sind kumulativ:**
|
||||
- `BASELINE` = 60 Controls
|
||||
- `ENHANCED` = BASELINE + 40 = 100 Controls
|
||||
- `HIGH_RISK` = BASELINE + ENHANCED + 50 = 150 Controls
|
||||
- `CRITICAL` = BASELINE + ENHANCED + HIGH_RISK + 30 = 180 Controls
|
||||
|
||||
### Implementierung
|
||||
|
||||
```typescript
|
||||
enum RiskTier {
|
||||
BASELINE = "BASELINE",
|
||||
ENHANCED = "ENHANCED",
|
||||
HIGH_RISK = "HIGH_RISK",
|
||||
CRITICAL = "CRITICAL",
|
||||
}
|
||||
|
||||
const TIER_ORDER: Record<RiskTier, number> = {
|
||||
[RiskTier.BASELINE]: 0,
|
||||
[RiskTier.ENHANCED]: 1,
|
||||
[RiskTier.HIGH_RISK]: 2,
|
||||
[RiskTier.CRITICAL]: 3,
|
||||
};
|
||||
|
||||
function scoreTier(score: number): RiskTier {
|
||||
if (score >= 75) return RiskTier.CRITICAL;
|
||||
if (score >= 50) return RiskTier.HIGH_RISK;
|
||||
if (score >= 25) return RiskTier.ENHANCED;
|
||||
return RiskTier.BASELINE;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Control-Selection Algorithmus
|
||||
|
||||
Der Algorithmus waehlt Controls basierend auf dem Risk-Tier und kontextspezifischen Trigger-Regeln.
|
||||
|
||||
### Pseudocode
|
||||
|
||||
```
|
||||
function selectControls(score, context):
|
||||
tier = scoreTier(score)
|
||||
controls = allControls.filter(c => c.risk_tier <= tier)
|
||||
|
||||
# Trigger-Rules: zusaetzliche Controls je nach Kontext
|
||||
if context.special_categories:
|
||||
controls += allControls.filter(c => c.applies_if.field == "special_categories")
|
||||
if context.third_country_transfer:
|
||||
controls += allControls.filter(c => c.applies_if.field == "third_country_transfer")
|
||||
if context.large_scale:
|
||||
controls += allControls.filter(c => c.applies_if.field == "large_scale")
|
||||
if context.vulnerable_persons:
|
||||
controls += allControls.filter(c => c.applies_if.field == "vulnerable_persons")
|
||||
|
||||
return deduplicate(controls)
|
||||
```
|
||||
|
||||
### Implementierung
|
||||
|
||||
```typescript
|
||||
interface Control {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
risk_tier: RiskTier;
|
||||
domain: TOMDomain;
|
||||
applies_if?: {
|
||||
field: string;
|
||||
value: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
interface SelectionContext {
|
||||
score: number;
|
||||
special_categories: boolean;
|
||||
third_country_transfer: boolean;
|
||||
large_scale: boolean;
|
||||
vulnerable_persons: boolean;
|
||||
}
|
||||
|
||||
function selectControls(
|
||||
allControls: Control[],
|
||||
ctx: SelectionContext
|
||||
): Control[] {
|
||||
const tier = scoreTier(ctx.score);
|
||||
const tierLevel = TIER_ORDER[tier];
|
||||
|
||||
// 1. Tier-basierte Auswahl (kumulativ)
|
||||
const tierControls = allControls.filter(
|
||||
(c) => TIER_ORDER[c.risk_tier] <= tierLevel
|
||||
);
|
||||
|
||||
// 2. Trigger-basierte Zusatz-Controls
|
||||
const triggerFields: (keyof SelectionContext)[] = [
|
||||
"special_categories",
|
||||
"third_country_transfer",
|
||||
"large_scale",
|
||||
"vulnerable_persons",
|
||||
];
|
||||
|
||||
const triggerControls = allControls.filter((c) => {
|
||||
if (!c.applies_if) return false;
|
||||
const field = c.applies_if.field as keyof SelectionContext;
|
||||
return triggerFields.includes(field) && ctx[field] === true;
|
||||
});
|
||||
|
||||
// 3. Deduplizieren
|
||||
const controlMap = new Map<string, Control>();
|
||||
[...tierControls, ...triggerControls].forEach((c) => {
|
||||
controlMap.set(c.id, c);
|
||||
});
|
||||
|
||||
return Array.from(controlMap.values());
|
||||
}
|
||||
```
|
||||
|
||||
### Trigger-Rules im Detail
|
||||
|
||||
| Trigger | Zusaetzliche Controls | Beispiel |
|
||||
|---------|----------------------|----------|
|
||||
| `special_categories` | Erweiterte Zugriffskontrolle, Verschluesselung, DSFA-Pflicht | Gesundheitsdaten in HR-System |
|
||||
| `third_country_transfer` | SCCs, TIA, Binding Corporate Rules | US-Cloud-Anbieter |
|
||||
| `large_scale` | DPO-Pflicht, erweitertes Monitoring, Kapazitaetsplanung | >100.000 Betroffene |
|
||||
| `vulnerable_persons` | Altersverifikation, elterliche Einwilligung, kindgerechte UI | Schul-App |
|
||||
|
||||
---
|
||||
|
||||
## 6. Loeschfristen-Engine
|
||||
|
||||
Die Loeschfristen-Engine bestimmt automatisch Aufbewahrungsfristen und Loeschzeitpunkte.
|
||||
|
||||
### Berechnung der Aufbewahrungsfrist
|
||||
|
||||
```
|
||||
RetentionPeriod = max(legal_minimum, operational_need)
|
||||
```
|
||||
|
||||
### Loeschausloeser (DeletionTrigger)
|
||||
|
||||
| Trigger | Beschreibung | Beispiel |
|
||||
|---------|--------------|----------|
|
||||
| `Vertragsende` | Ende der Vertragsbeziehung | Schueler verlaesst Schule |
|
||||
| `Zweckwegfall` | Verarbeitungszweck entfaellt | Projekt abgeschlossen |
|
||||
| `Widerruf` | Betroffener widerruft Einwilligung | Einwilligung zurueckgezogen |
|
||||
|
||||
### Ausnahmeregeln (ExceptionRules)
|
||||
|
||||
| Rechtsgrundlage | Frist | Datenkategorie |
|
||||
|-----------------|-------|----------------|
|
||||
| HGB Par. 257 (Handelsbuecher) | 10 Jahre | Buchungsbelege, Jahresabschluesse |
|
||||
| AO Par. 147 (Abgabenordnung) | 10 Jahre | Steuerrelevante Unterlagen |
|
||||
| AO Par. 147 (sonstige Unterlagen) | 6 Jahre | Geschaeftsbriefe |
|
||||
| BetrVG (Betriebsrat) | 3 Jahre | Betriebsratsprotokolle |
|
||||
| BDSG Par. 35 | Unverzueglich | Nicht mehr benoetigte personenbezogene Daten |
|
||||
| **Rechtsstreit-Hold** | Bis Abschluss | Alle prozessrelevanten Daten |
|
||||
|
||||
### Default-Retention je Datenkategorie
|
||||
|
||||
| Datenkategorie | Default-Frist | Gesetzliche Grundlage |
|
||||
|----------------|---------------|----------------------|
|
||||
| Stammdaten (Name, Adresse) | 3 Jahre nach Vertragsende | DSGVO Art. 17, Verjaehrung Par. 195 BGB |
|
||||
| Vertragsdaten | 10 Jahre | HGB Par. 257 |
|
||||
| Rechnungsdaten | 10 Jahre | AO Par. 147 |
|
||||
| Kommunikationsdaten (E-Mails) | 6 Jahre | AO Par. 147 |
|
||||
| Bewerberdaten | 6 Monate | AGG Par. 15 Abs. 4 |
|
||||
| Log-Daten (Server, Zugriff) | 90 Tage | DSGVO Art. 5 Abs. 1 lit. e |
|
||||
| Gesundheitsdaten | 10 Jahre | Aerztliche Aufbewahrungspflicht |
|
||||
| Schulnoten / Zeugnisse | 10 Jahre nach Abgang | Landesschulgesetze |
|
||||
| Einwilligungen (Nachweis) | 3 Jahre nach Widerruf | DSGVO Art. 7 Abs. 1, Beweislast |
|
||||
| Video-Ueberwachung | 72 Stunden | BDSG Par. 4 Abs. 5 |
|
||||
|
||||
### Implementierung
|
||||
|
||||
```typescript
|
||||
interface RetentionRule {
|
||||
category: string;
|
||||
default_days: number;
|
||||
legal_basis: string;
|
||||
deletion_trigger: "Vertragsende" | "Zweckwegfall" | "Widerruf";
|
||||
exception_rules: ExceptionRule[];
|
||||
}
|
||||
|
||||
interface ExceptionRule {
|
||||
condition: string; // z.B. "Rechtsstreit-Hold"
|
||||
override_days: number; // -1 = unbegrenzt bis Bedingung entfaellt
|
||||
legal_basis: string;
|
||||
}
|
||||
|
||||
function calculateDeletionDate(
|
||||
rule: RetentionRule,
|
||||
triggerDate: Date,
|
||||
activeExceptions: ExceptionRule[]
|
||||
): Date | null {
|
||||
// Aktive Ausnahmen pruefen
|
||||
const holdException = activeExceptions.find(
|
||||
(e) => e.override_days === -1
|
||||
);
|
||||
if (holdException) return null; // Loeschung ausgesetzt
|
||||
|
||||
// Maximale Frist berechnen
|
||||
const retentionDays = Math.max(
|
||||
rule.default_days,
|
||||
...activeExceptions.map((e) => e.override_days)
|
||||
);
|
||||
|
||||
const deletionDate = new Date(triggerDate);
|
||||
deletionDate.setDate(deletionDate.getDate() + retentionDays);
|
||||
return deletionDate;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Mapping: Score → TOM-Domaenen → Textbausteine
|
||||
|
||||
### TOM-Domaenen nach SDM (Standard-Datenschutzmodell)
|
||||
|
||||
| Domaene | Beschreibung | SDM-Gewaehrleistungsziel |
|
||||
|---------|--------------|--------------------------|
|
||||
| `ZUGANG` | Zugangskontrolle | Vertraulichkeit |
|
||||
| `ZUGRIFF` | Zugriffskontrolle | Vertraulichkeit |
|
||||
| `UEBERTRAGUNG` | Weitergabekontrolle | Integritaet |
|
||||
| `EINGABE` | Eingabekontrolle | Integritaet |
|
||||
| `AUFTRAG` | Auftragskontrolle | Integritaet |
|
||||
| `VERFUEGBARKEIT` | Verfuegbarkeitskontrolle | Verfuegbarkeit |
|
||||
| `TRENNUNG` | Trennungskontrolle | Nichtverkettung |
|
||||
| `TRANSPARENZ` | Transparenzkontrolle | Transparenz |
|
||||
| `INTERVENIERBARKEIT` | Betroffenenrechte | Intervenierbarkeit |
|
||||
| `DATENMINIMIERUNG` | Datenminimierung | Datenminimierung |
|
||||
|
||||
### Tier → Domaenen-Zuordnung
|
||||
|
||||
| Domaene | BASELINE | ENHANCED | HIGH_RISK | CRITICAL |
|
||||
|---------|----------|----------|-----------|----------|
|
||||
| ZUGANG | Pflicht | Pflicht | Pflicht | Pflicht |
|
||||
| ZUGRIFF | Pflicht | Pflicht | Pflicht | Pflicht |
|
||||
| UEBERTRAGUNG | Pflicht | Pflicht | Pflicht | Pflicht |
|
||||
| EINGABE | Empfohlen | Pflicht | Pflicht | Pflicht |
|
||||
| AUFTRAG | Empfohlen | Pflicht | Pflicht | Pflicht |
|
||||
| VERFUEGBARKEIT | Pflicht | Pflicht | Pflicht | Pflicht |
|
||||
| TRENNUNG | Empfohlen | Empfohlen | Pflicht | Pflicht |
|
||||
| TRANSPARENZ | Pflicht | Pflicht | Pflicht | Pflicht |
|
||||
| INTERVENIERBARKEIT | Pflicht | Pflicht | Pflicht | Pflicht |
|
||||
| DATENMINIMIERUNG | Empfohlen | Pflicht | Pflicht | Pflicht |
|
||||
|
||||
### Textbausteine je Tier und Domaene (Auszug)
|
||||
|
||||
```typescript
|
||||
const TOM_TEXTBAUSTEINE: Record<RiskTier, Record<string, string[]>> = {
|
||||
BASELINE: {
|
||||
ZUGANG: [
|
||||
"Passwortrichtlinie mit Mindestlaenge 12 Zeichen",
|
||||
"Automatische Bildschirmsperre nach 5 Minuten",
|
||||
"Besuchermanagement mit Protokollierung",
|
||||
],
|
||||
ZUGRIFF: [
|
||||
"Rollenbasierte Zugriffskontrolle (RBAC)",
|
||||
"Need-to-know-Prinzip",
|
||||
"Regelmaessige Ueberpruefung der Berechtigungen (jaehrlich)",
|
||||
],
|
||||
VERFUEGBARKEIT: [
|
||||
"Taegliche Backups mit Integritaetspruefung",
|
||||
"USV-Anlage fuer kritische Systeme",
|
||||
"Dokumentierter Notfallplan",
|
||||
],
|
||||
},
|
||||
ENHANCED: {
|
||||
ZUGANG: [
|
||||
"Multi-Faktor-Authentifizierung (MFA) fuer alle Nutzer",
|
||||
"Zentrales Identity Management (IdP)",
|
||||
"Hardware-Token oder FIDO2 fuer Admin-Zugaenge",
|
||||
],
|
||||
ZUGRIFF: [
|
||||
"Attributbasierte Zugriffskontrolle (ABAC)",
|
||||
"Privileged Access Management (PAM)",
|
||||
"Quartalsweise Zugriffs-Reviews",
|
||||
],
|
||||
VERFUEGBARKEIT: [
|
||||
"Geo-redundante Backups",
|
||||
"Recovery Time Objective (RTO) < 4 Stunden",
|
||||
"Jaehrlicher Disaster-Recovery-Test",
|
||||
],
|
||||
},
|
||||
HIGH_RISK: {
|
||||
ZUGANG: [
|
||||
"Zero-Trust-Architektur",
|
||||
"Biometrische Zugangskontrolle fuer Serverraeume",
|
||||
"Netzwerksegmentierung mit Mikrosegmenten",
|
||||
],
|
||||
ZUGRIFF: [
|
||||
"Just-in-Time Access (zeitlich begrenzte Berechtigungen)",
|
||||
"Vier-Augen-Prinzip fuer kritische Operationen",
|
||||
"Echtzeit-Anomalieerkennung bei Zugriffen",
|
||||
],
|
||||
TRENNUNG: [
|
||||
"Mandantentrennung auf Datenbankebene (Schemata)",
|
||||
"Getrennte Verschluesselungsschluessel je Mandant",
|
||||
"Isolierte Verarbeitungsumgebungen",
|
||||
],
|
||||
},
|
||||
CRITICAL: {
|
||||
ZUGANG: [
|
||||
"Air-Gapped Systeme fuer kritischste Daten",
|
||||
"24/7 SOC-Ueberwachung",
|
||||
"Penetrationstests (quartalsweise, extern)",
|
||||
],
|
||||
ZUGRIFF: [
|
||||
"Hardware Security Modules (HSM) fuer Schluessel",
|
||||
"Break-Glass-Verfahren mit Audit-Trail",
|
||||
"Kontinuierliche Authentifizierung",
|
||||
],
|
||||
VERFUEGBARKEIT: [
|
||||
"Active-Active Cluster mit automatischem Failover",
|
||||
"RTO < 15 Minuten, RPO < 5 Minuten",
|
||||
"Monatliche Disaster-Recovery-Tests",
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Kompatibilitaet mit bestehendem Modell
|
||||
|
||||
### Bestehendes Modell (backend-compliance)
|
||||
|
||||
Das bestehende Modell in `backend-compliance/compliance/db/models.py` nutzt eine vereinfachte Skala:
|
||||
|
||||
| Parameter | Bestehend | Neu (diese Spec) |
|
||||
|-----------|-----------|-------------------|
|
||||
| Impact-Skala | 1--5 | 0--10 |
|
||||
| Likelihood-Skala | 1--5 | 0--10 |
|
||||
| Score-Bereich | 1--25 | 0--100 |
|
||||
| Schwellenwerte | 6 / 12 / 20 | 25 / 50 / 75 |
|
||||
|
||||
### Konvertierung: Alte Skala → Neue Skala
|
||||
|
||||
```typescript
|
||||
// Alt (1-5) → Neu (0-10)
|
||||
function oldToNewScale(oldValue: number): number {
|
||||
return Math.round((oldValue / 5) * 10);
|
||||
}
|
||||
|
||||
// Neu (0-10) → Alt (1-5)
|
||||
function newToOldScale(newValue: number): number {
|
||||
return Math.max(1, Math.round((newValue / 10) * 5));
|
||||
}
|
||||
```
|
||||
|
||||
### Konvertierung: Alter Score → Neuer Score
|
||||
|
||||
```typescript
|
||||
// Alt (1-25) → Neu (0-100)
|
||||
function oldScoreToNew(oldScore: number): number {
|
||||
return Math.round((oldScore / 25) * 100);
|
||||
}
|
||||
|
||||
// Neu (0-100) → Alt (1-25)
|
||||
function newScoreToOld(newScore: number): number {
|
||||
return Math.max(1, Math.round((newScore / 100) * 25));
|
||||
}
|
||||
```
|
||||
|
||||
### Schwellenwert-Mapping
|
||||
|
||||
| Altes Tier (1--25) | Neues Tier (0--100) | Risk-Tier |
|
||||
|---------------------|---------------------|-----------|
|
||||
| 1--5 | 0--24 | BASELINE |
|
||||
| 6--11 | 25--49 | ENHANCED |
|
||||
| 12--19 | 50--74 | HIGH_RISK |
|
||||
| 20--25 | 75--100 | CRITICAL |
|
||||
|
||||
### Migrations-Strategie
|
||||
|
||||
Bei der Migration bestehender Risikobewertungen:
|
||||
|
||||
```sql
|
||||
-- Bestehende Scores konvertieren (1-25 → 0-100)
|
||||
UPDATE compliance_risks
|
||||
SET score_v2 = ROUND((score::numeric / 25.0) * 100)
|
||||
WHERE score_v2 IS NULL;
|
||||
|
||||
-- Impact/Likelihood konvertieren (1-5 → 0-10)
|
||||
UPDATE compliance_risks
|
||||
SET impact_v2 = ROUND((impact::numeric / 5.0) * 10),
|
||||
likelihood_v2 = ROUND((likelihood::numeric / 5.0) * 10)
|
||||
WHERE impact_v2 IS NULL;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Anhang A: Vollstaendiges Berechnungsbeispiel
|
||||
|
||||
### Szenario: Lernplattform mit KI-Korrekturvorschlaegen
|
||||
|
||||
**Kontext:**
|
||||
- Schueler-Plattform (Kinder betroffen)
|
||||
- KI bewertet Klausuren (automatisierte Entscheidung)
|
||||
- Gesundheitsdaten bei Attestverwaltung
|
||||
- Cloud-Hosting (AWS Frankfurt)
|
||||
- MFA vorhanden, aber kein SIEM
|
||||
|
||||
**Impact-Berechnung:**
|
||||
|
||||
```
|
||||
Basis = 2
|
||||
+ Kinder / Schutzbeduerftige = +2
|
||||
+ Automatisierte Entscheidungen = +1
|
||||
+ Gesundheitsdaten = +1
|
||||
+ Besondere Kategorien (Art. 9) = +2
|
||||
─────────────────────────────────────
|
||||
Impact = min(8, 10) = 8
|
||||
```
|
||||
|
||||
**Likelihood-Berechnung:**
|
||||
|
||||
```
|
||||
Basis = 2
|
||||
+ Internet-Exponierung = +2
|
||||
+ Fehlendes Logging / SIEM = +2
|
||||
─────────────────────────────────────
|
||||
Likelihood = min(6, 10) = 6
|
||||
```
|
||||
|
||||
**Score und Tier:**
|
||||
|
||||
```
|
||||
Score = round(8 * 6) = 48 → Tier: ENHANCED
|
||||
```
|
||||
|
||||
**Ausgewaehlte Controls:** 100 (60 BASELINE + 40 ENHANCED)
|
||||
plus Trigger-Controls fuer `special_categories` und `vulnerable_persons`.
|
||||
|
||||
**Empfohlene Massnahmen (Auszug):**
|
||||
- MFA fuer alle Nutzer (bereits vorhanden)
|
||||
- SIEM-System einfuehren (fehlend -- Prioritaet hoch)
|
||||
- Altersverifikation und elterliche Einwilligung
|
||||
- DSFA durchfuehren (Art. 35 -- Kinder + automatisierte Entscheidung)
|
||||
- Erklaerbarkeit der KI-Entscheidungen sicherstellen (AI Act)
|
||||
|
||||
---
|
||||
|
||||
## Anhang B: Glossar
|
||||
|
||||
| Begriff | Erklaerung |
|
||||
|---------|-----------|
|
||||
| **TOM** | Technisch-organisatorische Massnahmen (Art. 32 DSGVO) |
|
||||
| **DSFA** | Datenschutz-Folgenabschaetzung (Art. 35 DSGVO) |
|
||||
| **SDM** | Standard-Datenschutzmodell der Datenschutzkonferenz |
|
||||
| **IAM** | Identity and Access Management |
|
||||
| **SIEM** | Security Information and Event Management |
|
||||
| **SCCs** | Standard Contractual Clauses (Standardvertragsklauseln) |
|
||||
| **TIA** | Transfer Impact Assessment |
|
||||
| **AVV** | Auftragsverarbeitungsvertrag (Art. 28 DSGVO) |
|
||||
| **RBAC** | Role-Based Access Control |
|
||||
| **ABAC** | Attribute-Based Access Control |
|
||||
| **PAM** | Privileged Access Management |
|
||||
| **HSM** | Hardware Security Module |
|
||||
| **SOC** | Security Operations Center |
|
||||
| **RTO** | Recovery Time Objective |
|
||||
| **RPO** | Recovery Point Objective |
|
||||
1721
scripts/edpb-crawler.py
Executable file
1721
scripts/edpb-crawler.py
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user