Technisch-organisatorische Maßnahmen (TOMs) gemäß Art. 32 DSGVO
Stand: 27. Juli 2026 | Version: 1.2 | Verantwortlicher: KYTH. Systems UG (haftungsbeschränkt)
1. Vertraulichkeit (Art. 32 Abs. 1 lit. b DSGVO)
1.1 Zutrittskontrolle (physisch)
Maßnahmen, die geeignet sind, Unbefugten den Zutritt zu Datenverarbeitungsanlagen zu verwehren, mit denen personenbezogene Daten verarbeitet oder genutzt werden.
- Hosting in einem nach ISO 27001 zertifizierten Rechenzentrum der IONOS SE in Berlin (Deutschland) — kein eigener Server-Standort des Auftragsverarbeiters.
- Zutrittskontrollen des Rechenzentrums (Vereinzelungsanlagen, Vier-Augen-Prinzip, biometrischer Zugang, Videoüberwachung, 24/7-Bewachung) sind durch IONOS gewährleistet und im IONOS-AVV vertraglich abgesichert.
- Keine physische Übergabe von Datenträgern an Mitarbeiter oder Dritte; sämtliche Verwaltung erfolgt remote über verschlüsselte SSH-Verbindungen.
1.2 Zugangskontrolle (logisch)
Maßnahmen, die verhindern, dass Datenverarbeitungssysteme von Unbefugten genutzt werden können.
- Shopify-Händler-Zugang: OAuth 2.0 (Shopify-Standard) + Shopify Session Token (JWT HS256) — Multi-Tenant-Isolation pro Shop;
- Admin-Zugang: E-Mail/Passwort-Authentifizierung mit PBKDF2-SHA256 (310.000 Iterationen) für Passwort-Hashing;
- Intranet/Backend-Zugang: HTTP Basic Authentication +
HMAC-signierte Session-Cookies (
KARL_INTRANET_SECRET); - Datenbank-Zugang: kein Direktzugang aus dem Internet — der Datenbank-Port ist nicht nach außen veröffentlicht, die Verbindung läuft ausschließlich innerhalb des Container-Netzwerks (Coolify); Zugang zum Host nur schlüsselbasiert per SSH;
- SSH-Zugang zum Server: ausschließlich Schlüssel-basiert (kein Passwort-Login), nur Geschäftsführung;
- HMAC-Verifizierung auf allen Shopify-OAuth-Callbacks und GDPR-Webhook-Endpoints (Schutz vor unauthorisierten Webhook-Calls).
1.3 Zugriffskontrolle (Daten)
Maßnahmen, die gewährleisten, dass die zur Benutzung eines Datenverarbeitungssystems Berechtigten ausschließlich auf die ihrer Zugriffsberechtigung unterliegenden Daten zugreifen können.
- Multi-Tenant-Isolation: sämtliche datenhaltenden Tabellen führen
eine
shop_id-Spalte; alle Anwendungs-Queries enthalten zwingendWHERE shop_id = %s; - Per-Request ContextVar: der aktuelle Shop-Kontext wird über Python
contextvars.ContextVarisoliert pro Request gehalten — keine globalen Zustandsvariablen; - Tabellen-Whitelist (
_ALLOWED_TABLES): dynamische Tabellennamen sind ausschließlich gegen eine Whitelist zulässig (Schutz gegen SQL-Injection bei generischer GDPR-Löschung); - Parametrisierte SQL-Queries: ausschließlich
%s-Placeholder, niemals f-string-Interpolation für User-Input; - Zugriffsbeschränkung der Händler-Mitarbeiter: Wer die App im
Shopify-Adminbereich öffnen darf, bestimmt der Händler über die Mitarbeiter-Berechtigungen
seines Shopify-Kontos; jede Anfrage an KARL wird gegen den von Shopify signierten
Session-Token geprüft. Innerhalb dieses Rahmens führt KARL zusätzlich Nutzer-Rollen in
admin_users.role(„admin", „user") — sie steuern den Funktionsumfang der Oberfläche (etwa das Ausblenden von Preisen) und ersetzen nicht die Rechtevergabe in Shopify; - Verschlüsselung lookuper-Felder: z. B. Admin-E-Mail-Adressen werden
verschlüsselt gespeichert; SQL-Lookups erfolgen über deterministischen
HMAC-SHA256-Hash (
email_lookup_hash) ohne Klartext-Speicherung.
1.4 Trennungskontrolle (separate Verarbeitung)
Maßnahmen, die gewährleisten, dass zu unterschiedlichen Zwecken erhobene Daten getrennt verarbeitet werden können.
- Logische Trennung der Mandanten (Shopify-Händler) auf Datenbankebene über
shop_id; - Sandbox-Modus pro Shop (
shop_settings.sandbox_mode): produktive und Sandbox-Aufträge werden auf Anwendungsebene strikt getrennt — Sandbox erzeugt weder echte Versandetiketten noch echte Carrier-API-Calls; - Beta- und Production-Umgebung über
SENTRY_ENVIRONMENT(DefaultbetabeiKARL_BETA_MODE=true, sonstproduction) getrennt im Error-Tracking auswertbar.
1.5 Pseudonymisierung (Art. 32 Abs. 1 lit. a DSGVO)
- Sämtliche Empfänger-PII (Name, Firma, Adress-Felder mit personenbezogenem Bezug, E-Mail, Telefon) werden mit AES-256-GCM verschlüsselt gespeichert;
- Carrier-API-Request-/Response-Logs (
api_request_json,api_response_json) werden ebenfalls verschlüsselt — Klartext-Adressen sind in diesen Logs nicht zugänglich; - Lookups erfolgen für ausgewählte Felder über deterministischen HMAC-Hash
(z. B.
email_lookup_hash) — kein Reverse-Lookup von Pseudonym auf Klartext außerhalb des AES-Keys möglich; - Logs (
logger.*) enthalten gemäß interner Coding-Konvention keine PII (kein Name, keine Adresse, keine E-Mail, keine Telefonnummer).
1.6 Verschlüsselung (Art. 32 Abs. 1 lit. a DSGVO)
| Datenart | Methode | Schutzrichtung |
|---|---|---|
| Empfänger-Name, Firma, Straße, Adresszusatz, Telefon, E-Mail | AES-256-GCM (Python cryptography) |
at-rest |
| API-Logs (Carrier-Request/Response) | AES-256-GCM | at-rest |
| Shop-Settings (Absender-PII) | AES-256-GCM auf JSONB-Feld | at-rest |
| Label-PDFs (Base64) | AES-256-GCM | at-rest |
| Shopify OAuth-Tokens | AES-256-GCM | at-rest |
| Carrier-API-Credentials (BYOAK) | AES-256-GCM | at-rest |
| Carrier-Account-Passwörter | AES-256-GCM | at-rest |
| Portokasse OAuth-Tokens | AES-256-GCM | at-rest |
| eBay OAuth-Tokens | AES-256-GCM | at-rest |
| UPS OAuth-Tokens („Mit UPS verbinden") | AES-256-GCM | at-rest |
| Admin-E-Mail + Name | AES-256-GCM (+HMAC-Lookup-Hash) | at-rest |
| Admin-Passwörter | PBKDF2-SHA256, 310.000 Iter., zufälliger Salt pro User | at-rest (one-way) |
| Backups (pg_dump) | GPG AES-256 (symmetrisch, Passphrase-basiert) | at-rest (Backup-Storage) |
| Backups (wal-g WAL) | libsodium AES-256 + lz4-Kompression | at-rest (Backup-Storage) |
| Sämtliche externen Verbindungen | TLS 1.2+ (Let's Encrypt via Traefik) | in-transit |
| Database-Connection | Nicht nach außen veröffentlicht; ausschließlich innerhalb des Container-Netzwerks erreichbar. Personenbezogene Felder sind zusätzlich bereits auf Feldebene AES-256-GCM verschlüsselt (siehe Zeilen oben), verlassen die Anwendung also nicht im Klartext. | Netzwerk-Isolation + Feldverschlüsselung |
Schlüsselverwaltung: Der AES-Schlüssel wird über die Environment-Variable
AES_KEY in Coolify gehalten (verschlüsselt im Coolify-Vault). Bei
KARL_BETA_MODE=false ist AES_KEY Pflicht — der Application-Server
verweigert beim Startup ohne Schlüssel den Start (RuntimeError, Fail-Closed).
Schlüsselrotation erfolgt via dediziertem Skript
(scripts/rotate-aes-key.py) mit Alt-/Neu-Schlüssel-Übergangsphase
(KARL_OLD_AES_KEY + KARL_NEW_AES_KEY).
2. Integrität (Art. 32 Abs. 1 lit. b DSGVO)
2.1 Eingabekontrolle
Maßnahmen, die gewährleisten, dass nachträglich überprüft und festgestellt werden kann, ob und von wem personenbezogene Daten in Datenverarbeitungssysteme eingegeben, verändert oder entfernt worden sind.
- Audit-Log (
audit_log-Tabelle): jede DSGVO-relevante Aktion (shop_redact,customers_redact,data_request, manuelle Datenkorrekturen) wird mit Zeitstempel, Aktion und betroffener Shop-ID protokolliert (Art. 30 Abs. 2 DSGVO); - Sub-Processor-Änderungs-Historie: Änderungen der Sub-Processor-Liste
werden über die versionierte, datierte Sub-Processor-Übersicht
(
/sub-processors+ maschinenlesbarer/api/sub-processors.json-Feed) sowie die Versionshistorie des Dokuments nachvollziehbar dokumentiert; - Versand-Audit-Trail: jedes erstellte Versandetikett wird mit über
50 Feldern protokolliert (
shipments-Tabelle), inklusive vollständiger Carrier-API-Request- und Response-JSONs (verschlüsselt); - Application-Logs: Server-Anwendungs-Logs (Uvicorn) enthalten Timestamp, Request-ID und Endpoint, jedoch keine PII (siehe 1.5);
- Error-Tracking (GlitchTip): automatisches Logging von
Anwendungs-Exceptions inklusive Stack-Trace; PII-Scrubbing über
before_send-Hook inapp.py.
2.2 Schutz vor SQL-Injection und XSS
- Parametrisierte SQL-Queries mit psycopg2
%s-Placeholder; - Tabellen-Whitelist (
_ALLOWED_TABLES) für dynamische Tabellennamen; - HTML-Escape (
html.escape()) auf jeglichem User-Input vor HTML-Rendering; - Content-Security-Policy (CSP) Middleware mit
frame-ancestorsfür Shopify Embedded; - Regelmäßige interne Security-Audits (siehe
docs/audit/im Repository).
2.3 Schutz vor unautorisiertem Lese-/Schreibzugriff
autocommit=Falsein der Datenbankverbindung — atomare Transaktionen mit explizitem Commit (Pflicht für Multi-Statement-DSGVO-Löschung);- Vorschalten von
FOR UPDATE-Locks bei kritischen Schreibvorgängen (z. B. Order-State-Übergänge); - Connection-Pool mit
min=2, max=15ThreadedConnectionPool für saubere Connection-Lifecycles.
3. Verfügbarkeit und Belastbarkeit (Art. 32 Abs. 1 lit. b DSGVO)
3.1 Verfügbarkeit
- Hosting: IONOS VPS L+ (6 vCores, 8 GB RAM, 240 GB NVMe), Berlin, Deutschland — Multi-Tenant-Coolify-Plattform mit Health-Checks;
- HEALTHCHECK: Docker-Healthcheck via curl auf
/health-Endpoint — Coolify überwacht die Verfügbarkeit kontinuierlich; - Background Jobs: APScheduler für periodische Aufgaben (Tracking-Updates 4h, DSGVO-Bereinigung täglich 03:00 UTC, Billing-Sync stündlich);
- Angestrebte Verfügbarkeit: 99,5% (monatlich, exkl. geplanter Wartung und Carrier-API-Ausfälle).
3.2 Belastbarkeit gegen Angriffe
- Rate-Limiting auf API-Ebene (
karl/services/rate_limiter.py); - HMAC-Verifizierung schützt Webhook-Endpoints vor unauthorisierten Calls;
- CSP-Middleware reduziert XSS-Angriffsfläche;
- Container-Härtung: Application läuft im Docker-Container als nicht-root-User
(
USER karlseit v0.0.598 im Dockerfile); - Regelmäßige Updates der Python- und Node-Dependencies (
pip-audit,npm audit) als Teil des CI/CD-Prozesses.
3.3 Wiederherstellbarkeit (Art. 32 Abs. 1 lit. c DSGVO)
- wal-g WAL-Streaming (Phase 5b): client-side libsodium-AES-256 + lz4-Kompression + IONOS S3 — Sub-Sekunden Point-in-Time-Recovery;
- wal-g daily base backup: 03:00 UTC, 7-Tage-Retention via
wal-g delete retain FULL 7; - Objektsperre (WORM): Der Backup-Bucket ist mit Object Lock im Modus GOVERNANCE (30 Tage) und Versionierung konfiguriert — Schutz gegen Ransomware und nachträgliche Manipulation;
- pg_dump GPG-encrypted Cron:
/opt/karl-backup/backup.sh:pg_dump | gzip | gpg AES256auf IONOS S3, stündlich; - Coolify built-in pg_dump-Backup ist deaktiviert (war nicht client-side encrypted) — Reduktion der Angriffsfläche;
- Wiederherstellungs-Tests: Verfahren, Szenarien und Erfolgskriterien sind in einem
Wiederherstellungsplan dokumentiert (Restore aus letztem Base-Backup + WAL-Replay auf
separater Instanz). Tests sind mindestens halbjährlich vorgesehen und werden mit Datum
und Ergebnis protokolliert. Der erste vollständige Durchlauf wurde am
27.07.2026 durchgeführt: Wiederherstellung aus dem verschlüsselten
Datenbank-Abzug auf eine separate Instanz, anschließend Stichprobenprüfung der
verschlüsselten Felder mit dem produktiven Schlüssel — fehlerfrei, mit protokollierter
Wiederherstellungszeit. Das Protokoll liegt im Repository unter
docs/restore-tests/. Der Wiederherstellungsweg über fortlaufende Transaktionsprotokolle (WAL-Replay) ist eingerichtet, aber noch nicht separat durchgespielt; er ist für den nächsten Turnus vorgesehen.
4. Verfahren zur regelmäßigen Überprüfung (Art. 32 Abs. 1 lit. d DSGVO)
4.1 Regelmäßige Überprüfung der TOMs
- Jährliche oder anlassbezogene Überprüfung der TOMs auf Wirksamkeit und Anpassung an den Stand der Technik;
- Wesentliche Änderungen werden im Audit-Log und im Versions-Header dieses Dokuments dokumentiert;
- Auftraggeber werden über wesentliche Änderungen mit angemessener Vorlauffrist informiert.
4.2 Interne Security-Audits
- Regelmäßige interne Security-Audits (Code-Review, Dependency-Audits, GDPR-Sweep);
- Erkenntnisse werden in
docs/audit/als zeitstempelbenannte Audit-Berichte abgelegt (z. B.2026-04-19-security-gdpr-shopify-audit.md); - Findings nach Severity (CRITICAL / HIGH / MEDIUM / LOW) klassifiziert; CRITICAL und HIGH werden vor Releases gefixt.
4.3 Auftragskontrolle (Art. 28 DSGVO)
- Mit jedem Sub-Processor wird ein eigener AVV nach Art. 28 DSGVO geschlossen;
- Sub-Processor-Liste (Sub-Processor-Liste) wird öffentlich geführt;
- Änderungen werden mit 30-Tage-Vorlauffrist und Widerspruchsrecht des Auftraggebers kommuniziert (siehe AVV § 6).
4.4 Datenschutz durch Technikgestaltung und durch datenschutzfreundliche Voreinstellungen (Art. 25 DSGVO)
- Datenminimierung: KARL liest aus Shopify ausschließlich die für den Versandprozess erforderlichen Felder (Bestellinhalte, Adressen) — keine Profilbildung, kein Tracking, keine Weitergabe an Dritte zu Werbezwecken;
- Privacy by Design: Pseudonymisierung (Verschlüsselung) ist Default für alle PII-Spalten; ein Opt-out gibt es nicht;
- Privacy by Default: Sandbox-Modus ist nicht aktiviert; Beta-Modus mit unverbindlichen Test-Carrier-Calls; Live-Modus erfordert explizite Aktivierung durch den Händler.
5. Datenträgerverwaltung und Datenträgervernichtung
- Keine physischen Datenträger beim Auftragsverarbeiter — sämtliche Datenhaltung erfolgt auf gemieteten Cloud-Servern (IONOS).
- Bei Außerbetriebnahme der IONOS-Hardware übernimmt IONOS die DSGVO-konforme Datenträgervernichtung (siehe IONOS-AVV).
- Backups im S3-Object-Storage laufen durch die Retention-Policy automatisch aus: wal-g-Basis-Backups nach rund 7 Tagen, die stündlichen verschlüsselten Datenbank-Abzüge nach 30 Tagen. Der Bucket ist mit Objektsperre (WORM, Modus GOVERNANCE, 30 Tage) und Versionierung konfiguriert — ein geschriebenes Backup ist in dieser Zeit weder überschreibbar noch löschbar, auch nicht mit gültigen Zugangsdaten.
6. Eingabe-, Übertragungs- und Auftragskontrolle
- Eingabe: Eingaben in die App erfolgen ausschließlich über authentifizierte Browser-Sessions (Shopify-OAuth) oder über signierte Webhooks (HMAC-verifiziert);
- Übertragung: Sämtliche Übertragungen außerhalb des Servers erfolgen verschlüsselt (TLS 1.2+);
- Übermittlung an Dritte: nur an die in der Sub-Processor-Liste aufgeführten Empfänger und nur zum jeweils dort genannten Zweck;
- Auftrag: Verarbeitung ausschließlich auf dokumentierte Weisung des Auftraggebers (siehe AVV § 9).
7. Datenpannen-Meldeprozess (Art. 33, 34 DSGVO)
- Bei Bekanntwerden einer Datenpanne wird der betroffene Auftraggeber innerhalb von 24 Stunden per E-Mail an die hinterlegte Kontakt-Adresse benachrichtigt (siehe AVV § 8);
- Parallel wird das Ereignis im internen Incident-Response-Plan
(
docs/incident-response.html) dokumentiert; - Die Meldung an die Aufsichtsbehörde gemäß Art. 33 Abs. 1 DSGVO erfolgt in der Verantwortung des betroffenen Auftraggebers — der Auftragsverarbeiter unterstützt mit allen nötigen Informationen.
8. Verantwortliche Stellen und Aufsichtsbehörde
- Auftragsverarbeiter: KYTH. Systems UG (haftungsbeschränkt), Prof.-Mederer-Str. 4, 92348 Berg, Deutschland;
- Datenschutz-Kontakt: datenschutz@kyth.systems;
- Zuständige Aufsichtsbehörde: Bayerisches Landesamt für Datenschutzaufsicht (BayLDA), Promenade 18, 91522 Ansbach, www.lda.bayern.de;
- Datenschutzbeauftragter: Aufgrund der Unternehmensgröße besteht keine Pflicht zur Bestellung eines DSB nach § 38 BDSG. Datenschutz-Anfragen werden zentral durch die Geschäftsführung beantwortet.