Services: Admin-Compliance, Backend-Compliance, AI-Compliance-SDK, Consent-SDK, Developer-Portal, PCA-Platform, DSMS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1232 lines
46 KiB
Go
1232 lines
46 KiB
Go
package ucca
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// ============================================================================
|
|
// Rule Engine - Deterministic rule evaluation
|
|
// ============================================================================
|
|
|
|
// Rule represents a single evaluation rule
|
|
type Rule struct {
|
|
Code string
|
|
Category string
|
|
Title string
|
|
TitleDE string
|
|
Description string
|
|
DescriptionDE string
|
|
Severity Severity
|
|
ScoreDelta int // Points added to risk score
|
|
GDPRRef string // GDPR article reference
|
|
Controls []string // Required control IDs
|
|
Patterns []string // Recommended pattern IDs
|
|
Condition func(intake *UseCaseIntake) bool
|
|
Rationale func(intake *UseCaseIntake) string
|
|
}
|
|
|
|
// RuleEngine holds all rules and performs evaluation
|
|
type RuleEngine struct {
|
|
rules []Rule
|
|
}
|
|
|
|
// NewRuleEngine creates a new rule engine with all rules
|
|
func NewRuleEngine() *RuleEngine {
|
|
return &RuleEngine{
|
|
rules: AllRules,
|
|
}
|
|
}
|
|
|
|
// Evaluate runs all rules against the intake and returns the assessment result
|
|
func (e *RuleEngine) Evaluate(intake *UseCaseIntake) *AssessmentResult {
|
|
result := &AssessmentResult{
|
|
Feasibility: FeasibilityYES,
|
|
RiskLevel: RiskLevelMINIMAL,
|
|
Complexity: ComplexityLOW,
|
|
RiskScore: 0,
|
|
TriggeredRules: []TriggeredRule{},
|
|
RequiredControls: []RequiredControl{},
|
|
RecommendedArchitecture: []PatternRecommendation{},
|
|
ForbiddenPatterns: []ForbiddenPattern{},
|
|
ExampleMatches: []ExampleMatch{},
|
|
DSFARecommended: false,
|
|
Art22Risk: false,
|
|
TrainingAllowed: TrainingYES,
|
|
}
|
|
|
|
// Track triggered severities
|
|
hasBlock := false
|
|
hasWarn := false
|
|
controlMap := make(map[string]bool)
|
|
patternMap := make(map[string]int) // pattern -> priority
|
|
|
|
// Evaluate each rule
|
|
for _, rule := range e.rules {
|
|
if rule.Condition(intake) {
|
|
// Add triggered rule
|
|
triggered := TriggeredRule{
|
|
Code: rule.Code,
|
|
Category: rule.Category,
|
|
Title: rule.TitleDE,
|
|
Description: rule.DescriptionDE,
|
|
Severity: rule.Severity,
|
|
ScoreDelta: rule.ScoreDelta,
|
|
GDPRRef: rule.GDPRRef,
|
|
Rationale: rule.Rationale(intake),
|
|
}
|
|
result.TriggeredRules = append(result.TriggeredRules, triggered)
|
|
|
|
// Update risk score
|
|
result.RiskScore += rule.ScoreDelta
|
|
|
|
// Track severity
|
|
switch rule.Severity {
|
|
case SeverityBLOCK:
|
|
hasBlock = true
|
|
case SeverityWARN:
|
|
hasWarn = true
|
|
}
|
|
|
|
// Collect required controls
|
|
for _, controlID := range rule.Controls {
|
|
if !controlMap[controlID] {
|
|
controlMap[controlID] = true
|
|
if ctrl := GetControlByID(controlID); ctrl != nil {
|
|
result.RequiredControls = append(result.RequiredControls, *ctrl)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Collect recommended patterns
|
|
for i, patternID := range rule.Patterns {
|
|
if _, exists := patternMap[patternID]; !exists {
|
|
patternMap[patternID] = i + 1 // priority
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Determine feasibility based on aggregation rules (R-090 to R-092)
|
|
if hasBlock {
|
|
result.Feasibility = FeasibilityNO
|
|
} else if hasWarn {
|
|
result.Feasibility = FeasibilityCONDITIONAL
|
|
} else {
|
|
result.Feasibility = FeasibilityYES
|
|
}
|
|
|
|
// Determine risk level based on score
|
|
if result.RiskScore >= 80 {
|
|
result.RiskLevel = RiskLevelUNACCEPTABLE
|
|
} else if result.RiskScore >= 60 {
|
|
result.RiskLevel = RiskLevelHIGH
|
|
} else if result.RiskScore >= 40 {
|
|
result.RiskLevel = RiskLevelMEDIUM
|
|
} else if result.RiskScore >= 20 {
|
|
result.RiskLevel = RiskLevelLOW
|
|
} else {
|
|
result.RiskLevel = RiskLevelMINIMAL
|
|
}
|
|
|
|
// Determine complexity
|
|
if len(result.RequiredControls) >= 5 || result.RiskScore >= 50 {
|
|
result.Complexity = ComplexityHIGH
|
|
} else if len(result.RequiredControls) >= 3 || result.RiskScore >= 25 {
|
|
result.Complexity = ComplexityMEDIUM
|
|
} else {
|
|
result.Complexity = ComplexityLOW
|
|
}
|
|
|
|
// Check DSFA recommendation
|
|
if result.RiskLevel == RiskLevelHIGH || result.RiskLevel == RiskLevelUNACCEPTABLE ||
|
|
intake.DataTypes.Article9Data || intake.DataTypes.BiometricData ||
|
|
(intake.Purpose.Profiling && intake.DataTypes.PersonalData) {
|
|
result.DSFARecommended = true
|
|
}
|
|
|
|
// Check Art. 22 risk
|
|
if intake.Automation == AutomationFullyAutomated &&
|
|
(intake.Outputs.LegalEffects || intake.Outputs.RankingsOrScores || intake.Purpose.EvaluationScoring) {
|
|
result.Art22Risk = true
|
|
}
|
|
|
|
// Determine training allowed
|
|
if intake.ModelUsage.Training && intake.DataTypes.PersonalData {
|
|
result.TrainingAllowed = TrainingNO
|
|
} else if intake.ModelUsage.Finetune && intake.DataTypes.PersonalData {
|
|
result.TrainingAllowed = TrainingCONDITIONAL
|
|
}
|
|
|
|
// Add recommended architecture patterns
|
|
for patternID, priority := range patternMap {
|
|
if p := GetPatternByID(patternID); p != nil {
|
|
result.RecommendedArchitecture = append(result.RecommendedArchitecture,
|
|
PatternToRecommendation(*p, "Empfohlen basierend auf ausgelösten Regeln", priority))
|
|
}
|
|
}
|
|
|
|
// Add applicable patterns not yet recommended
|
|
applicable := GetApplicablePatterns(intake)
|
|
for _, p := range applicable {
|
|
found := false
|
|
for _, rec := range result.RecommendedArchitecture {
|
|
if rec.PatternID == p.ID {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
result.RecommendedArchitecture = append(result.RecommendedArchitecture,
|
|
PatternToRecommendation(p, "Anwendbar für Ihren Use Case", len(result.RecommendedArchitecture)+1))
|
|
}
|
|
}
|
|
|
|
// Add forbidden patterns
|
|
result.ForbiddenPatterns = GetForbiddenPatterns(intake)
|
|
|
|
// Add matching examples
|
|
result.ExampleMatches = MatchExamples(intake)
|
|
|
|
// Generate summary
|
|
result.Summary = generateSummary(result, intake)
|
|
result.Recommendation = generateRecommendation(result, intake)
|
|
if result.Feasibility == FeasibilityNO {
|
|
result.AlternativeApproach = generateAlternative(result, intake)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// generateSummary creates a human-readable summary
|
|
func generateSummary(result *AssessmentResult, intake *UseCaseIntake) string {
|
|
var parts []string
|
|
|
|
switch result.Feasibility {
|
|
case FeasibilityYES:
|
|
parts = append(parts, "Der Use Case ist aus DSGVO-Sicht grundsätzlich umsetzbar.")
|
|
case FeasibilityCONDITIONAL:
|
|
parts = append(parts, "Der Use Case ist unter Auflagen umsetzbar.")
|
|
case FeasibilityNO:
|
|
parts = append(parts, "Der Use Case ist in der aktuellen Form nicht DSGVO-konform umsetzbar.")
|
|
}
|
|
|
|
if len(result.TriggeredRules) > 0 {
|
|
blockCount := 0
|
|
warnCount := 0
|
|
for _, r := range result.TriggeredRules {
|
|
if r.Severity == SeverityBLOCK {
|
|
blockCount++
|
|
} else if r.Severity == SeverityWARN {
|
|
warnCount++
|
|
}
|
|
}
|
|
if blockCount > 0 {
|
|
parts = append(parts, fmt.Sprintf("%d kritische Regelverletzung(en) identifiziert.", blockCount))
|
|
}
|
|
if warnCount > 0 {
|
|
parts = append(parts, fmt.Sprintf("%d Warnungen erfordern Aufmerksamkeit.", warnCount))
|
|
}
|
|
}
|
|
|
|
if result.DSFARecommended {
|
|
parts = append(parts, "Eine Datenschutz-Folgenabschätzung (DSFA) wird empfohlen.")
|
|
}
|
|
|
|
return strings.Join(parts, " ")
|
|
}
|
|
|
|
// generateRecommendation creates actionable recommendations
|
|
func generateRecommendation(result *AssessmentResult, intake *UseCaseIntake) string {
|
|
if result.Feasibility == FeasibilityYES {
|
|
return "Fahren Sie mit der Implementierung fort. Beachten Sie die empfohlenen Architektur-Patterns für optimale DSGVO-Konformität."
|
|
}
|
|
|
|
if result.Feasibility == FeasibilityCONDITIONAL {
|
|
if len(result.RequiredControls) > 0 {
|
|
return fmt.Sprintf("Implementieren Sie die %d erforderlichen Kontrollen vor dem Go-Live. Dokumentieren Sie alle Maßnahmen für den Nachweis der Rechenschaftspflicht (Art. 5 DSGVO).", len(result.RequiredControls))
|
|
}
|
|
return "Prüfen Sie die ausgelösten Warnungen und implementieren Sie entsprechende Schutzmaßnahmen."
|
|
}
|
|
|
|
// FeasibilityNO
|
|
return "Der Use Case erfordert grundlegende Änderungen. Prüfen Sie die Alternative-Ansatz-Empfehlung."
|
|
}
|
|
|
|
// generateAlternative creates alternative approach suggestions
|
|
func generateAlternative(result *AssessmentResult, intake *UseCaseIntake) string {
|
|
var suggestions []string
|
|
|
|
// Check specific blocking reasons
|
|
if intake.ModelUsage.Training && intake.DataTypes.PersonalData {
|
|
suggestions = append(suggestions, "Nutzen Sie nur RAG statt Training mit personenbezogenen Daten")
|
|
}
|
|
|
|
if intake.Automation == AutomationFullyAutomated && intake.Outputs.LegalEffects {
|
|
suggestions = append(suggestions, "Implementieren Sie Human-in-the-Loop für Entscheidungen mit rechtlichen Auswirkungen")
|
|
}
|
|
|
|
if intake.DataTypes.MinorData && intake.Purpose.EvaluationScoring {
|
|
suggestions = append(suggestions, "Verzichten Sie auf automatisches Scoring von Minderjährigen - nutzen Sie KI nur zur Unterstützung menschlicher Entscheidungsträger")
|
|
}
|
|
|
|
if intake.Hosting.Region == "third_country" && intake.DataTypes.PersonalData {
|
|
suggestions = append(suggestions, "Hosten Sie innerhalb der EU oder implementieren Sie Standardvertragsklauseln (SCCs)")
|
|
}
|
|
|
|
if len(suggestions) == 0 {
|
|
return "Überarbeiten Sie den Use Case unter Berücksichtigung der ausgelösten Regeln."
|
|
}
|
|
|
|
return strings.Join(suggestions, ". ") + "."
|
|
}
|
|
|
|
// GetRules returns all rules
|
|
func (e *RuleEngine) GetRules() []Rule {
|
|
return e.rules
|
|
}
|
|
|
|
// ============================================================================
|
|
// Control Definitions
|
|
// ============================================================================
|
|
|
|
var ControlLibrary = map[string]RequiredControl{
|
|
"C-CONSENT": {
|
|
ID: "C-CONSENT",
|
|
Title: "Einwilligungsmanagement",
|
|
Description: "Implementieren Sie ein System zur Einholung und Verwaltung von Einwilligungen.",
|
|
Severity: SeverityWARN,
|
|
Category: "organizational",
|
|
GDPRRef: "Art. 7 DSGVO",
|
|
},
|
|
"C-PII-DETECT": {
|
|
ID: "C-PII-DETECT",
|
|
Title: "PII-Erkennung",
|
|
Description: "Implementieren Sie automatische Erkennung personenbezogener Daten.",
|
|
Severity: SeverityWARN,
|
|
Category: "technical",
|
|
GDPRRef: "Art. 32 DSGVO",
|
|
},
|
|
"C-ANONYMIZE": {
|
|
ID: "C-ANONYMIZE",
|
|
Title: "Anonymisierung/Pseudonymisierung",
|
|
Description: "Implementieren Sie Anonymisierung oder Pseudonymisierung vor der Verarbeitung.",
|
|
Severity: SeverityWARN,
|
|
Category: "technical",
|
|
GDPRRef: "Art. 32 DSGVO",
|
|
},
|
|
"C-ACCESS-CONTROL": {
|
|
ID: "C-ACCESS-CONTROL",
|
|
Title: "Zugriffskontrollen",
|
|
Description: "Implementieren Sie rollenbasierte Zugriffskontrollen.",
|
|
Severity: SeverityWARN,
|
|
Category: "technical",
|
|
GDPRRef: "Art. 32 DSGVO",
|
|
},
|
|
"C-AUDIT-LOG": {
|
|
ID: "C-AUDIT-LOG",
|
|
Title: "Audit-Logging",
|
|
Description: "Protokollieren Sie alle Zugriffe und Verarbeitungen.",
|
|
Severity: SeverityINFO,
|
|
Category: "technical",
|
|
GDPRRef: "Art. 5(2) DSGVO",
|
|
},
|
|
"C-RETENTION": {
|
|
ID: "C-RETENTION",
|
|
Title: "Aufbewahrungsfristen",
|
|
Description: "Definieren und implementieren Sie automatische Löschfristen.",
|
|
Severity: SeverityWARN,
|
|
Category: "organizational",
|
|
GDPRRef: "Art. 5(1)(e) DSGVO",
|
|
},
|
|
"C-HITL": {
|
|
ID: "C-HITL",
|
|
Title: "Human-in-the-Loop",
|
|
Description: "Implementieren Sie menschliche Überprüfung für KI-Entscheidungen.",
|
|
Severity: SeverityBLOCK,
|
|
Category: "organizational",
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
},
|
|
"C-TRANSPARENCY": {
|
|
ID: "C-TRANSPARENCY",
|
|
Title: "Transparenz",
|
|
Description: "Informieren Sie Betroffene über KI-Verarbeitung.",
|
|
Severity: SeverityWARN,
|
|
Category: "organizational",
|
|
GDPRRef: "Art. 13/14 DSGVO",
|
|
},
|
|
"C-DSR-PROCESS": {
|
|
ID: "C-DSR-PROCESS",
|
|
Title: "Betroffenenrechte-Prozess",
|
|
Description: "Implementieren Sie Prozesse für Auskunft, Löschung, Berichtigung.",
|
|
Severity: SeverityWARN,
|
|
Category: "organizational",
|
|
GDPRRef: "Art. 15-22 DSGVO",
|
|
},
|
|
"C-DSFA": {
|
|
ID: "C-DSFA",
|
|
Title: "DSFA durchführen",
|
|
Description: "Führen Sie eine Datenschutz-Folgenabschätzung durch.",
|
|
Severity: SeverityWARN,
|
|
Category: "organizational",
|
|
GDPRRef: "Art. 35 DSGVO",
|
|
},
|
|
"C-SCC": {
|
|
ID: "C-SCC",
|
|
Title: "Standardvertragsklauseln",
|
|
Description: "Schließen Sie EU-Standardvertragsklauseln für Drittlandtransfers ab.",
|
|
Severity: SeverityBLOCK,
|
|
Category: "legal",
|
|
GDPRRef: "Art. 46 DSGVO",
|
|
},
|
|
"C-ENCRYPTION": {
|
|
ID: "C-ENCRYPTION",
|
|
Title: "Verschlüsselung",
|
|
Description: "Verschlüsseln Sie Daten in Übertragung und Speicherung.",
|
|
Severity: SeverityWARN,
|
|
Category: "technical",
|
|
GDPRRef: "Art. 32 DSGVO",
|
|
},
|
|
"C-MINOR-CONSENT": {
|
|
ID: "C-MINOR-CONSENT",
|
|
Title: "Elterneinwilligung",
|
|
Description: "Holen Sie Einwilligung der Erziehungsberechtigten ein.",
|
|
Severity: SeverityBLOCK,
|
|
Category: "organizational",
|
|
GDPRRef: "Art. 8 DSGVO",
|
|
},
|
|
"C-ART9-BASIS": {
|
|
ID: "C-ART9-BASIS",
|
|
Title: "Art. 9 Rechtsgrundlage",
|
|
Description: "Dokumentieren Sie die Rechtsgrundlage für besondere Datenkategorien.",
|
|
Severity: SeverityBLOCK,
|
|
Category: "legal",
|
|
GDPRRef: "Art. 9 DSGVO",
|
|
},
|
|
}
|
|
|
|
// GetControlByID returns a control by its ID
|
|
func GetControlByID(id string) *RequiredControl {
|
|
if ctrl, exists := ControlLibrary[id]; exists {
|
|
return &ctrl
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ============================================================================
|
|
// All Rules (~45 rules in 10 categories)
|
|
// ============================================================================
|
|
|
|
var AllRules = []Rule{
|
|
// =========================================================================
|
|
// A. Datenklassifikation (R-001 bis R-006)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-001",
|
|
Category: "A. Datenklassifikation",
|
|
Title: "Personal Data Processing",
|
|
TitleDE: "Verarbeitung personenbezogener Daten",
|
|
Description: "Personal data is being processed",
|
|
DescriptionDE: "Personenbezogene Daten werden verarbeitet",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 5,
|
|
GDPRRef: "Art. 4(1) DSGVO",
|
|
Controls: []string{"C-PII-DETECT", "C-ACCESS-CONTROL"},
|
|
Patterns: []string{"P-PRE-ANON"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Der Use Case verarbeitet personenbezogene Daten. Dies erfordert eine Rechtsgrundlage und entsprechende Schutzmaßnahmen."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-002",
|
|
Category: "A. Datenklassifikation",
|
|
Title: "Special Category Data (Art. 9)",
|
|
TitleDE: "Besondere Kategorien personenbezogener Daten (Art. 9)",
|
|
Description: "Processing of special category data requires explicit consent or legal basis",
|
|
DescriptionDE: "Verarbeitung besonderer Datenkategorien erfordert ausdrückliche Einwilligung oder Rechtsgrundlage",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 20,
|
|
GDPRRef: "Art. 9 DSGVO",
|
|
Controls: []string{"C-ART9-BASIS", "C-DSFA", "C-ENCRYPTION"},
|
|
Patterns: []string{"P-PRE-ANON", "P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.Article9Data
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Besondere Kategorien personenbezogener Daten (Gesundheit, Religion, etc.) erfordern besondere Schutzmaßnahmen und eine spezifische Rechtsgrundlage nach Art. 9 DSGVO."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-003",
|
|
Category: "A. Datenklassifikation",
|
|
Title: "Minor Data Processing",
|
|
TitleDE: "Verarbeitung von Daten Minderjähriger",
|
|
Description: "Processing data of children requires special protections",
|
|
DescriptionDE: "Verarbeitung von Daten Minderjähriger erfordert besonderen Schutz",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 15,
|
|
GDPRRef: "Art. 8 DSGVO",
|
|
Controls: []string{"C-MINOR-CONSENT", "C-DSFA"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.MinorData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Daten von Minderjährigen erfordern besonderen Schutz. Die Einwilligung muss von Erziehungsberechtigten eingeholt werden."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-004",
|
|
Category: "A. Datenklassifikation",
|
|
Title: "Biometric Data",
|
|
TitleDE: "Biometrische Daten",
|
|
Description: "Biometric data processing is high risk",
|
|
DescriptionDE: "Verarbeitung biometrischer Daten ist hochriskant",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 20,
|
|
GDPRRef: "Art. 9 DSGVO",
|
|
Controls: []string{"C-ART9-BASIS", "C-DSFA", "C-ENCRYPTION"},
|
|
Patterns: []string{"P-PRE-ANON"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.BiometricData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Biometrische Daten zur eindeutigen Identifizierung fallen unter Art. 9 DSGVO und erfordern eine DSFA."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-005",
|
|
Category: "A. Datenklassifikation",
|
|
Title: "Location Data",
|
|
TitleDE: "Standortdaten",
|
|
Description: "Location tracking requires transparency and consent",
|
|
DescriptionDE: "Standortverfolgung erfordert Transparenz und Einwilligung",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 10,
|
|
GDPRRef: "Art. 5, Art. 7 DSGVO",
|
|
Controls: []string{"C-CONSENT", "C-TRANSPARENCY"},
|
|
Patterns: []string{"P-LOG-MINIMIZATION"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.LocationData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Standortdaten ermöglichen Bewegungsprofile und erfordern klare Einwilligung und Aufbewahrungslimits."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-006",
|
|
Category: "A. Datenklassifikation",
|
|
Title: "Employee Data",
|
|
TitleDE: "Mitarbeiterdaten",
|
|
Description: "Employee data processing has special considerations",
|
|
DescriptionDE: "Mitarbeiterdatenverarbeitung hat besondere Anforderungen",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 10,
|
|
GDPRRef: "§ 26 BDSG",
|
|
Controls: []string{"C-ACCESS-CONTROL", "C-TRANSPARENCY"},
|
|
Patterns: []string{"P-NAMESPACE-ISOLATION"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.EmployeeData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Mitarbeiterdaten unterliegen zusätzlich dem BDSG § 26 und erfordern klare Zweckbindung."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// B. Zweck & Kontext (R-010 bis R-013)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-010",
|
|
Category: "B. Zweck & Kontext",
|
|
Title: "Marketing with Personal Data",
|
|
TitleDE: "Marketing mit personenbezogenen Daten",
|
|
Description: "Marketing purposes with PII require explicit consent",
|
|
DescriptionDE: "Marketing mit PII erfordert ausdrückliche Einwilligung",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 15,
|
|
GDPRRef: "Art. 6(1)(a) DSGVO",
|
|
Controls: []string{"C-CONSENT", "C-DSR-PROCESS"},
|
|
Patterns: []string{"P-PRE-ANON"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Purpose.Marketing && intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Marketing mit personenbezogenen Daten erfordert ausdrückliche, freiwillige Einwilligung."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-011",
|
|
Category: "B. Zweck & Kontext",
|
|
Title: "Profiling Purpose",
|
|
TitleDE: "Profiling-Zweck",
|
|
Description: "Profiling requires DSFA and transparency",
|
|
DescriptionDE: "Profiling erfordert DSFA und Transparenz",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 15,
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
Controls: []string{"C-DSFA", "C-TRANSPARENCY", "C-DSR-PROCESS"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Purpose.Profiling
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Profiling erfordert eine DSFA und transparente Information der Betroffenen über die Logik und Auswirkungen."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-012",
|
|
Category: "B. Zweck & Kontext",
|
|
Title: "Evaluation/Scoring Purpose",
|
|
TitleDE: "Bewertungs-/Scoring-Zweck",
|
|
Description: "Scoring of individuals requires safeguards",
|
|
DescriptionDE: "Scoring von Personen erfordert Schutzmaßnahmen",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 15,
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
Controls: []string{"C-HITL", "C-TRANSPARENCY"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Purpose.EvaluationScoring
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Bewertung/Scoring von Personen erfordert menschliche Überprüfung und Transparenz über die verwendete Logik."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-013",
|
|
Category: "B. Zweck & Kontext",
|
|
Title: "Customer Support - Low Risk",
|
|
TitleDE: "Kundenservice - Niedriges Risiko",
|
|
Description: "Customer support without PII storage is low risk",
|
|
DescriptionDE: "Kundenservice ohne PII-Speicherung ist risikoarm",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{"P-RAG-ONLY"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Purpose.CustomerSupport && !intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Kundenservice mit öffentlichen FAQ-Daten ohne Speicherung personenbezogener Daten ist risikoarm."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// C. Automatisierung (R-020 bis R-025)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-020",
|
|
Category: "C. Automatisierung",
|
|
Title: "Fully Automated with Legal Effects",
|
|
TitleDE: "Vollautomatisiert mit rechtlichen Auswirkungen",
|
|
Description: "Fully automated decisions with legal effects violate Art. 22",
|
|
DescriptionDE: "Vollautomatisierte Entscheidungen mit rechtlichen Auswirkungen verletzen Art. 22",
|
|
Severity: SeverityBLOCK,
|
|
ScoreDelta: 40,
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
Controls: []string{"C-HITL"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Automation == AutomationFullyAutomated && intake.Outputs.LegalEffects
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Vollautomatisierte Entscheidungen mit rechtlichen Auswirkungen ohne menschliche Beteiligung sind nach Art. 22 DSGVO unzulässig."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-021",
|
|
Category: "C. Automatisierung",
|
|
Title: "Fully Automated Rankings/Scores",
|
|
TitleDE: "Vollautomatisierte Rankings/Scores",
|
|
Description: "Automated scoring requires human review",
|
|
DescriptionDE: "Automatisches Scoring erfordert menschliche Überprüfung",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 20,
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
Controls: []string{"C-HITL", "C-TRANSPARENCY"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Automation == AutomationFullyAutomated && intake.Outputs.RankingsOrScores
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Vollautomatisierte Erstellung von Rankings oder Scores erfordert menschliche Überprüfung vor Verwendung."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-022",
|
|
Category: "C. Automatisierung",
|
|
Title: "Fully Automated Access Decisions",
|
|
TitleDE: "Vollautomatisierte Zugriffsentscheidungen",
|
|
Description: "Automated access decisions need safeguards",
|
|
DescriptionDE: "Automatisierte Zugriffsentscheidungen benötigen Schutzmaßnahmen",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 15,
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
Controls: []string{"C-HITL", "C-TRANSPARENCY", "C-DSR-PROCESS"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Automation == AutomationFullyAutomated && intake.Outputs.AccessDecisions
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Automatisierte Entscheidungen über Zugang erfordern Widerspruchsmöglichkeit und menschliche Überprüfung."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-023",
|
|
Category: "C. Automatisierung",
|
|
Title: "Semi-Automated - Medium Risk",
|
|
TitleDE: "Teilautomatisiert - Mittleres Risiko",
|
|
Description: "Semi-automated processing with human review",
|
|
DescriptionDE: "Teilautomatisierte Verarbeitung mit menschlicher Überprüfung",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 5,
|
|
GDPRRef: "",
|
|
Controls: []string{"C-AUDIT-LOG"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Automation == AutomationSemiAutomated && intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Teilautomatisierte Verarbeitung mit menschlicher Überprüfung ist grundsätzlich konform, erfordert aber Dokumentation."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-024",
|
|
Category: "C. Automatisierung",
|
|
Title: "Assistive Only - Low Risk",
|
|
TitleDE: "Nur assistierend - Niedriges Risiko",
|
|
Description: "Assistive AI without automated decisions is low risk",
|
|
DescriptionDE: "Assistive KI ohne automatisierte Entscheidungen ist risikoarm",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{"P-RAG-ONLY"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Automation == AutomationAssistive
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Rein assistive KI, die nur Vorschläge macht und keine Entscheidungen trifft, ist risikoarm."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-025",
|
|
Category: "C. Automatisierung",
|
|
Title: "HR Scoring - Blocked",
|
|
TitleDE: "HR-Scoring - Blockiert",
|
|
Description: "Automated HR scoring/evaluation is prohibited",
|
|
DescriptionDE: "Automatisiertes HR-Scoring/Bewertung ist verboten",
|
|
Severity: SeverityBLOCK,
|
|
ScoreDelta: 50,
|
|
GDPRRef: "Art. 22, § 26 BDSG",
|
|
Controls: []string{"C-HITL"},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Domain == DomainHR &&
|
|
intake.Purpose.EvaluationScoring &&
|
|
intake.Automation == AutomationFullyAutomated
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Vollautomatisierte Bewertung/Scoring von Mitarbeitern ist unzulässig. Arbeitsrechtliche Entscheidungen müssen von Menschen getroffen werden."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// D. Training vs Nutzung (R-030 bis R-035)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-030",
|
|
Category: "D. Training vs Nutzung",
|
|
Title: "Training with Personal Data",
|
|
TitleDE: "Training mit personenbezogenen Daten",
|
|
Description: "Training AI with personal data is high risk",
|
|
DescriptionDE: "Training von KI mit personenbezogenen Daten ist hochriskant",
|
|
Severity: SeverityBLOCK,
|
|
ScoreDelta: 40,
|
|
GDPRRef: "Art. 5(1)(b)(c) DSGVO",
|
|
Controls: []string{"C-ART9-BASIS", "C-DSFA"},
|
|
Patterns: []string{"P-RAG-ONLY"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.ModelUsage.Training && intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Training von KI-Modellen mit personenbezogenen Daten verstößt gegen Zweckbindung und Datenminimierung. Nutzen Sie stattdessen RAG."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-031",
|
|
Category: "D. Training vs Nutzung",
|
|
Title: "Fine-tuning with Personal Data",
|
|
TitleDE: "Fine-Tuning mit personenbezogenen Daten",
|
|
Description: "Fine-tuning with PII requires safeguards",
|
|
DescriptionDE: "Fine-Tuning mit PII erfordert Schutzmaßnahmen",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 25,
|
|
GDPRRef: "Art. 5(1)(b)(c) DSGVO",
|
|
Controls: []string{"C-ANONYMIZE", "C-DSFA"},
|
|
Patterns: []string{"P-PRE-ANON"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.ModelUsage.Finetune && intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Fine-Tuning mit personenbezogenen Daten ist nur nach Anonymisierung/Pseudonymisierung zulässig."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-032",
|
|
Category: "D. Training vs Nutzung",
|
|
Title: "RAG Only - Recommended",
|
|
TitleDE: "Nur RAG - Empfohlen",
|
|
Description: "RAG without training is the safest approach",
|
|
DescriptionDE: "RAG ohne Training ist der sicherste Ansatz",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{"P-RAG-ONLY"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.ModelUsage.RAG && !intake.ModelUsage.Training && !intake.ModelUsage.Finetune
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Nur-RAG ohne Training oder Fine-Tuning ist die empfohlene Architektur für DSGVO-Konformität."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-033",
|
|
Category: "D. Training vs Nutzung",
|
|
Title: "Training with Article 9 Data",
|
|
TitleDE: "Training mit Art. 9 Daten",
|
|
Description: "Training with special category data is prohibited",
|
|
DescriptionDE: "Training mit besonderen Datenkategorien ist verboten",
|
|
Severity: SeverityBLOCK,
|
|
ScoreDelta: 50,
|
|
GDPRRef: "Art. 9 DSGVO",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return (intake.ModelUsage.Training || intake.ModelUsage.Finetune) && intake.DataTypes.Article9Data
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Training oder Fine-Tuning mit besonderen Kategorien personenbezogener Daten (Gesundheit, Religion, etc.) ist grundsätzlich unzulässig."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-034",
|
|
Category: "D. Training vs Nutzung",
|
|
Title: "Inference with Public Data",
|
|
TitleDE: "Inferenz mit öffentlichen Daten",
|
|
Description: "Using only public data is low risk",
|
|
DescriptionDE: "Nutzung nur öffentlicher Daten ist risikoarm",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.PublicData && !intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Die ausschließliche Nutzung öffentlich zugänglicher Daten ohne Personenbezug ist unproblematisch."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-035",
|
|
Category: "D. Training vs Nutzung",
|
|
Title: "Training with Minor Data",
|
|
TitleDE: "Training mit Daten Minderjähriger",
|
|
Description: "Training with children's data is prohibited",
|
|
DescriptionDE: "Training mit Kinderdaten ist verboten",
|
|
Severity: SeverityBLOCK,
|
|
ScoreDelta: 50,
|
|
GDPRRef: "Art. 8 DSGVO, ErwG 38",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return (intake.ModelUsage.Training || intake.ModelUsage.Finetune) && intake.DataTypes.MinorData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Training von KI-Modellen mit Daten von Minderjährigen ist aufgrund des besonderen Schutzes unzulässig."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// E. Speicherung (R-040 bis R-042)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-040",
|
|
Category: "E. Speicherung",
|
|
Title: "Storing Prompts with PII",
|
|
TitleDE: "Speicherung von Prompts mit PII",
|
|
Description: "Storing prompts containing PII requires controls",
|
|
DescriptionDE: "Speicherung von Prompts mit PII erfordert Kontrollen",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 15,
|
|
GDPRRef: "Art. 5(1)(e) DSGVO",
|
|
Controls: []string{"C-RETENTION", "C-ANONYMIZE", "C-DSR-PROCESS"},
|
|
Patterns: []string{"P-LOG-MINIMIZATION", "P-PRE-ANON"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Retention.StorePrompts && intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Speicherung von Prompts mit personenbezogenen Daten erfordert Löschfristen und Anonymisierungsoptionen."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-041",
|
|
Category: "E. Speicherung",
|
|
Title: "Storing Responses with PII",
|
|
TitleDE: "Speicherung von Antworten mit PII",
|
|
Description: "Storing AI responses containing PII requires controls",
|
|
DescriptionDE: "Speicherung von KI-Antworten mit PII erfordert Kontrollen",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 10,
|
|
GDPRRef: "Art. 5(1)(e) DSGVO",
|
|
Controls: []string{"C-RETENTION", "C-DSR-PROCESS"},
|
|
Patterns: []string{"P-LOG-MINIMIZATION"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Retention.StoreResponses && intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Speicherung von KI-Antworten mit personenbezogenen Daten erfordert definierte Aufbewahrungsfristen."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-042",
|
|
Category: "E. Speicherung",
|
|
Title: "No Retention Policy",
|
|
TitleDE: "Keine Aufbewahrungsrichtlinie",
|
|
Description: "PII storage without retention limits is problematic",
|
|
DescriptionDE: "PII-Speicherung ohne Aufbewahrungslimits ist problematisch",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 10,
|
|
GDPRRef: "Art. 5(1)(e) DSGVO",
|
|
Controls: []string{"C-RETENTION"},
|
|
Patterns: []string{"P-LOG-MINIMIZATION"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return (intake.Retention.StorePrompts || intake.Retention.StoreResponses) &&
|
|
intake.DataTypes.PersonalData &&
|
|
intake.Retention.RetentionDays == 0
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Speicherung personenbezogener Daten ohne definierte Aufbewahrungsfrist verstößt gegen den Grundsatz der Speicherbegrenzung."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// F. Hosting (R-050 bis R-052)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-050",
|
|
Category: "F. Hosting",
|
|
Title: "Third Country Transfer with PII",
|
|
TitleDE: "Drittlandtransfer mit PII",
|
|
Description: "Transferring PII to third countries requires safeguards",
|
|
DescriptionDE: "Übermittlung von PII in Drittländer erfordert Schutzmaßnahmen",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 20,
|
|
GDPRRef: "Art. 44-49 DSGVO",
|
|
Controls: []string{"C-SCC", "C-ENCRYPTION"},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Hosting.Region == "third_country" && intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Übermittlung personenbezogener Daten in Drittländer erfordert Standardvertragsklauseln oder andere geeignete Garantien."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-051",
|
|
Category: "F. Hosting",
|
|
Title: "EU Hosting - Compliant",
|
|
TitleDE: "EU-Hosting - Konform",
|
|
Description: "Hosting within EU is compliant with GDPR",
|
|
DescriptionDE: "Hosting innerhalb der EU ist DSGVO-konform",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Hosting.Region == "eu"
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Hosting innerhalb der EU/EWR erfüllt grundsätzlich die DSGVO-Anforderungen an den Datenstandort."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-052",
|
|
Category: "F. Hosting",
|
|
Title: "On-Premise Hosting",
|
|
TitleDE: "On-Premise-Hosting",
|
|
Description: "On-premise hosting gives most control",
|
|
DescriptionDE: "On-Premise-Hosting gibt die meiste Kontrolle",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{"C-ENCRYPTION"},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Hosting.Region == "on_prem"
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "On-Premise-Hosting bietet maximale Kontrolle über Daten, erfordert aber eigene Sicherheitsmaßnahmen."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// G. Transparenz (R-060 bis R-062)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-060",
|
|
Category: "G. Transparenz",
|
|
Title: "No Human Review for Decisions",
|
|
TitleDE: "Keine menschliche Überprüfung bei Entscheidungen",
|
|
Description: "Decisions affecting individuals need human review option",
|
|
DescriptionDE: "Entscheidungen, die Personen betreffen, benötigen menschliche Überprüfungsoption",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 15,
|
|
GDPRRef: "Art. 22(3) DSGVO",
|
|
Controls: []string{"C-HITL", "C-DSR-PROCESS"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return (intake.Outputs.LegalEffects || intake.Outputs.AccessDecisions || intake.Purpose.DecisionMaking) &&
|
|
intake.Automation != AutomationAssistive
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Betroffene haben das Recht auf menschliche Überprüfung bei automatisierten Entscheidungen."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-061",
|
|
Category: "G. Transparenz",
|
|
Title: "External Recommendations",
|
|
TitleDE: "Externe Empfehlungen",
|
|
Description: "Recommendations to users need transparency",
|
|
DescriptionDE: "Empfehlungen an Nutzer erfordern Transparenz",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 5,
|
|
GDPRRef: "Art. 13/14 DSGVO",
|
|
Controls: []string{"C-TRANSPARENCY"},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Outputs.RecommendationsToUsers && intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Personalisierte Empfehlungen erfordern Information der Nutzer über die KI-Verarbeitung."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-062",
|
|
Category: "G. Transparenz",
|
|
Title: "Content Generation without Disclosure",
|
|
TitleDE: "Inhaltsgenerierung ohne Offenlegung",
|
|
Description: "AI-generated content should be disclosed",
|
|
DescriptionDE: "KI-generierte Inhalte sollten offengelegt werden",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 5,
|
|
GDPRRef: "EU-AI-Act Art. 52",
|
|
Controls: []string{"C-TRANSPARENCY"},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Outputs.ContentGeneration
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "KI-generierte Inhalte sollten als solche gekennzeichnet werden (EU-AI-Act Transparenzpflicht)."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// H. Domain-spezifisch (R-070 bis R-074)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-070",
|
|
Category: "H. Domain-spezifisch",
|
|
Title: "Education + Scoring = Blocked",
|
|
TitleDE: "Bildung + Scoring = Blockiert",
|
|
Description: "Automated scoring of students is prohibited",
|
|
DescriptionDE: "Automatisches Scoring von Schülern ist verboten",
|
|
Severity: SeverityBLOCK,
|
|
ScoreDelta: 50,
|
|
GDPRRef: "Art. 8, Art. 22 DSGVO",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Domain == DomainEducation &&
|
|
intake.DataTypes.MinorData &&
|
|
(intake.Purpose.EvaluationScoring || intake.Outputs.RankingsOrScores)
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Automatisches Scoring oder Ranking von Schülern/Minderjährigen ist aufgrund des besonderen Schutzes unzulässig."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-071",
|
|
Category: "H. Domain-spezifisch",
|
|
Title: "Healthcare + Automated Diagnosis",
|
|
TitleDE: "Gesundheit + Automatische Diagnose",
|
|
Description: "Automated medical decisions require strict controls",
|
|
DescriptionDE: "Automatische medizinische Entscheidungen erfordern strenge Kontrollen",
|
|
Severity: SeverityBLOCK,
|
|
ScoreDelta: 45,
|
|
GDPRRef: "Art. 9, Art. 22 DSGVO",
|
|
Controls: []string{"C-HITL", "C-DSFA", "C-ART9-BASIS"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Domain == DomainHealthcare &&
|
|
intake.Automation == AutomationFullyAutomated &&
|
|
intake.Purpose.DecisionMaking
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Vollautomatisierte medizinische Diagnosen oder Behandlungsentscheidungen sind ohne ärztliche Überprüfung unzulässig."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-072",
|
|
Category: "H. Domain-spezifisch",
|
|
Title: "Finance + Automated Credit Scoring",
|
|
TitleDE: "Finanzen + Automatisches Credit-Scoring",
|
|
Description: "Automated credit decisions require transparency",
|
|
DescriptionDE: "Automatische Kreditentscheidungen erfordern Transparenz",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 20,
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
Controls: []string{"C-HITL", "C-TRANSPARENCY", "C-DSR-PROCESS"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Domain == DomainFinance &&
|
|
(intake.Purpose.EvaluationScoring || intake.Outputs.RankingsOrScores) &&
|
|
intake.DataTypes.FinancialData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Automatische Kreditwürdigkeitsprüfung erfordert Erklärbarkeit und Widerspruchsmöglichkeit."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-073",
|
|
Category: "H. Domain-spezifisch",
|
|
Title: "Utilities + RAG Chatbot = Low Risk",
|
|
TitleDE: "Versorgungsunternehmen + RAG-Chatbot = Niedriges Risiko",
|
|
Description: "RAG-based customer service chatbot is low risk",
|
|
DescriptionDE: "RAG-basierter Kundenservice-Chatbot ist risikoarm",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{"P-RAG-ONLY"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Domain == DomainUtilities &&
|
|
intake.ModelUsage.RAG &&
|
|
intake.Purpose.CustomerSupport &&
|
|
!intake.DataTypes.PersonalData
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Ein RAG-basierter Kundenservice-Chatbot ohne Speicherung personenbezogener Daten ist ein Best-Practice-Beispiel."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-074",
|
|
Category: "H. Domain-spezifisch",
|
|
Title: "Public Sector + Automated Decisions",
|
|
TitleDE: "Öffentlicher Sektor + Automatische Entscheidungen",
|
|
Description: "Public sector automated decisions need special care",
|
|
DescriptionDE: "Automatische Entscheidungen im öffentlichen Sektor erfordern besondere Sorgfalt",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 20,
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
Controls: []string{"C-HITL", "C-TRANSPARENCY", "C-DSFA"},
|
|
Patterns: []string{"P-HITL-ENFORCED"},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
return intake.Domain == DomainPublic &&
|
|
intake.Purpose.DecisionMaking &&
|
|
intake.Automation != AutomationAssistive
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Verwaltungsentscheidungen, die Bürger betreffen, erfordern besondere Transparenz und Überprüfungsmöglichkeiten."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// I. Aggregation (R-090 bis R-092) - Implicit in Evaluate()
|
|
// =========================================================================
|
|
{
|
|
Code: "R-090",
|
|
Category: "I. Aggregation",
|
|
Title: "Block Rules Triggered",
|
|
TitleDE: "Blockierungsregeln ausgelöst",
|
|
Description: "Any BLOCK severity results in NO feasibility",
|
|
DescriptionDE: "Jede BLOCK-Schwere führt zu NEIN-Machbarkeit",
|
|
Severity: SeverityBLOCK,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
// This is handled in aggregation logic
|
|
return false
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Eine oder mehrere kritische Regelverletzungen führen zur Einstufung als nicht umsetzbar."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-091",
|
|
Category: "I. Aggregation",
|
|
Title: "Warning Rules Only",
|
|
TitleDE: "Nur Warnungsregeln",
|
|
Description: "Only WARN severity results in CONDITIONAL",
|
|
DescriptionDE: "Nur WARN-Schwere führt zu BEDINGT",
|
|
Severity: SeverityWARN,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
// This is handled in aggregation logic
|
|
return false
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Warnungen erfordern Maßnahmen, blockieren aber nicht die Umsetzung."
|
|
},
|
|
},
|
|
{
|
|
Code: "R-092",
|
|
Category: "I. Aggregation",
|
|
Title: "Info Only - Clear Path",
|
|
TitleDE: "Nur Info - Freier Weg",
|
|
Description: "Only INFO severity results in YES",
|
|
DescriptionDE: "Nur INFO-Schwere führt zu JA",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
// This is handled in aggregation logic
|
|
return false
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Keine kritischen oder warnenden Regeln ausgelöst - Umsetzung empfohlen."
|
|
},
|
|
},
|
|
// =========================================================================
|
|
// J. Erklärung (R-100)
|
|
// =========================================================================
|
|
{
|
|
Code: "R-100",
|
|
Category: "J. Erklärung",
|
|
Title: "Rejection Must Include Reason and Alternative",
|
|
TitleDE: "Ablehnung muss Begründung und Alternative enthalten",
|
|
Description: "When feasibility is NO, provide reason and alternative",
|
|
DescriptionDE: "Bei Machbarkeit NEIN, Begründung und Alternative angeben",
|
|
Severity: SeverityINFO,
|
|
ScoreDelta: 0,
|
|
GDPRRef: "",
|
|
Controls: []string{},
|
|
Patterns: []string{},
|
|
Condition: func(intake *UseCaseIntake) bool {
|
|
// This is handled in summary generation
|
|
return false
|
|
},
|
|
Rationale: func(intake *UseCaseIntake) string {
|
|
return "Jede Ablehnung enthält eine klare Begründung und einen alternativen Ansatz."
|
|
},
|
|
},
|
|
}
|