Files
breakpilot-core/docs-src/architecture/sdk-protection.md
Benjamin Boenisch b7d21daa24
All checks were successful
CI / test-bqas (push) Successful in 32s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 46s
CI / test-python-voice (push) Successful in 38s
feat: Add DevSecOps tools, Woodpecker proxy, Vault persistent storage, pitch-deck annex slides
- Install Gitleaks, Trivy, Grype, Syft, Semgrep, Bandit in backend-core Dockerfile
- Add Woodpecker SQLite proxy API (fallback without API token)
- Mount woodpecker_data volume read-only to backend-core
- Add backend proxy fallback in admin-core Woodpecker route
- Add Vault file-based persistent storage (config.hcl, init-vault.sh)
- Auto-init, unseal and root-token persistence for Vault
- Add 6 pitch-deck annex slides (Assumptions, Architecture, GTM, Regulatory, Engineering, AI Pipeline)
- Dynamic margin/amortization KPIs in BusinessModelSlide
- Market sources modal with citations in MarketSlide
- Redesign nginx landing page to 3-column layout (Lehrer/Compliance/Core)
- Extend MkDocs nav with Services and SDK documentation sections
- Add SDK Protection architecture doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 15:42:43 +01:00

15 KiB
Raw Permalink Blame History

SDK Protection Middleware

1. Worum geht es?

Die SDK Protection Middleware schuetzt die Compliance-SDK-Endpunkte vor einer bestimmten Art von Angriff: der systematischen Enumeration. Was bedeutet das?

Ein Wettbewerber registriert sich als zahlender Kunde und laesst ein Skript langsam und verteilt alle TOM-Controls, alle Pruefaspekte und alle Assessment-Kriterien abfragen. Aus den Ergebnissen rekonstruiert er die gesamte Compliance-Framework-Logik.

Der klassische Rate Limiter (100 Requests/Minute) hilft hier nicht, weil ein cleverer Angreifer langsam vorgeht -- vielleicht nur 20 Anfragen pro Minute, dafuer systematisch und ueber Stunden. Die SDK Protection erkennt solche Muster und reagiert darauf.

!!! info "Kern-Designprinzip" Normale Nutzer merken nichts. Ein Lehrer, der im TOM-Modul arbeitet, greift typischerweise auf 3-5 Kategorien zu und wiederholt Anfragen an gleiche Endpunkte. Ein Angreifer durchlaeuft dagegen 40+ Kategorien in alphabetischer Reihenfolge. Genau diesen Unterschied erkennt die Middleware.


2. Wie funktioniert der Schutz?

Die Middleware nutzt ein Anomaly-Score-System. Jeder Benutzer hat einen Score, der bei 0 beginnt. Verschiedene verdaechtige Verhaltensweisen erhoehen den Score. Ueber die Zeit sinkt er wieder ab. Je hoeher der Score, desto staerker wird der Benutzer gebremst.

Man kann es sich wie eine Ampel vorstellen:

Score Ampel Wirkung Beispiel
0-29 Gruen Keine Einschraenkung Normaler Nutzer
30-59 Gelb 1-3 Sekunden Verzoegerung Leicht auffaelliges Muster
60-84 Orange 5-10 Sekunden Verzoegerung, reduzierte Details Deutlich verdaechtiges Verhalten
85+ Rot Zugriff blockiert (HTTP 429) Sehr wahrscheinlich automatisierter Angriff

Score-Zerfall

Der Score sinkt automatisch: Alle 5 Minuten wird er mit dem Faktor 0,95 multipliziert. Ein Score von 60 faellt also innerhalb einer Stunde auf etwa 30 -- wenn kein neues verdaechtiges Verhalten hinzukommt.


3. Was wird erkannt?

Die Middleware erkennt fuenf verschiedene Anomalie-Muster:

3.1 Hohe Kategorie-Diversitaet

Was: Ein Benutzer greift innerhalb einer Stunde auf mehr als 40 verschiedene SDK-Kategorien zu.

Warum verdaechtig: Ein normaler Nutzer arbeitet in der Regel mit 3-10 Kategorien. Wer systematisch alle durchlaeuft, sammelt vermutlich Daten.

Score-Erhoehung: +15

Normal:   tom/access-control → tom/access-control → tom/encryption → tom/encryption
                               (3 verschiedene Kategorien in einer Stunde)

Verdaechtig: tom/access-control → tom/encryption → tom/pseudonymization → tom/integrity
             → tom/availability → tom/resilience → dsfa/threshold → dsfa/necessity → ...
                               (40+ verschiedene Kategorien in einer Stunde)

3.2 Burst-Erkennung

Was: Ein Benutzer sendet mehr als 15 Anfragen an die gleiche Kategorie innerhalb von 2 Minuten.

Warum verdaechtig: Selbst ein eifriger Nutzer klickt nicht 15-mal pro Minute auf denselben Endpunkt. Das deutet auf automatisiertes Scraping hin.

Score-Erhoehung: +20

3.3 Sequentielle Enumeration

Was: Die letzten 10 aufgerufenen Kategorien sind zu mindestens 70% in alphabetischer oder numerischer Reihenfolge.

Warum verdaechtig: Menschen springen zwischen Kategorien -- sie arbeiten thematisch, nicht alphabetisch. Ein Skript dagegen iteriert oft ueber eine sortierte Liste.

Score-Erhoehung: +25

Verdaechtig: assessment_general → compliance_general → controls_general
             → dsfa_measures → dsfa_necessity → dsfa_residual → dsfa_risks
             → dsfa_threshold → eh_general → namespace_general
             (alphabetisch sortiert = Skript-Verhalten)

3.4 Ungewoehnliche Uhrzeiten

Was: Anfragen zwischen 0:00 und 5:00 Uhr UTC.

Warum verdaechtig: Lehrer arbeiten tagsüber. Wer um 3 Uhr morgens SDK-Endpunkte abfragt, ist wahrscheinlich ein automatisierter Prozess.

Score-Erhoehung: +10

3.5 Multi-Tenant-Zugriff

Was: Ein Benutzer greift innerhalb einer Stunde auf mehr als 3 verschiedene Mandanten (Tenants) zu.

Warum verdaechtig: Ein normaler Nutzer gehoert zu einem Mandanten. Wer mehrere durchprobiert, koennte versuchen, mandantenuebergreifend Daten zu sammeln.

Score-Erhoehung: +15


4. Quota-System (Mengenbegrenzung)

Zusaetzlich zum Anomaly-Score gibt es klassische Mengenbegrenzungen in vier Zeitfenstern:

Tier pro Minute pro Stunde pro Tag pro Monat
Free 30 500 3.000 50.000
Standard 60 1.500 10.000 200.000
Enterprise 120 5.000 50.000 1.000.000

Wenn ein Limit in irgendeinem Zeitfenster ueberschritten wird, erhaelt der Nutzer sofort HTTP 429 -- unabhaengig vom Anomaly-Score.


5. Architektur

Datenfluss eines SDK-Requests

Request kommt an
     │
     ▼
┌─────────────────────────────────────────────────────────────┐
│  Ist der Pfad geschuetzt?                                    │
│  (/api/sdk/*, /api/v1/tom/*, /api/v1/dsfa/*, ...)           │
│  Nein → direkt weiterleiten                                  │
└──────────────┬──────────────────────────────────────────────┘
               │ Ja
               ▼
┌─────────────────────────────────────────────────────────────┐
│  User + Tier + Kategorie extrahieren                         │
│  (aus Session, API-Key oder X-SDK-Tier Header)               │
└──────────────┬──────────────────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────────────────┐
│  Multi-Window Quota pruefen                                  │
│  (Minute / Stunde / Tag / Monat)                             │
│  Ueberschritten → HTTP 429 zurueck                          │
└──────────────┬──────────────────────────────────────────────┘
               │ OK
               ▼
┌─────────────────────────────────────────────────────────────┐
│  Anomaly-Score laden (aus Valkey)                            │
│  Zeitbasierten Zerfall anwenden (×0,95 alle 5 min)           │
└──────────────┬──────────────────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────────────────┐
│  Anomalie-Detektoren ausfuehren:                             │
│  ├── Diversity-Tracking     (+15 wenn >40 Kategorien/h)      │
│  ├── Burst-Detection        (+20 wenn >15 gleiche/2min)      │
│  ├── Sequential-Enumeration (+25 wenn sortiert)              │
│  ├── Unusual-Hours          (+10 wenn 0-5 Uhr UTC)           │
│  └── Multi-Tenant           (+15 wenn >3 Tenants/h)          │
└──────────────┬──────────────────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────────────────┐
│  Throttle-Level bestimmen                                    │
│  Level 3 (Score ≥85) → HTTP 429                              │
│  Level 2 (Score ≥60) → 5-10s Delay + reduzierte Details      │
│  Level 1 (Score ≥30) → 1-3s Delay                            │
│  Level 0             → keine Einschraenkung                  │
└──────────────┬──────────────────────────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────────────────────────┐
│  Request weiterleiten                                        │
│  Response-Headers setzen:                                    │
│  ├── X-SDK-Quota-Remaining-Minute/Hour                       │
│  ├── X-SDK-Throttle-Level                                    │
│  ├── X-SDK-Detail-Reduced (bei Level ≥2)                     │
│  └── X-BP-Trace (HMAC-Watermark)                             │
└─────────────────────────────────────────────────────────────┘

Valkey-Datenstrukturen

Die Middleware speichert alle Tracking-Daten in Valkey (Redis-Fork). Wenn Valkey nicht erreichbar ist, wird automatisch auf eine In-Memory-Implementierung zurueckgefallen.

Zweck Valkey-Typ Key-Muster TTL
Quota pro Zeitfenster Sorted Set sdk_protect:quota:{user}:{window} Fenster + 10s
Kategorie-Diversitaet Set sdk_protect:diversity:{user}:{stunde} 3660s
Burst-Tracking Sorted Set sdk_protect:burst:{user}:{kategorie} 130s
Sequenz-Tracking List sdk_protect:seq:{user} 310s
Anomaly-Score Hash sdk_protect:score:{user} 86400s
Tenant-Tracking Set sdk_protect:tenants:{user}:{stunde} 3660s

Watermarking

Jede Antwort enthaelt einen X-BP-Trace Header mit einem HMAC-basierten Fingerabdruck. Damit kann nachtraeglich nachgewiesen werden, welcher Benutzer wann welche Daten abgerufen hat -- ohne dass der Benutzer den Trace veraendern kann.


6. Geschuetzte Endpunkte

Die Middleware schuetzt alle Pfade, die SDK- und Compliance-relevante Daten liefern:

Pfad-Prefix Bereich
/api/sdk/* SDK-Hauptendpunkte
/api/compliance/* Compliance-Bewertungen
/api/v1/tom/* Technisch-organisatorische Massnahmen
/api/v1/dsfa/* Datenschutz-Folgenabschaetzung
/api/v1/vvt/* Verarbeitungsverzeichnis
/api/v1/controls/* Controls und Massnahmen
/api/v1/assessment/* Assessment-Bewertungen
/api/v1/eh/* Erwartungshorizonte
/api/v1/namespace/* Namespace-Verwaltung

Nicht geschuetzt sind /health, /metrics und /api/health.


7. Admin-Verwaltung

Ueber das Admin-Dashboard koennen Anomaly-Scores eingesehen und verwaltet werden:

Endpoint Methode Beschreibung
/api/admin/middleware/sdk-protection/scores GET Aktuelle Anomaly-Scores aller Benutzer
/api/admin/middleware/sdk-protection/stats GET Statistik: Benutzer pro Throttle-Level
/api/admin/middleware/sdk-protection/reset-score/{user_id} POST Score eines Benutzers zuruecksetzen
/api/admin/middleware/sdk-protection/tiers GET Tier-Konfigurationen anzeigen
/api/admin/middleware/sdk-protection/tiers/{name} PUT Tier-Limits aendern

8. Dateien und Quellcode

Datei Beschreibung
backend/middleware/sdk_protection.py Kern-Middleware (~460 Zeilen)
backend/middleware/__init__.py Export der Middleware-Klassen
backend/main.py Registrierung im FastAPI-Stack
backend/middleware_admin_api.py Admin-API-Endpoints
backend/migrations/add_sdk_protection_tables.sql Datenbank-Migration
backend/tests/test_middleware.py 14 Tests fuer alle Erkennungsmechanismen

9. Datenbank-Tabellen

sdk_anomaly_scores

Speichert Snapshots der Anomaly-Scores fuer Audit und Analyse.

Spalte Typ Beschreibung
id UUID Primaerschluessel
user_id VARCHAR(255) Benutzer-Identifikation
score DECIMAL(5,2) Aktueller Anomaly-Score
throttle_level SMALLINT Aktueller Throttle-Level (0-3)
triggered_rules JSONB Welche Regeln ausgeloest wurden
endpoint_diversity_count INT Anzahl verschiedener Kategorien
request_count_1h INT Anfragen in der letzten Stunde
snapshot_at TIMESTAMPTZ Zeitpunkt des Snapshots

sdk_protection_tiers

Konfigurierbare Quota-Tiers, editierbar ueber die Admin-API.

Spalte Typ Beschreibung
tier_name VARCHAR(50) Name des Tiers (free, standard, enterprise)
quota_per_minute INT Maximale Anfragen pro Minute
quota_per_hour INT Maximale Anfragen pro Stunde
quota_per_day INT Maximale Anfragen pro Tag
quota_per_month INT Maximale Anfragen pro Monat
diversity_threshold INT Max verschiedene Kategorien pro Stunde
burst_threshold INT Max gleiche Kategorie in 2 Minuten

10. Konfiguration

Die Middleware wird in main.py registriert:

from middleware import SDKProtectionMiddleware

app.add_middleware(SDKProtectionMiddleware)

Alle Parameter koennen ueber die SDKProtectionConfig Dataclass angepasst werden. Die wichtigsten Umgebungsvariablen:

Variable Default Beschreibung
VALKEY_URL redis://localhost:6379 Verbindung zur Valkey-Instanz
SDK_WATERMARK_SECRET (generiert) HMAC-Secret fuer Watermarks

11. Tests

Die Middleware wird durch 14 automatisierte Tests abgedeckt:

# Alle SDK Protection Tests ausfuehren
docker compose run --rm --no-deps backend \
  python -m pytest tests/test_middleware.py -v -k sdk
Test Prueft
test_allows_normal_request Normaler Request wird durchgelassen
test_blocks_after_quota_exceeded 429 bei Quota-Ueberschreitung
test_diversity_tracking_increments_score Viele Kategorien erhoehen den Score
test_burst_detection Schnelle gleiche Anfragen erhoehen den Score
test_sequential_enumeration_detection Alphabetische Muster werden erkannt
test_progressive_throttling_level_1 Delay bei Score >= 30
test_progressive_throttling_level_3_blocks Block bei Score >= 85
test_score_decay_over_time Score sinkt ueber die Zeit
test_skips_non_protected_paths Nicht-SDK-Pfade bleiben frei
test_watermark_header_present X-BP-Trace Header vorhanden
test_fallback_to_inmemory Funktioniert ohne Valkey
test_no_user_passes_through Anonyme Requests passieren
test_category_extraction Korrekte Kategorie-Zuordnung
test_quota_headers_present Response-Headers vorhanden