Skip to content

GDPR Article 17 - Right to Erasure

Implement GDPR-compliant data deletion with complete audit trails.

Overview

Article 17 of the GDPR grants individuals the "right to be forgotten" - the right to have their personal data erased. GateFlow provides comprehensive tools to handle erasure requests while maintaining compliance.

When Erasure Applies

Under GDPR Article 17, data subjects can request erasure when:

ConditionDescription
No longer necessaryData is no longer needed for its original purpose
Consent withdrawnSubject withdraws consent and no other legal basis exists
Object to processingSubject objects and no overriding legitimate grounds exist
Unlawfully processedData was collected or processed unlawfully
Legal obligationErasure required by EU or member state law
Child's dataData was collected from a child for online services

Exceptions to Erasure

Erasure may be denied when processing is necessary for:

  • Freedom of expression and information
  • Legal compliance with EU/member state law
  • Public interest in public health
  • Archiving for public interest, research, or statistics
  • Legal claims establishment, exercise, or defense

Handling Erasure Requests

Submit a Request

python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.gateflow.ai/v1",
    api_key="gw_prod_..."
)

# Submit erasure request
response = client.post(
    "/compliance/erasure-requests",
    json={
        "subject_id": "user_abc123",
        "subject_email": "user@example.com",
        "request_type": "full_erasure",
        "reason": "consent_withdrawn",
        "verification": {
            "method": "email_confirmation",
            "verified_at": "2026-02-17T10:00:00Z"
        },
        "scope": {
            "include_backups": True,
            "include_logs": False,  # May need retention for legal
            "include_derived_data": True
        }
    }
)

print(f"Request ID: {response['request_id']}")
print(f"Status: {response['status']}")
print(f"Deadline: {response['deadline']}")  # 30 days from request

cURL Example

bash
curl -X POST https://api.gateflow.ai/v1/compliance/erasure-requests \
  -H "Authorization: Bearer gw_prod_..." \
  -H "Content-Type: application/json" \
  -d '{
    "subject_id": "user_abc123",
    "subject_email": "user@example.com",
    "request_type": "full_erasure",
    "reason": "consent_withdrawn"
  }'

Data Discovery

Find All Subject Data

python
# Discover all data for a subject
discovery = client.post(
    "/compliance/data-discovery",
    json={
        "subject_id": "user_abc123",
        "subject_email": "user@example.com",
        "include_metadata": True
    }
)

print("Data found:")
for category in discovery["data_categories"]:
    print(f"\n{category['name']}:")
    print(f"  Documents: {category['document_count']}")
    print(f"  Vectors: {category['vector_count']}")
    print(f"  Size: {category['total_size_bytes']} bytes")

Example Response:

json
{
  "subject_id": "user_abc123",
  "data_categories": [
    {
      "name": "uploaded_documents",
      "document_count": 15,
      "vector_count": 234,
      "total_size_bytes": 4521984
    },
    {
      "name": "chat_history",
      "document_count": 0,
      "vector_count": 1205,
      "total_size_bytes": 892416
    },
    {
      "name": "audit_logs",
      "document_count": 0,
      "vector_count": 0,
      "total_size_bytes": 125440,
      "retention_required": true,
      "retention_reason": "legal_compliance"
    }
  ],
  "total_items": 1454,
  "total_size_bytes": 5539840
}

Execute Erasure

Approve and Execute

python
# After legal review, execute the erasure
execution = client.post(
    f"/compliance/erasure-requests/{request_id}/execute",
    json={
        "approved_by": "compliance_officer@company.com",
        "approval_notes": "Verified identity, no legal holds apply",
        "exclusions": [
            {
                "category": "audit_logs",
                "reason": "legal_retention_required",
                "retention_until": "2029-02-17"
            }
        ]
    }
)

print(f"Execution ID: {execution['execution_id']}")
print(f"Status: {execution['status']}")

Monitor Execution Progress

python
# Check execution status
status = client.get(
    f"/compliance/erasure-requests/{request_id}/status"
)

print(f"Overall Status: {status['status']}")
print(f"Progress: {status['progress_percent']}%")

for step in status["steps"]:
    print(f"\n{step['name']}:")
    print(f"  Status: {step['status']}")
    print(f"  Items: {step['items_processed']}/{step['items_total']}")

Example Response:

json
{
  "request_id": "erasure_xyz789",
  "status": "in_progress",
  "progress_percent": 65,
  "started_at": "2026-02-17T10:30:00Z",
  "steps": [
    {
      "name": "document_deletion",
      "status": "completed",
      "items_processed": 15,
      "items_total": 15
    },
    {
      "name": "vector_deletion",
      "status": "in_progress",
      "items_processed": 892,
      "items_total": 1439
    },
    {
      "name": "backup_deletion",
      "status": "pending",
      "items_processed": 0,
      "items_total": 3
    }
  ]
}

Partial Erasure

Selective Deletion

python
# Request erasure of specific data categories only
response = client.post(
    "/compliance/erasure-requests",
    json={
        "subject_id": "user_abc123",
        "request_type": "partial_erasure",
        "categories": [
            "uploaded_documents",
            "chat_history"
        ],
        "exclude_categories": [
            "transaction_records"  # Needed for legal/tax purposes
        ],
        "reason": "user_request"
    }
)

Pseudonymization Alternative

python
# When full erasure isn't possible, pseudonymize
response = client.post(
    "/compliance/pseudonymize",
    json={
        "subject_id": "user_abc123",
        "method": "tokenization",
        "categories": ["chat_history"],
        "retain_aggregated": True  # Keep anonymized analytics
    }
)

Audit Trail

Erasure Audit Record

Every erasure creates an immutable audit record:

json
{
  "audit_id": "audit_abc123",
  "event_type": "gdpr_erasure_executed",
  "timestamp": "2026-02-17T11:45:00Z",
  "request_id": "erasure_xyz789",
  "subject_id_hash": "sha256:abc123...",  // Hashed, not plaintext
  "executed_by": "compliance_officer@company.com",
  "data_erased": {
    "documents": 15,
    "vectors": 1439,
    "size_bytes": 5414400
  },
  "exclusions": [
    {
      "category": "audit_logs",
      "reason": "legal_retention_required"
    }
  ],
  "hash": "sha256:def456...",
  "previous_hash": "sha256:ghi789..."
}

Query Erasure History

python
# Get erasure audit trail
audit_log = client.get(
    "/compliance/audit-log",
    params={
        "event_type": "gdpr_erasure_executed",
        "start_date": "2026-01-01",
        "end_date": "2026-02-17"
    }
)

for entry in audit_log["entries"]:
    print(f"{entry['timestamp']}: Request {entry['request_id']}")
    print(f"  Data erased: {entry['data_erased']['documents']} documents")

Notification

Notify Data Subject

python
# Generate completion certificate
certificate = client.post(
    f"/compliance/erasure-requests/{request_id}/certificate",
    json={
        "format": "pdf",
        "language": "en",
        "include_details": True
    }
)

# Certificate includes:
# - Request ID and date
# - Categories of data deleted
# - Any exclusions with reasons
# - Completion timestamp
# - Verification hash

Notify Third Parties

Under Article 17(2), you must notify recipients of the data:

python
# Get list of third parties who received the data
third_parties = client.get(
    f"/compliance/data-sharing/{subject_id}"
)

# Notify each party
for party in third_parties["recipients"]:
    notification = client.post(
        "/compliance/erasure-notifications",
        json={
            "request_id": request_id,
            "recipient": party["id"],
            "recipient_email": party["contact_email"],
            "data_shared": party["data_categories"]
        }
    )

Automated Workflows

Configure Auto-Processing

python
# Set up automated erasure workflow
workflow = client.post(
    "/compliance/erasure-workflows",
    json={
        "name": "standard_erasure",
        "auto_approve": {
            "enabled": True,
            "conditions": [
                {"reason": "consent_withdrawn"},
                {"no_legal_holds": True},
                {"no_active_disputes": True}
            ]
        },
        "verification_required": True,
        "notification": {
            "on_complete": True,
            "include_certificate": True
        },
        "sla_days": 25  # Complete within 25 days (5-day buffer)
    }
)

Compliance Reporting

Generate GDPR Report

python
# Generate compliance report
report = client.post(
    "/compliance/reports",
    json={
        "type": "gdpr_erasure",
        "period": {
            "start": "2026-01-01",
            "end": "2026-02-17"
        },
        "format": "pdf",
        "include": [
            "request_summary",
            "completion_stats",
            "sla_compliance",
            "exceptions"
        ]
    }
)

Key Metrics

MetricDescriptionTarget
Response TimeTime to acknowledge request< 72 hours
Completion TimeTime to execute erasure< 30 days
SLA ComplianceRequests completed on time> 99%
Exception RateRequests requiring exceptions< 5%

Best Practices

  1. Verify identity - Confirm requester is the data subject
  2. Document everything - Maintain complete audit trail
  3. Review legal basis - Check for exceptions before erasure
  4. Include backups - Don't forget backup systems
  5. Notify recipients - Inform third parties per Article 17(2)
  6. Meet deadlines - Complete within 30 days
  7. Provide certificate - Give subject proof of completion

Error Handling

Common Issues

ErrorCauseResolution
legal_hold_activeData under litigation holdWait for hold release
verification_failedIdentity not confirmedRequest additional verification
retention_requiredLegal retention period activeDocument exception
third_party_failedCouldn't notify recipientRetry or document

Next Steps

Built with reliability in mind.