Privacy by Design als Aufgabe im Code, nicht im Vertrag
Die DSGVO verlangt von Entwicklerteams weit mehr als eine Datenschutzerklaerung. Datenminimierung im Datenbankschema, ein tatsaechlich funktionierendes Recht auf Loeschung ueber Backups und Drittanbieter hinweg, und die Faehigkeit, innerhalb von 72 Stunden zu melden, welche Daten betroffen sind, sind konkrete technische Aufgaben. Dieser Artikel zeigt, wie sich diese Anforderungen im Code und in der Magento-Architektur umsetzen lassen.
Inhaltsverzeichnis
- 1. Privacy by Design und by Default als technische Pflicht
- 2. Datenminimierung im Datenbankschema
- 3. Pseudonymisierung und Anonymisierung im Unterschied
- 4. Recht auf Loeschung: Die eigentliche Herausforderung
- 5. Loeschung in Backups, Logs und Caches
- 6. Drittanbieter und Auftragsverarbeiter technisch einbinden
- 7. Meldebereitschaft: die 72-Stunden-Frist technisch vorbereiten
- 8. Magento-Kundendaten: EAV, Exporte und Loeschtools
- 9. Technische Anforderungen im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Privacy by Design und by Default als technische Pflicht
Art. 25 DSGVO verlangt Datenschutz durch Technikgestaltung und durch datenschutzfreundliche Voreinstellungen, formuliert als rechtliche Pflicht, aber inhaltlich eine reine Architekturfrage. Privacy by Design bedeutet konkret: Bevor die erste Zeile Code geschrieben wird, muss feststehen, welche personenbezogenen Daten fuer welchen Zweck tatsaechlich noetig sind, wie lange sie aufbewahrt werden und wer darauf zugreifen darf. Wird diese Frage erst nachtraeglich gestellt, nachdem ein Datenmodell bereits produktiv ist, wird jede spaetere Korrektur zu einer aufwendigen Migration statt einer bewussten Designentscheidung.
Privacy by Default verlangt zusaetzlich, dass ohne aktives Zutun des Nutzers automatisch die datenschutzfreundlichste Einstellung gilt: ein neu angelegtes Kundenkonto darf nicht standardmaessig an Marketing-Tools uebertragen werden, ein Profilfeld darf nicht standardmaessig oeffentlich sichtbar sein. In der Praxis bedeutet das fuer Entwickler, bei jedem neuen Feature zuerst die datensparsamste Variante zu implementieren und Erweiterungen wie zusaetzliche Tracking-Parameter oder erweiterte Profildaten explizit opt-in zu gestalten, nicht opt-out.
2. Datenminimierung im Datenbankschema
Datenminimierung nach Art. 5 Abs. 1 lit. c DSGVO ist kein abstraktes Prinzip, sondern zeigt sich direkt im Datenbankschema: Jede Spalte, die personenbezogene Daten enthaelt, muss einem klar dokumentierten Zweck zugeordnet sein. Ein haeufiger Fehler in Magento-Projekten ist das Anlegen zusaetzlicher Kundenattribute "fuer spaeter", etwa ein Freitextfeld fuer interne Notizen, das faktisch beliebige personenbezogene Informationen aufnehmen kann, ohne dass ein Loeschkonzept dafuer existiert. Jedes zusaetzliche Feld erweitert die Angriffsflaeche und die Komplexitaet einer spaeteren Loeschung gleichermassen.
Praktisch bedeutet Datenminimierung im Schema-Design: Pflichtfelder auf das rechtlich und operativ Notwendige beschraenken, Aufbewahrungsfristen direkt als TTL-Mechanismus im System hinterlegen statt nur in einer Datenschutzerklaerung zu dokumentieren, und regelmaessige Datenbereinigung als Cronjob statt als manuellen, oft vergessenen Prozess einzuplanen. Ein db_schema.xml, das jede personenbezogene Spalte mit einem Kommentar zum Verarbeitungszweck versieht, macht spaetere Audits und DSFA-Bewertungen erheblich einfacher.
<!-- app/code/Mironsoft/CustomerPrivacy/etc/db_schema.xml -->
<!-- Data minimization: every PII column documents its processing purpose -->
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="customer_marketing_consent" resource="default" engine="innodb"
comment="Stores only the minimum required for consent proof, no raw campaign payloads">
<column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="true"
comment="Purpose: primary key"/>
<column xsi:type="int" name="customer_id" padding="10" unsigned="true" nullable="false"
comment="Purpose: link to customer, required for erasure cascade"/>
<column xsi:type="boolean" name="marketing_opt_in" nullable="false" default="false"
comment="Purpose: consent flag, no raw tracking data stored here"/>
<column xsi:type="timestamp" name="consent_timestamp" nullable="false"
comment="Purpose: proof of consent timing, required for Art. 7(1) accountability"/>
<column xsi:type="varchar" name="consent_version" nullable="false" length="16"
comment="Purpose: which banner/policy version was accepted"/>
<!-- Deliberately no free-text "notes" column: no undocumented PII sink -->
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="entity_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="MARKETING_CONSENT_CUSTOMER_ID"
table="customer_marketing_consent" column="customer_id"
referenceTable="customer_entity" referenceColumn="entity_id"
onDelete="CASCADE"/>
</table>
</schema>
3. Pseudonymisierung und Anonymisierung im Unterschied
Diese beiden Begriffe werden in Entwicklerteams haeufig verwechselt, obwohl der Unterschied rechtlich erheblich ist. Pseudonymisierung ersetzt direkte Identifikatoren durch ein Pseudonym, wobei eine Re-Identifizierung mit zusaetzlichem Wissen, etwa einer separat gespeicherten Zuordnungstabelle, weiterhin moeglich bleibt. Pseudonymisierte Daten gelten deshalb weiterhin als personenbezogene Daten im Sinne der DSGVO und unterliegen allen ihren Anforderungen, bieten aber einen zusaetzlichen Schutzmechanismus, etwa wenn Analytics-Daten mit einer Kunden-ID statt Klarnamen und E-Mail verarbeitet werden.
Anonymisierung hingegen entfernt den Personenbezug unwiderruflich, sodass auch mit zusaetzlichem Wissen keine Re-Identifizierung mehr moeglich ist. Echte Anonymisierung ist technisch deutlich anspruchsvoller als oft angenommen: Das blosse Loeschen von Name und E-Mail reicht nicht, wenn eine Kombination aus IP-Adresse, Bestellhistorie und Zeitstempel weiterhin eine eindeutige Zuordnung erlaubt. Erst echt anonymisierte Daten fallen aus dem Anwendungsbereich der DSGVO heraus, weshalb sich viele vermeintlich "anonymisierte" Auswertungen bei genauer Pruefung als lediglich pseudonymisiert herausstellen.
4. Recht auf Loeschung: Die eigentliche Herausforderung
Art. 17 DSGVO verpflichtet zur Loeschung personenbezogener Daten auf Antrag, sofern kein gesetzlicher Aufbewahrungsgrund entgegensteht, etwa handels- oder steuerrechtliche Fristen fuer Rechnungsdaten. Die technische Schwierigkeit liegt selten in der eigentlichen Loeschung eines Datensatzes aus der Haupttabelle, sondern in der Vollstaendigkeit: Ein Kunde existiert in einer modernen E-Commerce-Architektur nicht nur in customer_entity, sondern in Suchindizes, Caches, Analytics-Datenbanken, E-Mail-Marketing-Tools, CRM-Systemen und Log-Dateien. Eine Loeschroutine, die nur die primaere Datenbanktabelle bereinigt, erfuellt die Anforderung nicht.
Ein sauberes Loeschkonzept verlangt deshalb eine zentrale Datenkarte, die dokumentiert, in welchen Systemen personenbezogene Daten eines Kunden ueberhaupt existieren koennen. Diese Karte ist die Grundlage fuer eine Loeschroutine, die systematisch jedes System durchlaeuft, statt bei jeder Anfrage neu zu recherchieren, wo ueberall Daten liegen koennten. Fuer Daten mit gesetzlicher Aufbewahrungspflicht, etwa Rechnungen, ist statt vollstaendiger Loeschung eine Einschraenkung der Verarbeitung nach Art. 18 DSGVO der korrekte Mechanismus: Die Daten bleiben gespeichert, werden aber fuer alle Zwecke ausser der gesetzlichen Aufbewahrung gesperrt.
<?php
declare(strict_types=1);
namespace Mironsoft\CustomerPrivacy\Model;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
/**
* Executes a right-to-erasure request across the primary customer record
* while respecting statutory retention obligations for invoice data.
*/
final class ErasureRequestProcessor
{
public function __construct(
private readonly CustomerRepositoryInterface $customerRepository,
private readonly RetentionObligationChecker $retentionChecker,
private readonly PiiAnonymizer $anonymizer,
private readonly ErasureAuditLogger $auditLogger
) {
}
/**
* Anonymizes erasable fields and logs the action, but keeps invoice-linked
* records intact and merely restricts them per Art. 18 GDPR.
*
* @param int $customerId Entity ID of the customer requesting erasure
* @return void
* @throws NoSuchEntityException When the customer no longer exists
*/
public function process(int $customerId): void
{
$customer = $this->customerRepository->getById($customerId);
if ($this->retentionChecker->hasActiveInvoiceRetention($customerId)) {
// Cannot fully erase: statutory retention for invoices still applies
$this->anonymizer->restrictProcessing($customer);
$this->auditLogger->logRestriction($customerId, 'invoice_retention_active');
return;
}
$this->anonymizer->anonymizeCustomer($customer);
$this->customerRepository->save($customer);
$this->auditLogger->logErasure($customerId);
}
}
5. Loeschung in Backups, Logs und Caches
Backups sind der haeufigste blinde Fleck bei der Umsetzung des Loeschrechts. Ein Kundendatensatz, der heute aus der Live-Datenbank geloescht wird, existiert weiterhin in jedem Backup, das vor der Loeschung erstellt wurde, moeglicherweise ueber Monate hinweg gemaess der Backup-Rotationspolitik. Die pragmatische Loesung ist selten die sofortige Bereinigung jedes einzelnen Backups, sondern eine dokumentierte, kurze Backup-Aufbewahrungsfrist kombiniert mit der Zusage, dass Backups nur im Wiederherstellungsfall reaktiviert werden, verbunden mit einem Prozess, geloeschte Datensaetze auch nach einer Wiederherstellung erneut zu loeschen.
Log-Dateien enthalten haeufig unbeabsichtigt personenbezogene Daten: IP-Adressen, E-Mail-Adressen in Fehlermeldungen, oder Namen in URL-Parametern von GET-Requests. Eine strukturierte Log-Rotation mit kurzer Aufbewahrungsfrist reduziert das Risiko erheblich, reicht aber nicht als alleinige Massnahme, wenn ein einzelner Kunde eine gezielte Loeschung verlangt. Caches wie Redis-Sessions oder Varnish-Fragmente mit personenbezogenen Daten sollten eine kurze TTL besitzen, damit sie sich innerhalb weniger Stunden von selbst bereinigen, statt ein weiteres System zu sein, das eine manuelle Loeschroutine bedienen muss.
#!/usr/bin/env bash
# find-pii-in-logs.sh - Locate a customer's PII across log files for a targeted erasure request
set -euo pipefail
EMAIL="${1:?Usage: find-pii-in-logs.sh customer@example.com}"
LOG_DIRS=("/var/www/html/var/log" "/var/log/nginx")
REPORT="/tmp/pii-audit-$(date +%Y%m%d%H%M%S).txt"
echo "PII audit for: $EMAIL" > "$REPORT"
echo "Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$REPORT"
echo "---" >> "$REPORT"
for dir in "${LOG_DIRS[@]}"; do
[[ -d "$dir" ]] || continue
echo "[scanning] $dir"
grep -rl --include="*.log" -F "$EMAIL" "$dir" 2>/dev/null | while read -r file; do
count=$(grep -c -F "$EMAIL" "$file" || true)
echo "${file}: ${count} occurrence(s)" >> "$REPORT"
done
done
echo "[done] Report written to $REPORT"
echo "[note] Review manually before deciding on redaction vs. log rotation"
6. Drittanbieter und Auftragsverarbeiter technisch einbinden
Jede Erweiterung, jeder Zahlungsanbieter und jedes Newsletter-Tool, das Kundendaten verarbeitet, ist ein Auftragsverarbeiter im Sinne von Art. 28 DSGVO und muss vertraglich wie technisch in das Loeschkonzept eingebunden werden. Der haeufigste technische Fehler: Ein Kunde wird beim Checkout an einen Payment-Provider oder ein Newsletter-Tool per API uebertragen, aber es existiert keine Gegenrichtung, die bei einer Loeschanfrage auch den externen Datensatz beim Anbieter entfernt. Ohne eine dokumentierte, automatisierte Loesch-API-Anbindung bleibt die Loeschung auf das eigene System beschraenkt, waehrend die Daten beim Drittanbieter unbegrenzt fortbestehen.
Praktisch bedeutet das fuer jede Integration: pruefen, ob der Anbieter eine Loesch- oder Anonymisierungs-API bereitstellt, diese in die eigene Erasure-Pipeline einbinden, und den Auftragsverarbeitungsvertrag (AVV) mit konkreten technischen Fristen fuer die Datenloeschung versehen statt nur mit allgemeinen Formulierungen. Fuer Anbieter ohne Loesch-API bleibt oft nur die manuelle Anfrage per Support-Ticket, was in jedem Loeschprozess als expliziter, dokumentierter Schritt mit Fristueberwachung hinterlegt sein sollte.
7. Meldebereitschaft: die 72-Stunden-Frist technisch vorbereiten
Nach Art. 33 DSGVO muss eine Verletzung des Schutzes personenbezogener Daten innerhalb von 72 Stunden nach Kenntniserlangung an die Aufsichtsbehoerde gemeldet werden. Die technische Voraussetzung fuer eine fristgerechte, inhaltlich korrekte Meldung ist ein System, das zu jedem Zeitpunkt beantworten kann, welche Daten in welchem Umfang betroffen sind, nicht erst nach tagelanger manueller Analyse. Ohne strukturiertes Logging von Datenzugriffen und ohne ein aktuelles Datenverzeichnis (Verzeichnis von Verarbeitungstaetigkeiten nach Art. 30) verstreicht die Frist, waehrend das Team noch herausfindet, welche Tabellen ueberhaupt betroffen waren.
Meldebereitschaft bedeutet konkret: Audit-Logs, die dokumentieren, wer wann auf welche Kundendatensaetze zugegriffen hat, ein aktuelles Inventar aller Systeme mit personenbezogenen Daten, und ein vorbereitetes Template fuer die Erstmeldung, das mit unvollstaendigen, aber vorlaeufigen Informationen ausgefuellt werden kann. Die Meldung darf explizit stufenweise erfolgen, aber nur, wenn ueberhaupt eine erste Meldung fristgerecht moeglich ist, was ohne technische Vorbereitung selten gelingt.
{
"breach_readiness_checklist": {
"data_inventory": {
"last_updated": "2026-07-12",
"systems": [
{ "name": "magento_customer_db", "pii_categories": ["name", "email", "address", "order_history"] },
{ "name": "newsletter_provider", "pii_categories": ["email", "consent_status"] },
{ "name": "payment_gateway", "pii_categories": ["masked_card", "billing_address"] },
{ "name": "application_logs", "pii_categories": ["ip_address", "email_in_error_traces"] }
]
},
"access_audit_logging": {
"enabled": true,
"retention_days": 180,
"covers": ["admin_grid_customer_view", "api_customer_export", "support_ticket_lookup"]
},
"notification_template_ready": true,
"authority_contact": {
"name": "Landesbeauftragter fuer Datenschutz",
"notification_channel": "online_portal",
"sla_hours": 72
},
"dpo_escalation_minutes": 30
}
}
8. Magento-Kundendaten: EAV, Exporte und Loeschtools
Magentos EAV-Datenmodell (Entity-Attribute-Value) verteilt Kundenattribute ueber mehrere Tabellen je nach Datentyp, was Loeschroutinen erschwert, wenn sie naiv nur customer_entity ansprechen. Eigene Kundenattribute landen je nach Typ in customer_entity_varchar, customer_entity_int, customer_entity_text oder customer_entity_datetime, und ein vollstaendiges Loeschen erfordert entweder die Nutzung der Standard-Repository-Methoden, die diese Verteilung korrekt handhaben, oder eine explizite Pruefung aller EAV-Tabellen bei einer Custom-Implementierung. Zusaetzlich verbleiben Kundendaten in sales_order, sales_order_address und verwandten Tabellen auch nach Loeschung des Kundenkontos, da Bestelldaten eigenen Aufbewahrungsfristen unterliegen.
Fuer den Datenexport nach Art. 15 DSGVO (Auskunftsrecht) bietet sich ein zentraler Service an, der alle relevanten Datenquellen buendelt, statt bei jeder Anfrage manuell durch Datenbanktabellen zu suchen. Wichtig ist, dass ein solcher Export-Service auch Custom-Module beruecksichtigt: Jedes eigene Modul, das eine customer_id-Fremdschluesselbeziehung besitzt, muss sich in den zentralen Export- und Loeschprozess einklinken, am besten ueber ein definiertes Interface, das bei der Modulentwicklung verpflichtend implementiert wird.
<?php
declare(strict_types=1);
namespace Mironsoft\CustomerPrivacy\Api;
/**
* Contract every module storing customer-linked PII must implement so the
* central export and erasure pipeline can discover and process its data.
*/
interface CustomerDataProviderInterface
{
/**
* Exports all personal data this module holds for a given customer.
*
* @param int $customerId Entity ID of the customer requesting a data export
* @return array<string, mixed> Structured data, ready to include in an Art. 15 export
*/
public function exportData(int $customerId): array;
/**
* Erases or anonymizes all personal data this module holds for a given customer.
*
* @param int $customerId Entity ID of the customer requesting erasure
* @return bool True if fully erased, false if restricted due to retention obligations
*/
public function eraseData(int $customerId): bool;
}
9. Technische Anforderungen im direkten Vergleich
Viele DSGVO-Anforderungen werden in der Praxis nur formal, aber nicht technisch wirksam umgesetzt. Die folgende Uebersicht stellt haeufige Fehlannahmen der tatsaechlich erforderlichen technischen Umsetzung gegenueber.
| Anforderung | Nicht ausreichend | Technisch korrekt | Warum |
|---|---|---|---|
| Recht auf Loeschung | Nur customer_entity loeschen | Zentrale Erasure-Pipeline ueber alle Module/Systeme | Daten liegen in EAV, Logs, Caches, Drittsystemen |
| Privacy by Default | Marketing-Opt-in vorausgewaehlt | Alle nicht notwendigen Verarbeitungen standardmaessig aus | Art. 25 Abs. 2 verlangt datensparsame Voreinstellung |
| Meldebereitschaft | Manuelle Recherche im Vorfall | Aktuelles Dateninventar plus Audit-Logs | 72h reichen nicht fuer nachtraegliche Recherche |
| Anonymisierung | Nur Name/E-Mail entfernen | Kombinationsrisiko pruefen (IP, Historie, Zeitstempel) | Re-Identifizierung durch Datenkombination moeglich |
| Drittanbieter-Daten | AVV ohne technische Loesch-API | Automatisierte Loesch-API-Anbindung im Vertrag verankert | Vertrag allein loescht keine Datensaetze |
Mironsoft
DSGVO-Technikaudits und Privacy Engineering fuer Magento-Shops
DSGVO technisch wirklich abgedeckt?
Wir pruefen euer Datenmodell auf Datenminimierung, bauen eine zentrale Erasure- und Export-Pipeline ueber alle Module und Drittanbieter hinweg, und bereiten euer Team auf die 72-Stunden-Meldefrist mit einem aktuellen Dateninventar vor.
Datenmodell-Audit
Datenminimierung und Aufbewahrungsfristen im Schema pruefen
Erasure-Pipeline
Zentrale Loesch- und Export-Schnittstelle fuer alle Module aufbauen
Meldebereitschaft
Dateninventar und Audit-Logging fuer die 72-Stunden-Frist einrichten
10. Zusammenfassung
Die technischen Anforderungen der DSGVO loesen sich nicht durch eine aktualisierte Datenschutzerklaerung, sondern durch konkrete Architekturentscheidungen. Privacy by Design und by Default verlangen, Datenminimierung von der ersten Schema-Entscheidung an mitzudenken, statt sie nachtraeglich zu reparieren. Das Recht auf Loeschung ist erst dann technisch erfuellt, wenn eine zentrale Pipeline saemtliche Systeme erreicht, in denen personenbezogene Daten liegen koennen, einschliesslich Backups, Logs, Caches und Drittanbieter-Integrationen, nicht nur die primaere Kundentabelle.
Meldebereitschaft nach Art. 33 DSGVO ist eine Frage der Vorbereitung, nicht der Reaktionsgeschwindigkeit im Ernstfall: Ohne aktuelles Dateninventar und Audit-Logging verstreicht die 72-Stunden-Frist, waehrend noch geklaert wird, welche Systeme ueberhaupt betroffen sind. Fuer Magento-Shops bedeutet das konkret, EAV-Attribute, Sales-Daten und Custom-Module ueber ein einheitliches Interface in Export- und Loeschprozesse einzubinden, statt bei jeder Anfrage erneut zu recherchieren, wo Kundendaten ueberall liegen.
DSGVO/GDPR technische Anforderungen - Das Wichtigste auf einen Blick
Privacy by Design
Datenminimierung ab der ersten Schema-Entscheidung, datensparsame Voreinstellung ohne aktives Zutun des Nutzers.
Recht auf Loeschung
Zentrale Pipeline ueber Datenbank, Backups, Logs, Caches und Drittanbieter, nicht nur die Haupttabelle.
72-Stunden-Meldefrist
Aktuelles Dateninventar und Audit-Logging als Voraussetzung fuer fristgerechte, inhaltlich korrekte Meldung.
Magento EAV
Loeschung und Export ueber alle EAV-Tabellen und Custom-Module via einheitliches Interface, nicht nur customer_entity.