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>
280 lines
11 KiB
Go
280 lines
11 KiB
Go
package ucca
|
|
|
|
// ============================================================================
|
|
// Architecture Patterns - Hardcoded recommendations
|
|
// ============================================================================
|
|
|
|
// Pattern represents an architecture pattern recommendation
|
|
type Pattern struct {
|
|
ID string `json:"id"`
|
|
Title string `json:"title"`
|
|
TitleDE string `json:"title_de"`
|
|
Description string `json:"description"`
|
|
DescriptionDE string `json:"description_de"`
|
|
Benefits []string `json:"benefits"`
|
|
Requirements []string `json:"requirements"`
|
|
ApplicableWhen func(intake *UseCaseIntake) bool `json:"-"`
|
|
}
|
|
|
|
// PatternLibrary contains all available architecture patterns
|
|
var PatternLibrary = []Pattern{
|
|
{
|
|
ID: "P-RAG-ONLY",
|
|
Title: "RAG-Only Architecture",
|
|
TitleDE: "Nur-RAG-Architektur",
|
|
Description: "Use Retrieval-Augmented Generation without storing or training on personal data. The LLM only receives anonymized context from a vector database, never raw personal data.",
|
|
DescriptionDE: "Nutzen Sie Retrieval-Augmented Generation ohne Speicherung oder Training mit personenbezogenen Daten. Das LLM erhält nur anonymisierten Kontext aus einer Vektor-Datenbank, niemals Rohdaten.",
|
|
Benefits: []string{
|
|
"No personal data in model weights",
|
|
"Easy to delete/update information",
|
|
"Audit trail for all retrievals",
|
|
"Minimal GDPR compliance burden",
|
|
},
|
|
Requirements: []string{
|
|
"Vector database with access controls",
|
|
"Pre-anonymization pipeline",
|
|
"Query logging for audit",
|
|
},
|
|
ApplicableWhen: func(intake *UseCaseIntake) bool {
|
|
// Applicable when using RAG and dealing with personal data
|
|
return intake.ModelUsage.RAG && (intake.DataTypes.PersonalData || intake.DataTypes.CustomerData)
|
|
},
|
|
},
|
|
{
|
|
ID: "P-PRE-ANON",
|
|
Title: "Pre-Anonymization Pipeline",
|
|
TitleDE: "Vor-Anonymisierungs-Pipeline",
|
|
Description: "Implement mandatory anonymization/pseudonymization before any data reaches the AI system. Personal identifiers are replaced with tokens that can be resolved only by authorized systems.",
|
|
DescriptionDE: "Implementieren Sie eine verpflichtende Anonymisierung/Pseudonymisierung bevor Daten das KI-System erreichen. Persönliche Identifikatoren werden durch Tokens ersetzt, die nur von autorisierten Systemen aufgelöst werden können.",
|
|
Benefits: []string{
|
|
"Personal data never reaches AI",
|
|
"Reversible for authorized access",
|
|
"Compliant with Art. 32 GDPR",
|
|
"Reduces data breach impact",
|
|
},
|
|
Requirements: []string{
|
|
"PII detection system",
|
|
"Token mapping database (secured)",
|
|
"Re-identification access controls",
|
|
"Audit logging for re-identification",
|
|
},
|
|
ApplicableWhen: func(intake *UseCaseIntake) bool {
|
|
// Applicable when handling personal data and not public data only
|
|
return intake.DataTypes.PersonalData && !intake.DataTypes.PublicData
|
|
},
|
|
},
|
|
{
|
|
ID: "P-NAMESPACE-ISOLATION",
|
|
Title: "Namespace Isolation",
|
|
TitleDE: "Namespace-Isolation",
|
|
Description: "Strict separation of data and models per tenant/department. Each namespace has its own vector store, model context, and access controls. No data leakage between tenants.",
|
|
DescriptionDE: "Strikte Trennung von Daten und Modellen pro Mandant/Abteilung. Jeder Namespace hat eigenen Vektor-Speicher, Modellkontext und Zugriffskontrollen. Keine Datenlecks zwischen Mandanten.",
|
|
Benefits: []string{
|
|
"Multi-tenant compliance",
|
|
"Clear data ownership",
|
|
"Easy audit per namespace",
|
|
"Deletion per namespace",
|
|
},
|
|
Requirements: []string{
|
|
"Multi-tenant architecture",
|
|
"Namespace-aware APIs",
|
|
"Access control per namespace",
|
|
"Separate encryption keys",
|
|
},
|
|
ApplicableWhen: func(intake *UseCaseIntake) bool {
|
|
// Applicable for multi-tenant scenarios or when handling different data types
|
|
return intake.DataTypes.CustomerData || intake.DataTypes.EmployeeData
|
|
},
|
|
},
|
|
{
|
|
ID: "P-HITL-ENFORCED",
|
|
Title: "Human-in-the-Loop Enforcement",
|
|
TitleDE: "Verpflichtende menschliche Kontrolle",
|
|
Description: "Mandatory human review before any AI output affects individuals. The AI provides suggestions, but final decisions require human approval. Audit trail for all decisions.",
|
|
DescriptionDE: "Verpflichtende menschliche Überprüfung bevor KI-Ausgaben Personen betreffen. Die KI liefert Vorschläge, aber finale Entscheidungen erfordern menschliche Genehmigung. Prüfpfad für alle Entscheidungen.",
|
|
Benefits: []string{
|
|
"Art. 22 GDPR compliance",
|
|
"Accountability clear",
|
|
"Error correction possible",
|
|
"Human judgment preserved",
|
|
},
|
|
Requirements: []string{
|
|
"Review workflow system",
|
|
"Decision audit logging",
|
|
"Clear escalation paths",
|
|
"Training for reviewers",
|
|
},
|
|
ApplicableWhen: func(intake *UseCaseIntake) bool {
|
|
// Applicable when outputs have legal effects or involve scoring/decisions
|
|
return intake.Outputs.LegalEffects ||
|
|
intake.Outputs.RankingsOrScores ||
|
|
intake.Outputs.AccessDecisions ||
|
|
intake.Purpose.EvaluationScoring ||
|
|
intake.Purpose.DecisionMaking
|
|
},
|
|
},
|
|
{
|
|
ID: "P-LOG-MINIMIZATION",
|
|
Title: "Log Minimization",
|
|
TitleDE: "Log-Minimierung",
|
|
Description: "Minimize logging of personal data in AI interactions. Store only anonymized metrics, not raw prompts/responses. Implement automatic log rotation and deletion.",
|
|
DescriptionDE: "Minimieren Sie die Protokollierung personenbezogener Daten in KI-Interaktionen. Speichern Sie nur anonymisierte Metriken, keine Roh-Prompts/Antworten. Implementieren Sie automatische Log-Rotation und Löschung.",
|
|
Benefits: []string{
|
|
"Data minimization (Art. 5c GDPR)",
|
|
"Reduced storage costs",
|
|
"Simplified deletion requests",
|
|
"Lower breach impact",
|
|
},
|
|
Requirements: []string{
|
|
"Log anonymization pipeline",
|
|
"Automatic log rotation",
|
|
"Metrics without PII",
|
|
"Retention policy enforcement",
|
|
},
|
|
ApplicableWhen: func(intake *UseCaseIntake) bool {
|
|
// Applicable when storing prompts/responses
|
|
return intake.Retention.StorePrompts || intake.Retention.StoreResponses
|
|
},
|
|
},
|
|
}
|
|
|
|
// GetApplicablePatterns returns patterns applicable for the given intake
|
|
func GetApplicablePatterns(intake *UseCaseIntake) []Pattern {
|
|
var applicable []Pattern
|
|
for _, p := range PatternLibrary {
|
|
if p.ApplicableWhen(intake) {
|
|
applicable = append(applicable, p)
|
|
}
|
|
}
|
|
return applicable
|
|
}
|
|
|
|
// GetPatternByID returns a pattern by its ID
|
|
func GetPatternByID(id string) *Pattern {
|
|
for _, p := range PatternLibrary {
|
|
if p.ID == id {
|
|
return &p
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetAllPatterns returns all available patterns
|
|
func GetAllPatterns() []Pattern {
|
|
return PatternLibrary
|
|
}
|
|
|
|
// PatternToRecommendation converts a Pattern to a PatternRecommendation
|
|
func PatternToRecommendation(p Pattern, rationale string, priority int) PatternRecommendation {
|
|
return PatternRecommendation{
|
|
PatternID: p.ID,
|
|
Title: p.TitleDE,
|
|
Description: p.DescriptionDE,
|
|
Rationale: rationale,
|
|
Priority: priority,
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Forbidden Pattern Definitions
|
|
// ============================================================================
|
|
|
|
// ForbiddenPatternDef defines patterns that should NOT be used
|
|
type ForbiddenPatternDef struct {
|
|
ID string
|
|
Title string
|
|
TitleDE string
|
|
Description string
|
|
DescriptionDE string
|
|
Reason string
|
|
ReasonDE string
|
|
GDPRRef string
|
|
ForbiddenWhen func(intake *UseCaseIntake) bool
|
|
}
|
|
|
|
// ForbiddenPatternLibrary contains all forbidden pattern definitions
|
|
var ForbiddenPatternLibrary = []ForbiddenPatternDef{
|
|
{
|
|
ID: "FP-DIRECT-PII-TRAINING",
|
|
Title: "Direct PII Training",
|
|
TitleDE: "Direktes Training mit personenbezogenen Daten",
|
|
Description: "Training AI models directly on personal data without proper legal basis or consent.",
|
|
DescriptionDE: "Training von KI-Modellen direkt mit personenbezogenen Daten ohne ausreichende Rechtsgrundlage oder Einwilligung.",
|
|
Reason: "Violates GDPR purpose limitation and data minimization principles.",
|
|
ReasonDE: "Verstößt gegen DSGVO-Grundsätze der Zweckbindung und Datenminimierung.",
|
|
GDPRRef: "Art. 5(1)(b)(c) DSGVO",
|
|
ForbiddenWhen: func(intake *UseCaseIntake) bool {
|
|
return intake.ModelUsage.Training && intake.DataTypes.PersonalData
|
|
},
|
|
},
|
|
{
|
|
ID: "FP-ART9-WITHOUT-CONSENT",
|
|
Title: "Special Category Data Without Explicit Consent",
|
|
TitleDE: "Besondere Kategorien ohne ausdrückliche Einwilligung",
|
|
Description: "Processing special category data (health, religion, etc.) without explicit consent or legal basis.",
|
|
DescriptionDE: "Verarbeitung besonderer Datenkategorien (Gesundheit, Religion, etc.) ohne ausdrückliche Einwilligung oder Rechtsgrundlage.",
|
|
Reason: "Article 9 data requires explicit consent or specific legal basis.",
|
|
ReasonDE: "Art. 9-Daten erfordern ausdrückliche Einwilligung oder spezifische Rechtsgrundlage.",
|
|
GDPRRef: "Art. 9 DSGVO",
|
|
ForbiddenWhen: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.Article9Data
|
|
},
|
|
},
|
|
{
|
|
ID: "FP-AUTOMATED-LEGAL-DECISION",
|
|
Title: "Fully Automated Legal Decisions",
|
|
TitleDE: "Vollautomatisierte rechtliche Entscheidungen",
|
|
Description: "Making fully automated decisions with legal effects without human oversight.",
|
|
DescriptionDE: "Treffen vollautomatisierter Entscheidungen mit rechtlichen Auswirkungen ohne menschliche Aufsicht.",
|
|
Reason: "Article 22 GDPR restricts automated individual decision-making.",
|
|
ReasonDE: "Art. 22 DSGVO beschränkt automatisierte Einzelentscheidungen.",
|
|
GDPRRef: "Art. 22 DSGVO",
|
|
ForbiddenWhen: func(intake *UseCaseIntake) bool {
|
|
return intake.Automation == AutomationFullyAutomated && intake.Outputs.LegalEffects
|
|
},
|
|
},
|
|
{
|
|
ID: "FP-MINOR-PROFILING",
|
|
Title: "Profiling of Minors",
|
|
TitleDE: "Profiling von Minderjährigen",
|
|
Description: "Creating profiles or scores for children/minors.",
|
|
DescriptionDE: "Erstellen von Profilen oder Scores für Kinder/Minderjährige.",
|
|
Reason: "Special protection for minors under GDPR.",
|
|
ReasonDE: "Besonderer Schutz für Minderjährige unter der DSGVO.",
|
|
GDPRRef: "Art. 8, Erwägungsgrund 38 DSGVO",
|
|
ForbiddenWhen: func(intake *UseCaseIntake) bool {
|
|
return intake.DataTypes.MinorData && (intake.Purpose.Profiling || intake.Purpose.EvaluationScoring)
|
|
},
|
|
},
|
|
{
|
|
ID: "FP-THIRD-COUNTRY-PII",
|
|
Title: "PII Transfer to Third Countries",
|
|
TitleDE: "Übermittlung personenbezogener Daten in Drittländer",
|
|
Description: "Transferring personal data to third countries without adequate safeguards.",
|
|
DescriptionDE: "Übermittlung personenbezogener Daten in Drittländer ohne angemessene Schutzmaßnahmen.",
|
|
Reason: "Requires adequacy decision or appropriate safeguards.",
|
|
ReasonDE: "Erfordert Angemessenheitsbeschluss oder geeignete Garantien.",
|
|
GDPRRef: "Art. 44-49 DSGVO",
|
|
ForbiddenWhen: func(intake *UseCaseIntake) bool {
|
|
return intake.Hosting.Region == "third_country" && intake.DataTypes.PersonalData
|
|
},
|
|
},
|
|
}
|
|
|
|
// GetForbiddenPatterns returns forbidden patterns for the given intake
|
|
func GetForbiddenPatterns(intake *UseCaseIntake) []ForbiddenPattern {
|
|
var forbidden []ForbiddenPattern
|
|
for _, fp := range ForbiddenPatternLibrary {
|
|
if fp.ForbiddenWhen(intake) {
|
|
forbidden = append(forbidden, ForbiddenPattern{
|
|
PatternID: fp.ID,
|
|
Title: fp.TitleDE,
|
|
Description: fp.DescriptionDE,
|
|
Reason: fp.ReasonDE,
|
|
GDPRRef: fp.GDPRRef,
|
|
})
|
|
}
|
|
}
|
|
return forbidden
|
|
}
|