Files
Benjamin Admin 3707ffe799
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
feat: DSK/BfDI RAG-Ingest, TOM-Control-Library 180, Risk-Engine-Spec, RAG-Query-Optimierung
- 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>
2026-03-05 12:03:57 +01:00

20 KiB

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

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

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

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

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

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

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)

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

// 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

// 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:

-- 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