All checks were successful
CI/CD / go-lint (push) Has been skipped
CI/CD / python-lint (push) Has been skipped
CI/CD / nodejs-lint (push) Has been skipped
CI/CD / test-go-ai-compliance (push) Successful in 40s
CI/CD / test-python-backend-compliance (push) Successful in 39s
CI/CD / test-python-document-crawler (push) Successful in 30s
CI/CD / test-python-dsms-gateway (push) Successful in 24s
CI/CD / validate-canonical-controls (push) Successful in 15s
CI/CD / Deploy (push) Successful in 3s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1033 lines
32 KiB
Markdown
1033 lines
32 KiB
Markdown
# AI Compliance SDK - Entwickler-Dokumentation
|
||
|
||
## Inhaltsverzeichnis
|
||
|
||
1. [Schnellstart](#1-schnellstart)
|
||
2. [Architektur-Übersicht](#2-architektur-übersicht)
|
||
3. [Policy Engine](#3-policy-engine)
|
||
4. [License Policy Engine](#4-license-policy-engine)
|
||
5. [Legal RAG Integration](#5-legal-rag-integration)
|
||
6. [Wizard & Legal Assistant](#6-wizard--legal-assistant)
|
||
7. [Eskalations-System](#7-eskalations-system)
|
||
8. [API-Endpoints](#8-api-endpoints)
|
||
9. [Policy-Dateien](#9-policy-dateien)
|
||
10. [Tests ausführen](#10-tests-ausführen)
|
||
11. [Generic Obligations Framework](#11-generic-obligations-framework)
|
||
12. [Tests für Obligations Framework](#12-tests-für-obligations-framework)
|
||
13. [DSFA (Datenschutz-Folgenabschätzung)](#13-dsfa-datenschutz-folgenabschätzung-nach-art-35-dsgvo)
|
||
|
||
---
|
||
|
||
## 1. Schnellstart
|
||
|
||
### Voraussetzungen
|
||
|
||
- Go 1.21+
|
||
- PostgreSQL (für Eskalations-Store)
|
||
- Qdrant (für Legal RAG)
|
||
- Ollama oder Anthropic API Key (für LLM)
|
||
|
||
### Build & Run
|
||
|
||
```bash
|
||
# Build (lokal)
|
||
cd ai-compliance-sdk
|
||
go build -o server ./cmd/server
|
||
|
||
# Run (lokal)
|
||
./server --config config.yaml
|
||
|
||
# Production: CI/CD (automatisch bei Push auf main)
|
||
git push origin main && git push gitea main
|
||
# → Gitea Actions: Tests → Build → Deploy auf Coolify
|
||
# → Status: https://gitea.meghsakha.com/Benjamin_Boenisch/breakpilot-compliance/actions
|
||
|
||
# Alternativ: mit Docker (lokal)
|
||
docker compose up -d
|
||
```
|
||
|
||
### Erste Anfrage
|
||
|
||
```bash
|
||
# UCCA Assessment erstellen
|
||
curl -X POST http://localhost:8080/sdk/v1/ucca/assess \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"use_case_text": "Chatbot für Kundenservice mit FAQ-Suche",
|
||
"domain": "utilities",
|
||
"data_types": {
|
||
"personal_data": false,
|
||
"public_data": true
|
||
},
|
||
"automation": "assistive",
|
||
"model_usage": {
|
||
"rag": true
|
||
},
|
||
"hosting": {
|
||
"region": "eu"
|
||
}
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Architektur-Übersicht
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ API Layer (Gin) │
|
||
│ internal/api/handlers/ │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
|
||
│ │ UCCA │ │ License │ │ Eskalation │ │
|
||
│ │ Handler │ │ Handler │ │ Handler │ │
|
||
│ └──────┬──────┘ └──────┬──────┘ └───────────┬─────────────┘ │
|
||
│ │ │ │ │
|
||
├─────────┼────────────────┼──────────────────────┼────────────────┤
|
||
│ ▼ ▼ ▼ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
|
||
│ │ Policy │ │ License │ │ Escalation │ │
|
||
│ │ Engine │ │ Policy │ │ Store │ │
|
||
│ │ │ │ Engine │ │ │ │
|
||
│ └──────┬──────┘ └──────┬──────┘ └───────────┬─────────────┘ │
|
||
│ │ │ │ │
|
||
│ └────────┬───────┴──────────────────────┘ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────┐ │
|
||
│ │ Legal RAG System │ │
|
||
│ │ (Qdrant + LLM Integration) │ │
|
||
│ └─────────────────────────────────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Kernprinzip
|
||
|
||
**LLM ist NICHT die Quelle der Wahrheit!**
|
||
|
||
| Komponente | Entscheidet | LLM-Nutzung |
|
||
|------------|-------------|-------------|
|
||
| Policy Engine | Feasibility, Risk Level | Nein |
|
||
| License Engine | Operation Mode, Stop-Lines | Nein |
|
||
| Gap Mapping | Facts → Gaps → Controls | Nein |
|
||
| Legal RAG | Erklärung generieren | Ja (nur Output) |
|
||
|
||
---
|
||
|
||
## 3. Policy Engine
|
||
|
||
### Übersicht
|
||
|
||
Die Policy Engine (`internal/ucca/policy_engine.go`) evaluiert Use Cases gegen deterministische Regeln.
|
||
|
||
### Verwendung
|
||
|
||
```go
|
||
import "ai-compliance-sdk/internal/ucca"
|
||
|
||
// Engine erstellen
|
||
engine, err := ucca.NewPolicyEngineFromPath("policies/ucca_policy_v1.yaml")
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
// Intake erstellen
|
||
intake := &ucca.UseCaseIntake{
|
||
UseCaseText: "Chatbot für Kundenservice",
|
||
Domain: ucca.DomainUtilities,
|
||
DataTypes: ucca.DataTypes{
|
||
PersonalData: false,
|
||
PublicData: true,
|
||
},
|
||
Automation: ucca.AutomationAssistive,
|
||
ModelUsage: ucca.ModelUsage{
|
||
RAG: true,
|
||
},
|
||
Hosting: ucca.Hosting{
|
||
Region: "eu",
|
||
},
|
||
}
|
||
|
||
// Evaluieren
|
||
result := engine.Evaluate(intake)
|
||
|
||
// Ergebnis auswerten
|
||
fmt.Println("Feasibility:", result.Feasibility) // YES, NO, CONDITIONAL
|
||
fmt.Println("Risk Level:", result.RiskLevel) // MINIMAL, LOW, MEDIUM, HIGH
|
||
fmt.Println("Risk Score:", result.RiskScore) // 0-100
|
||
```
|
||
|
||
### Ergebnis-Struktur
|
||
|
||
```go
|
||
type EvaluationResult struct {
|
||
Feasibility Feasibility // YES, NO, CONDITIONAL
|
||
RiskLevel RiskLevel // MINIMAL, LOW, MEDIUM, HIGH
|
||
RiskScore int // 0-100
|
||
TriggeredRules []TriggeredRule // Ausgelöste Regeln
|
||
RequiredControls []Control // Erforderliche Maßnahmen
|
||
RecommendedArchitecture []Pattern // Empfohlene Patterns
|
||
DSFARecommended bool // DSFA erforderlich?
|
||
Art22Risk bool // Art. 22 Risiko?
|
||
TrainingAllowed TrainingAllowed // YES, NO, CONDITIONAL
|
||
PolicyVersion string // Version der Policy
|
||
}
|
||
```
|
||
|
||
### Regeln hinzufügen
|
||
|
||
Neue Regeln werden in `policies/ucca_policy_v1.yaml` definiert:
|
||
|
||
```yaml
|
||
rules:
|
||
- id: R-CUSTOM-001
|
||
code: R-CUSTOM-001
|
||
category: custom
|
||
title: Custom Rule
|
||
title_de: Benutzerdefinierte Regel
|
||
description: Custom rule description
|
||
severity: WARN # INFO, WARN, BLOCK
|
||
gdpr_ref: "Art. 6 DSGVO"
|
||
condition:
|
||
all_of:
|
||
- field: domain
|
||
equals: custom_domain
|
||
- field: data_types.personal_data
|
||
equals: true
|
||
controls:
|
||
- C_CUSTOM_CONTROL
|
||
```
|
||
|
||
---
|
||
|
||
## 4. License Policy Engine
|
||
|
||
### Übersicht
|
||
|
||
Die License Policy Engine (`internal/ucca/license_policy.go`) prüft die Lizenz-Compliance für Standards und Normen.
|
||
|
||
### Operationsmodi
|
||
|
||
| Modus | Beschreibung | Lizenzanforderung |
|
||
|-------|--------------|-------------------|
|
||
| `LINK_ONLY` | Nur Verweise | Keine |
|
||
| `NOTES_ONLY` | Eigene Notizen | Keine |
|
||
| `EXCERPT_ONLY` | Kurzzitate (<150 Zeichen) | Standard-Lizenz |
|
||
| `FULLTEXT_RAG` | Volltext-Embedding | Explizite KI-Lizenz |
|
||
| `TRAINING` | Modell-Training | Enterprise + Vertrag |
|
||
|
||
### Verwendung
|
||
|
||
```go
|
||
import "ai-compliance-sdk/internal/ucca"
|
||
|
||
engine := ucca.NewLicensePolicyEngine()
|
||
|
||
facts := &ucca.LicensedContentFacts{
|
||
Present: true,
|
||
Publisher: "DIN_MEDIA",
|
||
LicenseType: "SINGLE_WORKSTATION",
|
||
AIUsePermitted: "NO",
|
||
ProofUploaded: false,
|
||
OperationMode: "FULLTEXT_RAG",
|
||
}
|
||
|
||
result := engine.Evaluate(facts)
|
||
|
||
if !result.Allowed {
|
||
fmt.Println("Blockiert:", result.StopLine.Message)
|
||
fmt.Println("Effektiver Modus:", result.EffectiveMode)
|
||
}
|
||
```
|
||
|
||
### Ingest-Entscheidung
|
||
|
||
```go
|
||
// Prüfen ob Volltext-Ingest erlaubt ist
|
||
canIngest := engine.CanIngestFulltext(facts)
|
||
|
||
// Oder detaillierte Entscheidung
|
||
decision := engine.DecideIngest(facts)
|
||
fmt.Println("Fulltext:", decision.AllowFulltext)
|
||
fmt.Println("Notes:", decision.AllowNotes)
|
||
fmt.Println("Metadata:", decision.AllowMetadata)
|
||
```
|
||
|
||
### Audit-Logging
|
||
|
||
```go
|
||
// Audit-Entry erstellen
|
||
entry := engine.FormatAuditEntry("tenant-123", "doc-456", facts, result)
|
||
|
||
// Human-readable Summary
|
||
summary := engine.FormatHumanReadableSummary(result)
|
||
fmt.Println(summary)
|
||
```
|
||
|
||
### Publisher-spezifische Regeln
|
||
|
||
DIN Media hat explizite Restriktionen:
|
||
|
||
```go
|
||
// DIN Media blockiert FULLTEXT_RAG ohne AI-Lizenz
|
||
if facts.Publisher == "DIN_MEDIA" && facts.AIUsePermitted != "YES" {
|
||
// → STOP_DIN_FULLTEXT_AI_NOT_ALLOWED
|
||
// → Downgrade auf LINK_ONLY
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Legal RAG Integration
|
||
|
||
### Übersicht
|
||
|
||
Das Legal RAG System (`internal/ucca/legal_rag.go`) generiert Erklärungen mit rechtlichem Kontext.
|
||
|
||
### Verwendung
|
||
|
||
```go
|
||
import "ai-compliance-sdk/internal/ucca"
|
||
|
||
rag := ucca.NewLegalRAGService(qdrantClient, llmClient, "bp_legal_corpus")
|
||
|
||
// Erklärung generieren
|
||
explanation, err := rag.Explain(ctx, result, intake)
|
||
if err != nil {
|
||
log.Error(err)
|
||
}
|
||
|
||
fmt.Println("Erklärung:", explanation.Text)
|
||
fmt.Println("Rechtsquellen:", explanation.Sources)
|
||
```
|
||
|
||
### Rechtsquellen im RAG
|
||
|
||
| Quelle | Chunks | Beschreibung |
|
||
|--------|--------|--------------|
|
||
| DSGVO | 128 | EU Datenschutz-Grundverordnung |
|
||
| AI Act | 96 | EU AI-Verordnung |
|
||
| NIS2 | 128 | Netzwerk-Informationssicherheit |
|
||
| SCC | 32 | Standardvertragsklauseln |
|
||
| DPF | 714 | Data Privacy Framework |
|
||
|
||
---
|
||
|
||
## 6. Wizard & Legal Assistant
|
||
|
||
### Wizard-Schema
|
||
|
||
Das Wizard-Schema (`policies/wizard_schema_v1.yaml`) definiert die Fragen für das Frontend.
|
||
|
||
### Legal Assistant verwenden
|
||
|
||
```go
|
||
// Wizard-Frage an Legal Assistant stellen
|
||
type WizardAskRequest struct {
|
||
Question string `json:"question"`
|
||
StepNumber int `json:"step_number"`
|
||
FieldID string `json:"field_id,omitempty"`
|
||
CurrentData map[string]interface{} `json:"current_data,omitempty"`
|
||
}
|
||
|
||
// POST /sdk/v1/ucca/wizard/ask
|
||
```
|
||
|
||
### Beispiel API-Call
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/sdk/v1/ucca/wizard/ask \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"question": "Was sind personenbezogene Daten?",
|
||
"step_number": 2,
|
||
"field_id": "data_types.personal_data"
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Eskalations-System
|
||
|
||
### Eskalationsstufen
|
||
|
||
| Level | Auslöser | Prüfer | SLA |
|
||
|-------|----------|--------|-----|
|
||
| E0 | Nur INFO | Automatisch | - |
|
||
| E1 | WARN, geringes Risiko | Team-Lead | 24h |
|
||
| E2 | Art. 9, DSFA empfohlen | DSB | 8h |
|
||
| E3 | BLOCK, hohes Risiko | DSB + Legal | 4h |
|
||
|
||
### Eskalation erstellen
|
||
|
||
```go
|
||
import "ai-compliance-sdk/internal/ucca"
|
||
|
||
store := ucca.NewEscalationStore(db)
|
||
|
||
escalation := &ucca.Escalation{
|
||
AssessmentID: "assess-123",
|
||
Level: ucca.EscalationE2,
|
||
TriggerReason: "Art. 9 Daten betroffen",
|
||
RequiredReviews: 1,
|
||
}
|
||
|
||
err := store.CreateEscalation(ctx, escalation)
|
||
```
|
||
|
||
### SLA-Monitor
|
||
|
||
```go
|
||
monitor := ucca.NewSLAMonitor(store, notificationService)
|
||
|
||
// Im Hintergrund starten
|
||
go monitor.Start(ctx)
|
||
```
|
||
|
||
---
|
||
|
||
## 8. API-Endpoints
|
||
|
||
### UCCA Endpoints
|
||
|
||
| Method | Endpoint | Beschreibung |
|
||
|--------|----------|--------------|
|
||
| POST | `/sdk/v1/ucca/assess` | Assessment erstellen |
|
||
| GET | `/sdk/v1/ucca/assess/:id` | Assessment abrufen |
|
||
| POST | `/sdk/v1/ucca/explain` | Erklärung generieren |
|
||
| GET | `/sdk/v1/ucca/wizard/schema` | Wizard-Schema abrufen |
|
||
| POST | `/sdk/v1/ucca/wizard/ask` | Legal Assistant fragen |
|
||
|
||
### License Endpoints
|
||
|
||
| Method | Endpoint | Beschreibung |
|
||
|--------|----------|--------------|
|
||
| POST | `/sdk/v1/license/evaluate` | Lizenz-Prüfung |
|
||
| POST | `/sdk/v1/license/decide-ingest` | Ingest-Entscheidung |
|
||
|
||
### Eskalations-Endpoints
|
||
|
||
| Method | Endpoint | Beschreibung |
|
||
|--------|----------|--------------|
|
||
| GET | `/sdk/v1/escalations` | Offene Eskalationen |
|
||
| GET | `/sdk/v1/escalations/:id` | Eskalation abrufen |
|
||
| POST | `/sdk/v1/escalations/:id/decide` | Entscheidung treffen |
|
||
|
||
---
|
||
|
||
## 9. Policy-Dateien
|
||
|
||
### Dateistruktur
|
||
|
||
```
|
||
policies/
|
||
├── ucca_policy_v1.yaml # Haupt-Policy (Regeln, Controls, Patterns)
|
||
├── wizard_schema_v1.yaml # Wizard-Fragen und Legal Assistant
|
||
├── controls_catalog.yaml # Detaillierte Control-Beschreibungen
|
||
├── gap_mapping.yaml # Facts → Gaps → Controls
|
||
├── licensed_content_policy.yaml # Standards/Normen Compliance
|
||
└── scc_legal_corpus.yaml # SCC Rechtsquellen
|
||
```
|
||
|
||
### Policy-Version
|
||
|
||
Jede Policy hat eine Version:
|
||
|
||
```yaml
|
||
metadata:
|
||
version: "1.0.0"
|
||
effective_date: "2025-01-01"
|
||
author: "Compliance Team"
|
||
```
|
||
|
||
---
|
||
|
||
## 10. Tests ausführen
|
||
|
||
### Alle Tests
|
||
|
||
```bash
|
||
cd ai-compliance-sdk
|
||
go test -v ./...
|
||
|
||
# So wie die CI es ausfuehrt (CGO_ENABLED=0):
|
||
CGO_ENABLED=0 go test -v -coverprofile=coverage.out ./...
|
||
```
|
||
|
||
### CI/CD Pipeline
|
||
|
||
Tests laufen automatisch bei jedem Push via Gitea Actions (`.gitea/workflows/ci.yaml`):
|
||
|
||
| Job | Container | Was wird getestet |
|
||
|-----|-----------|-------------------|
|
||
| `test-go-ai-compliance` | `golang:1.24-alpine` | `go test -v ./...` |
|
||
| `test-python-backend-compliance` | `python:3.12-slim` | `pytest compliance/tests/` |
|
||
| `test-python-document-crawler` | `python:3.12-slim` | `pytest tests/` |
|
||
| `test-python-dsms-gateway` | `python:3.12-slim` | `pytest test_main.py` |
|
||
|
||
Nach erfolgreichen Tests: automatisches Deploy auf Coolify (`deploy-coolify` Job).
|
||
|
||
### Spezifische Tests
|
||
|
||
```bash
|
||
# Policy Engine Tests
|
||
go test -v ./internal/ucca/policy_engine_test.go
|
||
|
||
# License Policy Tests
|
||
go test -v ./internal/ucca/license_policy_test.go
|
||
|
||
# Eskalation Tests
|
||
go test -v ./internal/ucca/escalation_test.go
|
||
```
|
||
|
||
### Test-Coverage
|
||
|
||
```bash
|
||
go test -cover ./...
|
||
|
||
# HTML-Report
|
||
go test -coverprofile=coverage.out ./...
|
||
go tool cover -html=coverage.out
|
||
```
|
||
|
||
### Beispiel: Neuen Test hinzufügen
|
||
|
||
```go
|
||
func TestMyNewFeature(t *testing.T) {
|
||
engine := NewLicensePolicyEngine()
|
||
|
||
facts := &LicensedContentFacts{
|
||
Present: true,
|
||
Publisher: "DIN_MEDIA",
|
||
OperationMode: "FULLTEXT_RAG",
|
||
}
|
||
|
||
result := engine.Evaluate(facts)
|
||
|
||
if result.Allowed {
|
||
t.Error("Expected blocked for DIN_MEDIA FULLTEXT_RAG")
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Anhang: Wichtige Dateien
|
||
|
||
| Datei | Beschreibung |
|
||
|-------|--------------|
|
||
| `internal/ucca/policy_engine.go` | Haupt-Policy-Engine |
|
||
| `internal/ucca/license_policy.go` | License Policy Engine |
|
||
| `internal/ucca/legal_rag.go` | Legal RAG Integration |
|
||
| `internal/ucca/escalation_store.go` | Eskalations-Verwaltung |
|
||
| `internal/ucca/sla_monitor.go` | SLA-Überwachung |
|
||
| `internal/api/handlers/ucca_handlers.go` | API-Handler |
|
||
| `cmd/server/main.go` | Server-Einstiegspunkt |
|
||
|
||
---
|
||
|
||
---
|
||
|
||
## 11. Generic Obligations Framework
|
||
|
||
### Übersicht
|
||
|
||
Das Obligations Framework ermöglicht die automatische Ableitung regulatorischer Pflichten aus NIS2, DSGVO und AI Act.
|
||
|
||
### Verwendung
|
||
|
||
```go
|
||
import "ai-compliance-sdk/internal/ucca"
|
||
|
||
// Registry erstellen (lädt alle Module)
|
||
registry := ucca.NewObligationsRegistry()
|
||
|
||
// UnifiedFacts aufbauen
|
||
facts := &ucca.UnifiedFacts{
|
||
Organization: ucca.OrganizationFacts{
|
||
EmployeeCount: 150,
|
||
AnnualRevenue: 30000000,
|
||
Country: "DE",
|
||
EUMember: true,
|
||
},
|
||
Sector: ucca.SectorFacts{
|
||
PrimarySector: "digital_infrastructure",
|
||
SpecialServices: []string{"cloud", "msp"},
|
||
IsKRITIS: false,
|
||
},
|
||
DataProtection: ucca.DataProtectionFacts{
|
||
ProcessesPersonalData: true,
|
||
},
|
||
AIUsage: ucca.AIUsageFacts{
|
||
UsesAI: true,
|
||
HighRiskCategories: []string{"employment"},
|
||
IsGPAIProvider: false,
|
||
},
|
||
}
|
||
|
||
// Alle anwendbaren Pflichten evaluieren
|
||
overview := registry.EvaluateAll(facts, "Muster GmbH")
|
||
|
||
// Ergebnis auswerten
|
||
fmt.Println("Anwendbare Regulierungen:", len(overview.ApplicableRegulations))
|
||
fmt.Println("Gesamtzahl Pflichten:", len(overview.Obligations))
|
||
fmt.Println("Kritische Pflichten:", overview.ExecutiveSummary.CriticalObligations)
|
||
```
|
||
|
||
### Neues Regulierungsmodul erstellen
|
||
|
||
```go
|
||
// 1. Module-Interface implementieren
|
||
type MyRegulationModule struct {
|
||
obligations []ucca.Obligation
|
||
controls []ucca.ObligationControl
|
||
incidentDeadlines []ucca.IncidentDeadline
|
||
}
|
||
|
||
func (m *MyRegulationModule) ID() string { return "my_regulation" }
|
||
func (m *MyRegulationModule) Name() string { return "My Regulation" }
|
||
|
||
func (m *MyRegulationModule) IsApplicable(facts *ucca.UnifiedFacts) bool {
|
||
// Prüflogik implementieren
|
||
return facts.Organization.Country == "DE"
|
||
}
|
||
|
||
func (m *MyRegulationModule) DeriveObligations(facts *ucca.UnifiedFacts) []ucca.Obligation {
|
||
// Pflichten basierend auf Facts ableiten
|
||
return m.obligations
|
||
}
|
||
|
||
// 2. In Registry registrieren
|
||
func NewMyRegulationModule() (*MyRegulationModule, error) {
|
||
m := &MyRegulationModule{}
|
||
// YAML laden oder hardcoded Pflichten definieren
|
||
return m, nil
|
||
}
|
||
|
||
// In obligations_registry.go:
|
||
// r.Register(NewMyRegulationModule())
|
||
```
|
||
|
||
### YAML-basierte Pflichten
|
||
|
||
```yaml
|
||
# policies/obligations/my_regulation_obligations.yaml
|
||
regulation: my_regulation
|
||
name: "My Regulation"
|
||
|
||
obligations:
|
||
- id: "MYREG-OBL-001"
|
||
title: "Compliance-Pflicht"
|
||
description: "Beschreibung der Pflicht"
|
||
applies_when: "classification != 'nicht_betroffen'"
|
||
legal_basis:
|
||
- norm: "§ 1 MyReg"
|
||
category: "Governance"
|
||
responsible: "Geschäftsführung"
|
||
deadline:
|
||
type: "relative"
|
||
duration: "12 Monate"
|
||
sanctions:
|
||
max_fine: "1 Mio. EUR"
|
||
priority: "high"
|
||
|
||
controls:
|
||
- id: "MYREG-CTRL-001"
|
||
name: "Kontrollmaßnahme"
|
||
category: "Technical"
|
||
when_applicable: "immer"
|
||
what_to_do: "Maßnahme implementieren"
|
||
evidence_needed:
|
||
- "Dokumentation"
|
||
```
|
||
|
||
### PDF Export
|
||
|
||
```go
|
||
import "ai-compliance-sdk/internal/ucca"
|
||
|
||
// Exporter erstellen
|
||
exporter := ucca.NewPDFExporter("de")
|
||
|
||
// PDF generieren
|
||
response, err := exporter.ExportManagementMemo(overview)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
// base64-kodierter PDF-Inhalt
|
||
fmt.Println("Content-Type:", response.ContentType) // application/pdf
|
||
fmt.Println("Filename:", response.Filename)
|
||
|
||
// PDF speichern
|
||
decoded, _ := base64.StdEncoding.DecodeString(response.Content)
|
||
os.WriteFile("memo.pdf", decoded, 0644)
|
||
|
||
// Alternativ: Markdown
|
||
mdResponse, err := exporter.ExportMarkdown(overview)
|
||
fmt.Println(mdResponse.Content) // Markdown-Text
|
||
```
|
||
|
||
### API-Endpoints
|
||
|
||
```bash
|
||
# Assessment erstellen
|
||
curl -X POST http://localhost:8090/sdk/v1/ucca/obligations/assess \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"facts": {
|
||
"organization": {"employee_count": 150, "country": "DE"},
|
||
"sector": {"primary_sector": "healthcare"},
|
||
"data_protection": {"processes_personal_data": true},
|
||
"ai_usage": {"uses_ai": false}
|
||
},
|
||
"organization_name": "Test GmbH"
|
||
}'
|
||
|
||
# PDF Export (direkt)
|
||
curl -X POST http://localhost:8090/sdk/v1/ucca/obligations/export/direct \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"overview": { ... },
|
||
"format": "pdf",
|
||
"language": "de"
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
## 12. Tests für Obligations Framework
|
||
|
||
```bash
|
||
# Alle Obligations-Tests
|
||
go test -v ./internal/ucca/..._module_test.go
|
||
|
||
# NIS2 Module Tests
|
||
go test -v ./internal/ucca/nis2_module_test.go
|
||
|
||
# DSGVO Module Tests
|
||
go test -v ./internal/ucca/dsgvo_module_test.go
|
||
|
||
# AI Act Module Tests
|
||
go test -v ./internal/ucca/ai_act_module_test.go
|
||
|
||
# PDF Export Tests
|
||
go test -v ./internal/ucca/pdf_export_test.go
|
||
```
|
||
|
||
### Beispiel-Tests
|
||
|
||
```go
|
||
func TestNIS2Module_LargeCompanyInAnnexISector(t *testing.T) {
|
||
module, _ := ucca.NewNIS2Module()
|
||
|
||
facts := &ucca.UnifiedFacts{
|
||
Organization: ucca.OrganizationFacts{
|
||
EmployeeCount: 500,
|
||
AnnualRevenue: 100000000,
|
||
Country: "DE",
|
||
},
|
||
Sector: ucca.SectorFacts{
|
||
PrimarySector: "energy",
|
||
},
|
||
}
|
||
|
||
if !module.IsApplicable(facts) {
|
||
t.Error("Expected NIS2 to apply to large energy company")
|
||
}
|
||
|
||
classification := module.Classify(facts)
|
||
if classification != "besonders_wichtige_einrichtung" {
|
||
t.Errorf("Expected 'besonders_wichtige_einrichtung', got '%s'", classification)
|
||
}
|
||
}
|
||
|
||
func TestAIActModule_HighRiskEmploymentAI(t *testing.T) {
|
||
module, _ := ucca.NewAIActModule()
|
||
|
||
facts := &ucca.UnifiedFacts{
|
||
AIUsage: ucca.AIUsageFacts{
|
||
UsesAI: true,
|
||
HighRiskCategories: []string{"employment"},
|
||
},
|
||
}
|
||
|
||
if !module.IsApplicable(facts) {
|
||
t.Error("Expected AI Act to apply")
|
||
}
|
||
|
||
riskLevel := module.ClassifyRisk(facts)
|
||
if riskLevel != ucca.AIActHighRisk {
|
||
t.Errorf("Expected 'high_risk', got '%s'", riskLevel)
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Anhang: Wichtige Dateien (erweitert)
|
||
|
||
| Datei | Beschreibung |
|
||
|-------|--------------|
|
||
| `internal/ucca/policy_engine.go` | Haupt-Policy-Engine |
|
||
| `internal/ucca/license_policy.go` | License Policy Engine |
|
||
| `internal/ucca/obligations_framework.go` | Obligations Interfaces & Typen |
|
||
| `internal/ucca/obligations_registry.go` | Modul-Registry |
|
||
| `internal/ucca/nis2_module.go` | NIS2 Decision Tree |
|
||
| `internal/ucca/dsgvo_module.go` | DSGVO Pflichten |
|
||
| `internal/ucca/ai_act_module.go` | AI Act Risk Classification |
|
||
| `internal/ucca/pdf_export.go` | PDF/Markdown Export |
|
||
| `internal/api/handlers/obligations_handlers.go` | Obligations API |
|
||
| `policies/obligations/*.yaml` | Pflichten-Kataloge |
|
||
|
||
---
|
||
|
||
---
|
||
|
||
## 13. DSFA (Datenschutz-Folgenabschätzung nach Art. 35 DSGVO)
|
||
|
||
### Übersicht
|
||
|
||
Das DSFA-Modul implementiert die Datenschutz-Folgenabschätzung gemäß Art. 35 DSGVO als generisches Compliance-Tool für jeden KI-Anwendungsfall.
|
||
|
||
### Architektur
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ Frontend (admin-v2) │
|
||
│ app/(sdk)/sdk/dsfa/ │
|
||
│ ├── page.tsx (Dashboard) │
|
||
│ └── [id]/page.tsx (5-Abschnitt-Editor) │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Components │
|
||
│ components/sdk/dsfa/ │
|
||
│ ├── DSFACard.tsx (Listenansicht) │
|
||
│ ├── RiskMatrix.tsx (Interaktive Risiko-Matrix) │
|
||
│ └── ApprovalPanel.tsx (Genehmigungs-Workflow) │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ API Client │
|
||
│ lib/sdk/dsfa/ │
|
||
│ ├── types.ts (TypeScript-Typen) │
|
||
│ └── api.ts (API-Funktionen) │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Backend (Go) │
|
||
│ internal/dsgvo/ │
|
||
│ ├── models.go (DSFA-Datenmodell) │
|
||
│ ├── store.go (PostgreSQL-Persistierung) │
|
||
│ └── handlers.go (API-Endpoints) │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Zwei Einstiegswege
|
||
|
||
| Weg | Beschreibung | Vorausgefüllt |
|
||
|-----|--------------|---------------|
|
||
| **UCCA-getriggert** | Automatisch bei Trigger-Regeln (R-A002, R-A003, etc.) | Ja |
|
||
| **Standalone** | Manuell für Verarbeitungen ohne UCCA | Nein |
|
||
|
||
### Die 5 Abschnitte nach Art. 35 DSGVO
|
||
|
||
| # | Abschnitt | Art. 35 Ref | Inhalt |
|
||
|---|-----------|-------------|--------|
|
||
| 1 | Systematische Beschreibung | Abs. 7 lit. a | Zweck, Datenkategorien, Betroffene, Empfänger, Rechtsgrundlage |
|
||
| 2 | Notwendigkeit & Verhältnismäßigkeit | Abs. 7 lit. b | Warum notwendig? Alternativen? Datenminimierung? |
|
||
| 3 | Risikobewertung | Abs. 7 lit. c | Risiko-Matrix (Eintrittswahrscheinlichkeit × Schwere) |
|
||
| 4 | Abhilfemaßnahmen | Abs. 7 lit. d | Technische + Organisatorische Maßnahmen |
|
||
| 5 | Stellungnahme DSB | Abs. 2 + Art. 36 | DSB-Konsultation, ggf. Behörden-Konsultation |
|
||
|
||
### Datenmodell
|
||
|
||
```go
|
||
type DSFA struct {
|
||
ID uuid.UUID `json:"id"`
|
||
TenantID uuid.UUID `json:"tenant_id"`
|
||
AssessmentID *uuid.UUID `json:"assessment_id,omitempty"` // UCCA-Verknüpfung
|
||
Name string `json:"name"`
|
||
Description string `json:"description"`
|
||
|
||
// Abschnitt 1: Systematische Beschreibung
|
||
ProcessingDescription string `json:"processing_description"`
|
||
ProcessingPurpose string `json:"processing_purpose"`
|
||
DataCategories []string `json:"data_categories"`
|
||
DataSubjects []string `json:"data_subjects"`
|
||
Recipients []string `json:"recipients"`
|
||
LegalBasis string `json:"legal_basis"`
|
||
|
||
// Abschnitt 2: Notwendigkeit
|
||
NecessityAssessment string `json:"necessity_assessment"`
|
||
ProportionalityAssessment string `json:"proportionality_assessment"`
|
||
DataMinimization string `json:"data_minimization"`
|
||
AlternativesConsidered string `json:"alternatives_considered"`
|
||
|
||
// Abschnitt 3: Risikobewertung
|
||
Risks []DSFARisk `json:"risks"`
|
||
OverallRiskLevel string `json:"overall_risk_level"`
|
||
RiskScore int `json:"risk_score"`
|
||
AffectedRights []string `json:"affected_rights"`
|
||
TriggeredRuleCodes []string `json:"triggered_rule_codes"`
|
||
|
||
// Abschnitt 4: Maßnahmen
|
||
Mitigations []DSFAMitigation `json:"mitigations"`
|
||
TOMReferences []string `json:"tom_references"`
|
||
|
||
// Abschnitt 5: DSB-Stellungnahme
|
||
DPOConsulted bool `json:"dpo_consulted"`
|
||
DPOName string `json:"dpo_name"`
|
||
DPOOpinion string `json:"dpo_opinion"`
|
||
AuthorityConsulted bool `json:"authority_consulted"`
|
||
AuthorityReference string `json:"authority_reference"`
|
||
|
||
// Workflow
|
||
Status string `json:"status"` // draft, in_review, approved, rejected
|
||
SectionProgress DSFASectionProgress `json:"section_progress"`
|
||
ReviewComments []DSFAReviewComment `json:"review_comments"`
|
||
}
|
||
|
||
type DSFARisk struct {
|
||
ID string `json:"id"`
|
||
Category string `json:"category"` // confidentiality, integrity, availability, rights_freedoms
|
||
Description string `json:"description"`
|
||
Likelihood string `json:"likelihood"` // low, medium, high
|
||
Impact string `json:"impact"` // low, medium, high
|
||
RiskLevel string `json:"risk_level"` // low, medium, high, very_high
|
||
}
|
||
|
||
type DSFAMitigation struct {
|
||
ID string `json:"id"`
|
||
RiskID string `json:"risk_id"`
|
||
Description string `json:"description"`
|
||
Type string `json:"type"` // technical, organizational, legal
|
||
Status string `json:"status"` // planned, in_progress, implemented, verified
|
||
ResponsibleParty string `json:"responsible_party"`
|
||
TOMReference string `json:"tom_reference,omitempty"`
|
||
}
|
||
```
|
||
|
||
### API-Endpoints
|
||
|
||
| Method | Endpoint | Beschreibung |
|
||
|--------|----------|--------------|
|
||
| GET | `/sdk/v1/dsgvo/dsfas` | Alle DSFAs auflisten |
|
||
| POST | `/sdk/v1/dsgvo/dsfas` | Neue DSFA erstellen |
|
||
| GET | `/sdk/v1/dsgvo/dsfas/:id` | DSFA abrufen |
|
||
| PUT | `/sdk/v1/dsgvo/dsfas/:id` | DSFA aktualisieren |
|
||
| DELETE | `/sdk/v1/dsgvo/dsfas/:id` | DSFA löschen |
|
||
| PUT | `/sdk/v1/dsgvo/dsfas/:id/sections/:num` | Abschnitt aktualisieren |
|
||
| POST | `/sdk/v1/dsgvo/dsfas/:id/submit-for-review` | Zur Prüfung einreichen |
|
||
| POST | `/sdk/v1/dsgvo/dsfas/:id/approve` | Genehmigen/Ablehnen |
|
||
| GET | `/sdk/v1/dsgvo/dsfas/stats` | Statistiken abrufen |
|
||
| POST | `/sdk/v1/dsgvo/dsfas/from-assessment/:id` | DSFA aus UCCA erstellen |
|
||
| GET | `/sdk/v1/dsgvo/dsfas/by-assessment/:id` | DSFA zu Assessment finden |
|
||
|
||
### Verwendung (Backend)
|
||
|
||
```go
|
||
import "ai-compliance-sdk/internal/dsgvo"
|
||
|
||
// Store erstellen
|
||
store := dsgvo.NewStore(db)
|
||
|
||
// DSFA erstellen
|
||
dsfa := &dsgvo.DSFA{
|
||
Name: "KI-Chatbot Kundenservice",
|
||
ProcessingPurpose: "Automatisierte Kundenanfragen-Bearbeitung",
|
||
DataCategories: []string{"Kontaktdaten", "Anfrageinhalte"},
|
||
DataSubjects: []string{"Kunden"},
|
||
LegalBasis: "legitimate_interest",
|
||
Status: "draft",
|
||
}
|
||
|
||
id, err := store.CreateDSFA(ctx, tenantID, dsfa)
|
||
|
||
// Abschnitt aktualisieren
|
||
err = store.UpdateDSFASection(ctx, id, 1, map[string]interface{}{
|
||
"processing_description": "Detaillierte Beschreibung...",
|
||
})
|
||
|
||
// Zur Prüfung einreichen
|
||
err = store.SubmitDSFAForReview(ctx, id, userID)
|
||
|
||
// Genehmigen
|
||
err = store.ApproveDSFA(ctx, id, approverID, true, "Genehmigt nach Prüfung")
|
||
```
|
||
|
||
### Verwendung (Frontend)
|
||
|
||
```typescript
|
||
import { listDSFAs, getDSFA, updateDSFASection, submitDSFAForReview } from '@/lib/sdk/dsfa/api'
|
||
|
||
// DSFAs laden
|
||
const dsfas = await listDSFAs()
|
||
|
||
// Einzelne DSFA laden
|
||
const dsfa = await getDSFA(id)
|
||
|
||
// Abschnitt aktualisieren
|
||
await updateDSFASection(id, 1, {
|
||
processing_purpose: 'Neuer Zweck',
|
||
data_categories: ['Kontaktdaten', 'Nutzungsdaten'],
|
||
})
|
||
|
||
// Zur Prüfung einreichen
|
||
await submitDSFAForReview(id)
|
||
```
|
||
|
||
### Risiko-Matrix
|
||
|
||
Die Risiko-Matrix berechnet die Risikostufe aus Eintrittswahrscheinlichkeit und Auswirkung:
|
||
|
||
```typescript
|
||
import { calculateRiskLevel } from '@/lib/sdk/dsfa/types'
|
||
|
||
const { level, score } = calculateRiskLevel('high', 'high')
|
||
// level: 'very_high', score: 90
|
||
```
|
||
|
||
| Eintritt \ Auswirkung | Niedrig | Mittel | Hoch |
|
||
|-----------------------|---------|--------|------|
|
||
| **Hoch** | Mittel (40) | Hoch (70) | Sehr Hoch (90) |
|
||
| **Mittel** | Niedrig (20) | Mittel (50) | Hoch (70) |
|
||
| **Niedrig** | Niedrig (10) | Niedrig (20) | Mittel (40) |
|
||
|
||
### UCCA-Integration (Trigger-Regeln)
|
||
|
||
Folgende UCCA-Regeln lösen eine DSFA-Empfehlung aus:
|
||
|
||
| Code | Beschreibung |
|
||
|------|--------------|
|
||
| R-A002 | Art. 9 Daten (besondere Kategorien) |
|
||
| R-A003 | Daten von Minderjährigen |
|
||
| R-A005 | Biometrische Daten |
|
||
| R-B002 | Scoring (systematische Bewertung) |
|
||
| R-B003 | Profiling |
|
||
| R-B004 | Marketing mit personenbezogenen Daten |
|
||
| R-D003 | Training mit Gesundheitsdaten |
|
||
| R-G002 | Risiko-Score ≥ 60 |
|
||
|
||
### Tests
|
||
|
||
```bash
|
||
# Backend-Tests
|
||
go test -v ./internal/dsgvo/...
|
||
|
||
# Frontend-Tests
|
||
cd admin-v2 && npm test -- --testPathPattern=dsfa
|
||
```
|
||
|
||
### Wichtige Dateien
|
||
|
||
| Datei | Beschreibung |
|
||
|-------|--------------|
|
||
| `internal/dsgvo/models.go` | DSFA-Datenmodell |
|
||
| `internal/dsgvo/store.go` | PostgreSQL-Store |
|
||
| `internal/api/handlers/dsgvo_handlers.go` | API-Handler |
|
||
| `admin-v2/lib/sdk/dsfa/types.ts` | TypeScript-Typen |
|
||
| `admin-v2/lib/sdk/dsfa/api.ts` | API-Client |
|
||
| `admin-v2/components/sdk/dsfa/` | UI-Komponenten |
|
||
| `admin-v2/app/(sdk)/sdk/dsfa/` | Dashboard & Editor |
|
||
|
||
---
|
||
|
||
*Dokumentationsstand: 2026-03-11*
|