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:
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 |
|
||||
Reference in New Issue
Block a user