Erweiterte Compliance-Vorlagen fuer den Document Generator: - DSFA V2: Schwellwertanalyse (9 WP248-Kriterien), SDM-basierte TOM, strukturierte Risikobewertung, KI-Modul (AI Act), Art.36-Pruefung - TOM V2: 7 SDM-Gewaehrleistungsziele, Sektor-Erweiterungen, NIS2/ISO27001/AI Act Varianten - VVT V2: 6 Branchen-Muster (IT/SaaS, Gesundheit, Handel, Handwerk, Bildung, Beratung) + allgemeine Art.30-Vorlage - AVV V2: Vollstaendiger Art.28-Vertrag mit TOM-Anlage - Verpflichtungserklaerung: Mitarbeiter-Vertraulichkeit - Art.13/14 Informationspflichten-Muster Enthalt SQL-Migrations (compliance_legal_templates), Python-Generatoren und Qdrant-Cleanup-Skript. Feature-Branch fuer spaetere Integration in breakpilot-compliance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
286 lines
15 KiB
Python
286 lines
15 KiB
Python
"""TOM template generator V2 — SDM-structured TOM catalog.
|
|
|
|
Replaces the flat 17-measure list with a hierarchical structure based on
|
|
the 7 SDM Gewaehrleistungsziele (Standard-Datenschutzmodell V3.1a).
|
|
"""
|
|
|
|
# -- SDM-structured TOM catalog ---------------------------------------------
|
|
|
|
SDM_TOM_CATALOG = {
|
|
"verfuegbarkeit": {
|
|
"label": "Verfuegbarkeit",
|
|
"sdm_baustein": "SDM-B11 (Aufbewahren)",
|
|
"measures": [
|
|
{"name": "Redundante Datenhaltung", "description": "RAID, Replikation, Geo-Redundanz", "type": "technical"},
|
|
{"name": "Backup-Strategie", "description": "Taeglich inkrementell, woechentlich voll, verschluesselt", "type": "technical"},
|
|
{"name": "Disaster-Recovery-Plan", "description": "Dokumentierte RTO/RPO-Werte, jaehrliche Tests", "type": "organizational"},
|
|
{"name": "USV / Notstromversorgung", "description": "Unterbrechungsfreie Stromversorgung fuer kritische Systeme", "type": "technical"},
|
|
],
|
|
},
|
|
"integritaet": {
|
|
"label": "Integritaet",
|
|
"sdm_baustein": "SDM-B61 (Berichtigen)",
|
|
"measures": [
|
|
{"name": "Pruefsummen und Signaturen", "description": "Digitale Signaturen fuer Datenuebertragungen", "type": "technical"},
|
|
{"name": "Eingabevalidierung", "description": "Plausibilitaetspruefungen auf allen Eingabeschnittstellen", "type": "technical"},
|
|
{"name": "Change Management", "description": "Dokumentierte Aenderungsverfahren mit Freigabeprozess", "type": "organizational"},
|
|
{"name": "Versionierung", "description": "Versionierung von Datensaetzen und Konfigurationen", "type": "technical"},
|
|
],
|
|
},
|
|
"vertraulichkeit": {
|
|
"label": "Vertraulichkeit",
|
|
"sdm_baustein": "SDM-B51 (Zugriffe regeln)",
|
|
"measures": [
|
|
{"name": "Verschluesselung im Transit", "description": "TLS 1.3 fuer alle Verbindungen", "type": "technical"},
|
|
{"name": "Verschluesselung at Rest", "description": "AES-256 fuer gespeicherte Daten", "type": "technical"},
|
|
{"name": "Zugriffskonzept (RBAC)", "description": "Rollenbasiert, Least-Privilege-Prinzip, regelmaessige Reviews", "type": "technical"},
|
|
{"name": "Multi-Faktor-Authentifizierung", "description": "MFA fuer alle administrativen Zugaenge", "type": "technical"},
|
|
{"name": "Physische Zutrittskontrolle", "description": "Schluessel, Kartenleser, Besucherprotokoll", "type": "technical"},
|
|
{"name": "Vertraulichkeitsverpflichtung", "description": "Schriftliche Verpflichtung aller Mitarbeitenden", "type": "organizational"},
|
|
],
|
|
},
|
|
"nichtverkettung": {
|
|
"label": "Nichtverkettung",
|
|
"sdm_baustein": "SDM-B50 (Trennen)",
|
|
"measures": [
|
|
{"name": "Mandantentrennung", "description": "Logische Datentrennung nach Mandanten/Zweck", "type": "technical"},
|
|
{"name": "Pseudonymisierung", "description": "Wo fachlich moeglich, Einsatz von Pseudonymen", "type": "technical"},
|
|
{"name": "Zweckbindungspruefung", "description": "Pruefung bei jeder neuen Datennutzung", "type": "organizational"},
|
|
],
|
|
},
|
|
"transparenz": {
|
|
"label": "Transparenz",
|
|
"sdm_baustein": "SDM-B42 (Dokumentieren), SDM-B43 (Protokollieren)",
|
|
"measures": [
|
|
{"name": "Verarbeitungsverzeichnis", "description": "Art. 30 DS-GVO konformes VVT", "type": "organizational"},
|
|
{"name": "Audit-Logging", "description": "Vollstaendige Protokollierung aller Datenzugriffe", "type": "technical"},
|
|
{"name": "Informationspflichten", "description": "Art. 13/14 DS-GVO Datenschutzerklaerung", "type": "organizational"},
|
|
{"name": "Datenpannen-Prozess", "description": "Dokumentierter Meldeprozess Art. 33/34 DS-GVO", "type": "organizational"},
|
|
],
|
|
},
|
|
"intervenierbarkeit": {
|
|
"label": "Intervenierbarkeit",
|
|
"sdm_baustein": "SDM-B60 (Loeschen), SDM-B61 (Berichtigen), SDM-B62 (Einschraenken)",
|
|
"measures": [
|
|
{"name": "Betroffenenanfragen-Prozess", "description": "Auskunft, Loeschung, Berichtigung, Widerspruch", "type": "organizational"},
|
|
{"name": "Technische Loeschfaehigkeit", "description": "Loeschung mit Nachweis (Loeschprotokoll)", "type": "technical"},
|
|
{"name": "Datenportabilitaet", "description": "Export in maschinenlesbarem Format (Art. 20)", "type": "technical"},
|
|
{"name": "Sperrfunktion", "description": "Einschraenkung der Verarbeitung moeglich", "type": "technical"},
|
|
],
|
|
},
|
|
"datenminimierung": {
|
|
"label": "Datenminimierung",
|
|
"sdm_baustein": "SDM-B41 (Planen und Spezifizieren)",
|
|
"measures": [
|
|
{"name": "Erforderlichkeitspruefung", "description": "Regelmaessige Pruefung der erhobenen Datenfelder", "type": "organizational"},
|
|
{"name": "Automatisierte Loeschung", "description": "Fristgerechte Loeschung nach Aufbewahrungsfrist", "type": "technical"},
|
|
{"name": "Anonymisierung", "description": "Anonymisierung/Aggregation fuer Statistik", "type": "technical"},
|
|
{"name": "Privacy by Design", "description": "Datenschutz ab Entwurfsphase neuer Verarbeitungen", "type": "organizational"},
|
|
],
|
|
},
|
|
}
|
|
|
|
# -- Sector-specific extensions ----------------------------------------------
|
|
|
|
SECTOR_TOMS = {
|
|
"it_saas": {
|
|
"label": "IT / SaaS",
|
|
"measures": [
|
|
{"name": "Container-Isolation", "description": "Workload-Isolation zwischen Mandanten (Kubernetes Namespaces)", "type": "technical", "sdm_goal": "nichtverkettung"},
|
|
{"name": "API-Security", "description": "Rate Limiting, OAuth 2.0, API-Key-Rotation", "type": "technical", "sdm_goal": "vertraulichkeit"},
|
|
{"name": "DevSecOps Pipeline", "description": "SAST/DAST in CI/CD, Dependency Scanning", "type": "technical", "sdm_goal": "integritaet"},
|
|
{"name": "Secrets Management", "description": "Vault/KMS fuer Credentials, keine Hardcoded Secrets", "type": "technical", "sdm_goal": "vertraulichkeit"},
|
|
],
|
|
},
|
|
"gesundheitswesen": {
|
|
"label": "Gesundheitswesen",
|
|
"measures": [
|
|
{"name": "Patientenakten-Verschluesselung", "description": "Ende-zu-Ende-Verschluesselung fuer Gesundheitsdaten (Art. 9)", "type": "technical", "sdm_goal": "vertraulichkeit"},
|
|
{"name": "Notfallzugriff", "description": "Break-the-Glass-Verfahren fuer medizinische Notfaelle", "type": "organizational", "sdm_goal": "verfuegbarkeit"},
|
|
{"name": "Forschungsdaten-Anonymisierung", "description": "Vollstaendige Anonymisierung vor Forschungsnutzung", "type": "technical", "sdm_goal": "datenminimierung"},
|
|
],
|
|
},
|
|
"finanzdienstleistungen": {
|
|
"label": "Finanzdienstleistungen",
|
|
"measures": [
|
|
{"name": "Transaktions-Monitoring", "description": "Echtzeit-Ueberwachung auf Unregelmaessigkeiten (GwG)", "type": "technical", "sdm_goal": "integritaet"},
|
|
{"name": "Aufbewahrungspflichten", "description": "10 Jahre Aufbewahrung gemaess AO/HGB, danach Loeschung", "type": "organizational", "sdm_goal": "datenminimierung"},
|
|
{"name": "PCI-DSS Compliance", "description": "Payment Card Industry Standards fuer Kartendaten", "type": "technical", "sdm_goal": "vertraulichkeit"},
|
|
],
|
|
},
|
|
"handel": {
|
|
"label": "Handel / E-Commerce",
|
|
"measures": [
|
|
{"name": "Cookie-Consent-Management", "description": "TDDDG-konformes Einwilligungsmanagement", "type": "technical", "sdm_goal": "transparenz"},
|
|
{"name": "Gastzugang-Option", "description": "Bestellung ohne Pflicht-Kundenkonto (Datenminimierung)", "type": "organizational", "sdm_goal": "datenminimierung"},
|
|
{"name": "Zahlungsdaten-Tokenisierung", "description": "Keine direkte Speicherung von Zahlungsdaten", "type": "technical", "sdm_goal": "vertraulichkeit"},
|
|
],
|
|
},
|
|
"handwerk": {
|
|
"label": "Handwerk",
|
|
"measures": [
|
|
{"name": "Mobile-Device-Management", "description": "Absicherung mobiler Endgeraete auf Baustellen", "type": "technical", "sdm_goal": "vertraulichkeit"},
|
|
{"name": "Papierakten-Sicherung", "description": "Verschlossene Schraenke fuer physische Kundenakten", "type": "technical", "sdm_goal": "vertraulichkeit"},
|
|
],
|
|
},
|
|
}
|
|
|
|
# -- NIS2 / ISO 27001 / AI Act extensions -----------------------------------
|
|
|
|
NIS2_TOMS = [
|
|
{"name": "Incident-Response-Plan", "description": "NIS2-konformer Vorfallreaktionsplan (72h Meldepflicht an BSI)", "type": "organizational", "sdm_goal": "verfuegbarkeit"},
|
|
{"name": "Supply-Chain-Security", "description": "Bewertung der Lieferkettensicherheit (BSIG 2025)", "type": "organizational", "sdm_goal": "integritaet"},
|
|
{"name": "Vulnerability Management", "description": "Regelmaessige Schwachstellenscans, Patch-Management", "type": "technical", "sdm_goal": "integritaet"},
|
|
{"name": "Security Awareness", "description": "Pflicht-Schulungen Cybersicherheit fuer Geschaeftsleitung", "type": "organizational", "sdm_goal": "vertraulichkeit"},
|
|
]
|
|
|
|
ISO27001_TOMS = [
|
|
{"name": "ISMS Risikomanagement", "description": "ISO 27001 Anhang A — Informationssicherheits-Risikobewertung", "type": "organizational", "sdm_goal": "verfuegbarkeit"},
|
|
{"name": "Dokumentenlenkung", "description": "Versionierte Sicherheitsrichtlinien und -verfahren", "type": "organizational", "sdm_goal": "transparenz"},
|
|
{"name": "Management Review", "description": "Jaehrliche Ueberprufung des ISMS durch Geschaeftsleitung", "type": "organizational", "sdm_goal": "transparenz"},
|
|
]
|
|
|
|
AI_ACT_TOMS = [
|
|
{"name": "KI-Risikoklassifizierung", "description": "Bewertung aller KI-Systeme nach EU AI Act Risikokategorien", "type": "organizational", "sdm_goal": "transparenz"},
|
|
{"name": "Human Oversight", "description": "Menschliche Aufsicht fuer Hochrisiko-KI-Systeme (Art. 14 KI-VO)", "type": "organizational", "sdm_goal": "intervenierbarkeit"},
|
|
{"name": "KI-Transparenz", "description": "Transparenzpflichten bei KI-Einsatz gegenueber Betroffenen (Art. 13 KI-VO)", "type": "organizational", "sdm_goal": "transparenz"},
|
|
{"name": "KI-Bias-Monitoring", "description": "Ueberwachung auf diskriminierende Ergebnisse", "type": "technical", "sdm_goal": "integritaet"},
|
|
]
|
|
|
|
|
|
def generate_tom_drafts(ctx: dict) -> list[dict]:
|
|
"""Generate TOM measure drafts structured by SDM Gewaehrleistungsziele.
|
|
|
|
Args:
|
|
ctx: Flat dict from company-profile/template-context.
|
|
|
|
Returns:
|
|
List of TOM measure dicts with SDM goal assignment.
|
|
"""
|
|
measures = []
|
|
control_counter = 0
|
|
|
|
# Base SDM measures
|
|
for goal_key, goal_data in SDM_TOM_CATALOG.items():
|
|
for m in goal_data["measures"]:
|
|
control_counter += 1
|
|
measures.append(_build_measure(
|
|
counter=control_counter,
|
|
measure=m,
|
|
sdm_goal=goal_key,
|
|
sdm_baustein=goal_data["sdm_baustein"],
|
|
category=goal_data["label"],
|
|
ctx=ctx,
|
|
))
|
|
|
|
# Regulatory extensions
|
|
if ctx.get("subject_to_nis2"):
|
|
for m in NIS2_TOMS:
|
|
control_counter += 1
|
|
measures.append(_build_measure(
|
|
counter=control_counter,
|
|
measure=m,
|
|
sdm_goal=m["sdm_goal"],
|
|
sdm_baustein="NIS2 / BSIG 2025",
|
|
category="Cybersicherheit (NIS2)",
|
|
ctx=ctx,
|
|
))
|
|
|
|
if ctx.get("subject_to_iso27001"):
|
|
for m in ISO27001_TOMS:
|
|
control_counter += 1
|
|
measures.append(_build_measure(
|
|
counter=control_counter,
|
|
measure=m,
|
|
sdm_goal=m["sdm_goal"],
|
|
sdm_baustein="ISO 27001 Anhang A",
|
|
category="ISMS (ISO 27001)",
|
|
ctx=ctx,
|
|
))
|
|
|
|
if ctx.get("subject_to_ai_act") or ctx.get("has_ai_systems"):
|
|
for m in AI_ACT_TOMS:
|
|
control_counter += 1
|
|
measures.append(_build_measure(
|
|
counter=control_counter,
|
|
measure=m,
|
|
sdm_goal=m["sdm_goal"],
|
|
sdm_baustein="EU AI Act (2024/1689)",
|
|
category="KI-Compliance",
|
|
ctx=ctx,
|
|
))
|
|
|
|
# Sector-specific extensions
|
|
sector = _detect_sector(ctx)
|
|
if sector and sector in SECTOR_TOMS:
|
|
sector_data = SECTOR_TOMS[sector]
|
|
for m in sector_data["measures"]:
|
|
control_counter += 1
|
|
measures.append(_build_measure(
|
|
counter=control_counter,
|
|
measure=m,
|
|
sdm_goal=m.get("sdm_goal", "vertraulichkeit"),
|
|
sdm_baustein=f"Sektor: {sector_data['label']}",
|
|
category=f"Sektor ({sector_data['label']})",
|
|
ctx=ctx,
|
|
))
|
|
|
|
return measures
|
|
|
|
|
|
def sdm_coverage_summary(measures: list[dict]) -> dict:
|
|
"""Return coverage matrix: SDM goal -> measure count."""
|
|
summary = {}
|
|
for goal_key in SDM_TOM_CATALOG:
|
|
count = sum(1 for m in measures if m.get("sdm_goal") == goal_key)
|
|
summary[goal_key] = {
|
|
"label": SDM_TOM_CATALOG[goal_key]["label"],
|
|
"count": count,
|
|
}
|
|
return summary
|
|
|
|
|
|
# -- Internal helpers --------------------------------------------------------
|
|
|
|
def _build_measure(counter: int, measure: dict, sdm_goal: str,
|
|
sdm_baustein: str, category: str, ctx: dict) -> dict:
|
|
return {
|
|
"control_id": f"TOM-SDM-{counter:03d}",
|
|
"name": measure["name"],
|
|
"description": measure["description"],
|
|
"category": category,
|
|
"type": measure.get("type", "organizational"),
|
|
"sdm_goal": sdm_goal,
|
|
"sdm_baustein_ref": sdm_baustein,
|
|
"implementation_status": "not_implemented",
|
|
"effectiveness_rating": "not_assessed",
|
|
"responsible_department": "IT-Sicherheit",
|
|
"priority": _assess_priority(measure, ctx),
|
|
"review_frequency": f"{ctx.get('review_cycle_months', 12)} Monate",
|
|
}
|
|
|
|
|
|
def _assess_priority(measure: dict, ctx: dict) -> str:
|
|
name_lower = measure.get("name", "").lower()
|
|
if any(kw in name_lower for kw in ["verschluesselung", "mfa", "incident", "ki-risiko"]):
|
|
return "high"
|
|
if any(kw in name_lower for kw in ["backup", "zugriff", "logging", "loeschung"]):
|
|
return "high"
|
|
return "medium"
|
|
|
|
|
|
def _detect_sector(ctx: dict) -> str | None:
|
|
"""Map company industry to sector key."""
|
|
industry = (ctx.get("industry") or "").lower()
|
|
mapping = {
|
|
"technologie": "it_saas", "it": "it_saas", "saas": "it_saas", "software": "it_saas",
|
|
"gesundheit": "gesundheitswesen", "pharma": "gesundheitswesen", "medizin": "gesundheitswesen",
|
|
"finanz": "finanzdienstleistungen", "bank": "finanzdienstleistungen", "versicherung": "finanzdienstleistungen",
|
|
"handel": "handel", "e-commerce": "handel", "einzelhandel": "handel", "shop": "handel",
|
|
"handwerk": "handwerk", "bau": "handwerk", "kfz": "handwerk",
|
|
}
|
|
for keyword, sector in mapping.items():
|
|
if keyword in industry:
|
|
return sector
|
|
return None
|