Module 6: Data Privacy & PII Protection
7. Compliance Basics: GDPR, CCPA, and AI
Overview
You've built a complete technical pipeline: PII detection (capsule 03), redaction (04), minimization (05), retention and encryption (06). Each of these techniques exists for a reason that goes beyond engineering — it exists because there are legal frameworks that require personal data protection, and the fines for non-compliance are real and substantial.
This capsule gives you technical awareness of the compliance frameworks most relevant to AI systems: GDPR (Europe), CCPA (California), and the EU AI Act. It doesn't pretend to be — or replace — legal advice. Your legal team defines your organization's specific obligations. But as an engineer who designs and implements AI systems, you need to understand what these frameworks require so your technical decisions are aligned with the legal requirements.
The question isn't "do I have to comply with GDPR?" but "does my AI system process data of people in the EU, California, or jurisdictions with similar regulations?" If the answer is yes — and for most internet-connected AI systems it is — you need your PII Protection Layer designed with compliance in mind.
Important disclaimer
This capsule provides technical awareness about compliance frameworks. It is NOT legal advice. Your organization's specific obligations depend on your jurisdiction, the type of data you process, your relationship with the data subjects, and other factors that only a legal team can assess. Consult data protection lawyers before making compliance decisions.
GDPR: what an AI engineer needs to know
The EU's General Data Protection Regulation (GDPR) is the de facto global standard for personal data protection. If your AI system processes data of people in the EU — even if your company is outside Europe — GDPR applies.
Key principles and their technical impact
gdpr_principles_for_ai = {
"lawfulness_fairness_transparency": {
"article": "Art. 5(1)(a)",
"principle": "Lawfulness, fairness and transparency",
"ai_impact": (
"You need a legal basis to process data with AI. "
"Consent or legitimate interest are the most common bases. "
"You must inform the user that their data will be processed by AI."
),
"technical_action": [
"Implement a consent mechanism before AI processing",
"Record the legal basis of each processing activity",
"Provide clear information about the use of AI in the privacy policy",
],
},
"purpose_limitation": {
"article": "Art. 5(1)(b)",
"principle": "Purpose limitation",
"ai_impact": (
"Data collected for customer support can't be used "
"for fine-tuning without additional consent. Each use of the "
"data needs a specific and documented purpose."
),
"technical_action": [
"Document the purpose of each data flow through the LLM",
"Don't reuse production data for training without authorization",
"Implement access controls by purpose",
],
},
"data_minimization": {
"article": "Art. 5(1)(c)",
"principle": "Data minimisation",
"ai_impact": (
"Only send the strictly necessary data to the LLM. "
"The DataMinimizer from capsule 05 implements this principle."
),
"technical_action": [
"DataMinimizer with per-endpoint policies",
"Exclude unnecessary fields from the LLM context",
"Document what data is sent to the LLM and why",
],
},
"accuracy": {
"article": "Art. 5(1)(d)",
"principle": "Accuracy",
"ai_impact": (
"Personal data processed by AI must be accurate. "
"If the LLM generates incorrect information about a person, "
"this can constitute a violation."
),
"technical_action": [
"Post-LLM filter to verify claims about people",
"Mechanism for users to correct incorrect data",
"Don't present LLM outputs as verified facts",
],
},
"storage_limitation": {
"article": "Art. 5(1)(e)",
"principle": "Storage limitation",
"ai_impact": (
"Data shouldn't be kept longer than necessary. "
"The RetentionScheduler from capsule 06 implements this principle."
),
"technical_action": [
"RetentionScheduler with policies by data type",
"Automatic deletion of expired logs and outputs",
"Don't store full prompts indefinitely",
],
},
"integrity_confidentiality": {
"article": "Art. 5(1)(f)",
"principle": "Integrity and confidentiality",
"ai_impact": (
"You must protect data against unauthorized access. "
"Encryption at rest/transit and access control are mandatory."
),
"technical_action": [
"Encryption at rest for stored data (capsule 06)",
"HTTPS/TLS for all connections",
"Role-based access control for user data",
],
},
}
print("GDPR principles and their impact on AI systems:\n")
for key, info in gdpr_principles_for_ai.items():
print(f" {info['article']}: {info['principle']}")
print(f" AI impact: {info['ai_impact'][:80]}...")
for action in info['technical_action'][:2]:
print(f" → {action}")
print()
Data subject rights
data_subject_rights = {
"right_to_access": {
"article": "Art. 15",
"right": "Right of access",
"what_it_means": (
"The user can request a copy of all their personal data "
"that you process, including data processed by AI."
),
"ai_challenge": (
"What user data is in the LLM logs? "
"In the vector store? In the chat history?"
),
"implementation": [
"Index data by user_id across all stores",
"Ability to export the user's data in a readable format",
"Include AI-processed data in the access report",
],
},
"right_to_erasure": {
"article": "Art. 17",
"right": "Right to erasure (right to be forgotten)",
"what_it_means": (
"The user can request that you delete all their personal data."
),
"ai_challenge": (
"Can you delete a user's data from the vector store? "
"From the logs? From the fine-tuned model that used their data?"
),
"implementation": [
"Ability to delete data by user_id from all stores",
"Deletion of embeddings from the vector store",
"Deletion of chat history and associated logs",
"If you fine-tuned with the user's data: re-train without it",
],
},
"right_to_rectification": {
"article": "Art. 16",
"right": "Right to rectification",
"what_it_means": (
"The user can request that you correct incorrect personal data."
),
"ai_challenge": (
"If the LLM generates incorrect information about a user, "
"how do you correct that in a model you can't edit directly?"
),
"implementation": [
"Mechanism for users to report incorrect data",
"Ability to update/correct data in the LLM context",
"If you use RAG: update source documents with corrected data",
],
},
"right_to_data_portability": {
"article": "Art. 20",
"right": "Right to data portability",
"what_it_means": (
"The user can request their data in a structured, "
"machine-readable format to take it to another service."
),
"ai_challenge": (
"Can you export the conversation history, "
"learned preferences, and AI-processed data?"
),
"implementation": [
"JSON export of chat history",
"Export of AI-processed user data",
"Data portability API",
],
},
"right_to_object": {
"article": "Art. 21",
"right": "Right to object",
"what_it_means": (
"The user can object to the processing of their data, "
"including processing by AI."
),
"ai_challenge": (
"Can you offer your service without AI processing if the "
"user objects? Is there a manual alternative?"
),
"implementation": [
"Per-user flag for opting out of AI processing",
"Alternative route without AI (if viable)",
"Record of objections and actions taken",
],
},
}
print("Data subject rights and their implementation in AI:\n")
for key, info in data_subject_rights.items():
print(f" {info['article']}: {info['right']}")
print(f" {info['what_it_means'][:80]}...")
print(f" AI challenge: {info['ai_challenge'][:60]}...")
for impl in info['implementation'][:2]:
print(f" → {impl}")
print()
Data Subject Access Request (DSAR) handler
from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import Optional
from enum import Enum
class DSARType(Enum):
ACCESS = "access"
ERASURE = "erasure"
RECTIFICATION = "rectification"
PORTABILITY = "portability"
OBJECTION = "objection"
@dataclass
class DSARRequest:
request_id: str
user_id: str
request_type: DSARType
submitted_at: datetime
details: str = ""
status: str = "pending"
deadline: Optional[datetime] = None
def __post_init__(self):
if self.deadline is None:
self.deadline = self.submitted_at + __import__("datetime").timedelta(days=30)
class DSARHandler:
"""Manages Data Subject Access Requests for GDPR compliance."""
def __init__(self):
self.requests: list[DSARRequest] = []
self.data_sources = [
"chat_history",
"llm_logs",
"vector_store",
"user_database",
"audit_logs",
]
def submit_request(
self,
user_id: str,
request_type: DSARType,
details: str = "",
) -> DSARRequest:
"""Registers a new DSAR."""
request = DSARRequest(
request_id=f"DSAR-{len(self.requests) + 1:04d}",
user_id=user_id,
request_type=request_type,
submitted_at=datetime.now(timezone.utc),
details=details,
)
self.requests.append(request)
return request
def process_access_request(self, request: DSARRequest) -> dict:
"""Processes an access request (Art. 15)."""
report = {
"request_id": request.request_id,
"user_id": request.user_id,
"data_found": {},
"sources_checked": self.data_sources,
}
for source in self.data_sources:
report["data_found"][source] = {
"status": "checked",
"records_found": 0,
"note": f"Implement actual {source} query here",
}
request.status = "completed"
return report
def process_erasure_request(self, request: DSARRequest) -> dict:
"""Processes an erasure request (Art. 17)."""
report = {
"request_id": request.request_id,
"user_id": request.user_id,
"deletions": {},
}
for source in self.data_sources:
report["deletions"][source] = {
"status": "deleted",
"records_deleted": 0,
"note": f"Implement actual {source} deletion here",
}
request.status = "completed"
return report
def get_overdue_requests(self) -> list[DSARRequest]:
"""Identifies requests that exceed the 30-day deadline."""
now = datetime.now(timezone.utc)
return [
r for r in self.requests
if r.status == "pending" and r.deadline and r.deadline < now
]
# --- Demo ---
handler = DSARHandler()
access_req = handler.submit_request(
user_id="usr-456",
request_type=DSARType.ACCESS,
details="I want to know what data of mine you process with AI",
)
print(f"DSAR submitted: {access_req.request_id}")
print(f" Type: {access_req.request_type.value}")
print(f" Deadline: {access_req.deadline.strftime('%Y-%m-%d')}")
print(f" Status: {access_req.status}")
report = handler.process_access_request(access_req)
print(f"\nAccess report:")
print(f" Sources checked: {len(report['sources_checked'])}")
for source, info in report['data_found'].items():
print(f" {source}: {info['status']}")
CCPA: California Consumer Privacy Act
CCPA is the most relevant privacy regulation in the United States. If your AI system processes data of California residents (even if your company is outside California), CCPA may apply.
ccpa_key_requirements = {
"right_to_know": {
"section": "§1798.100",
"right": "Right to know what personal information is collected",
"ai_relevance": (
"Consumers can request what data you collect and how you use it, "
"including data processed by AI."
),
"implementation": "Similar to GDPR Art. 15 — export data per user",
},
"right_to_delete": {
"section": "§1798.105",
"right": "Right to delete personal information",
"ai_relevance": (
"Consumers can request deletion of their data. "
"It includes data in vector stores, chat histories, and logs."
),
"implementation": "Similar to GDPR Art. 17 — delete from all stores",
},
"right_to_opt_out": {
"section": "§1798.120",
"right": "Right to opt-out of sale of personal information",
"ai_relevance": (
"If you use consumer data to improve an AI service "
"that you sell to third parties, this could constitute a 'sale' of data."
),
"implementation": "Opt-out flag, don't use data for fine-tuning models you sell",
},
"non_discrimination": {
"section": "§1798.125",
"right": "Right to non-discrimination",
"ai_relevance": (
"You can't discriminate against users who exercise their privacy "
"rights — for example, degrading the AI service quality."
),
"implementation": "Same service quality regardless of opt-outs",
},
"private_right_of_action": {
"section": "§1798.150",
"right": "Private right of action for data breaches",
"ai_relevance": (
"Consumers can sue directly for data breaches. "
"An LLM that reveals personal data could be a breach."
),
"implementation": "PII Protection Layer to prevent disclosure by the LLM",
},
}
print("CCPA — Key requirements for AI:\n")
for key, info in ccpa_key_requirements.items():
print(f" {info['section']}: {info['right']}")
print(f" AI: {info['ai_relevance'][:80]}...")
print(f" Impl: {info['implementation']}")
print()
Key differences GDPR vs CCPA
comparison = {
"scope": {
"gdpr": "Any person in the EU (citizens and residents)",
"ccpa": "California residents (with business thresholds)",
},
"consent_model": {
"gdpr": "Opt-in: you need consent before processing",
"ccpa": "Opt-out: you can process until the consumer says no",
},
"penalties": {
"gdpr": "Up to €20M or 4% of annual global revenue",
"ccpa": "Up to $7,500 per intentional violation + private right of action",
},
"data_definition": {
"gdpr": "'Personal data' — any data that identifies a person",
"ccpa": "'Personal information' — similar, but includes household data",
},
"breach_notification": {
"gdpr": "72 hours to notify the data protection authority",
"ccpa": "'Expeditiously' — no specific deadline",
},
"ai_specific": {
"gdpr": (
"Art. 22: right not to be subject to automated decisions. "
"Requires human oversight for significant decisions."
),
"ccpa": (
"It has no AI-specific provisions, but automated "
"processing of personal data is covered."
),
},
}
print("GDPR vs CCPA — Comparison for AI:\n")
for aspect, info in comparison.items():
print(f" {aspect.upper().replace('_', ' ')}:")
print(f" GDPR: {info['gdpr'][:70]}...")
print(f" CCPA: {info['ccpa'][:70]}...")
print()
EU AI Act: AI-specific regulation
The EU AI Act is the world's first regulation specific to artificial intelligence. It came into force in stages between 2024 and 2026.
ai_act_risk_levels = {
"unacceptable": {
"description": "Prohibited AI systems",
"examples": [
"Social scoring by governments",
"Subliminal manipulation that causes harm",
"Exploitation of people's vulnerabilities",
"Real-time remote biometric identification (with exceptions)",
],
"relevance": "If your AI system does anything on this list, stop.",
},
"high_risk": {
"description": "AI systems subject to strict requirements",
"examples": [
"Recruitment/employment systems",
"Credit scoring",
"Health and diagnosis systems",
"Education and assessment systems",
"Critical infrastructure management",
],
"relevance": (
"If your AI system makes or influences significant decisions "
"about people in these areas, it's 'high risk'."
),
},
"limited_risk": {
"description": "AI systems with transparency obligations",
"examples": [
"Chatbots (must disclose they are AI)",
"Content generators (deep fakes, AI images)",
"Emotion detection systems",
],
"relevance": (
"Most chatbots and AI assistants fall here. "
"You must inform the user they're interacting with AI."
),
},
"minimal_risk": {
"description": "AI systems with no additional obligations",
"examples": [
"Spam filters",
"AI in video games",
"Productivity tools with AI",
],
"relevance": "Recommended best practices, no legal obligations.",
},
}
print("EU AI Act — Risk levels:\n")
for level, info in ai_act_risk_levels.items():
print(f" {level.upper()} RISK")
print(f" {info['description']}")
print(f" Relevance: {info['relevance'][:70]}...")
for ex in info['examples'][:2]:
print(f" - {ex}")
print()
Consent management for AI processing
from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import Optional
from enum import Enum
class ConsentType(Enum):
AI_PROCESSING = "ai_processing"
DATA_COLLECTION = "data_collection"
ANALYTICS = "analytics"
TRAINING_DATA = "training_data"
THIRD_PARTY_SHARING = "third_party_sharing"
class ConsentStatus(Enum):
GRANTED = "granted"
DENIED = "denied"
WITHDRAWN = "withdrawn"
NOT_ASKED = "not_asked"
@dataclass
class ConsentRecord:
user_id: str
consent_type: ConsentType
status: ConsentStatus
granted_at: Optional[datetime] = None
withdrawn_at: Optional[datetime] = None
purpose: str = ""
version: str = "1.0"
class ConsentManager:
"""Manages user consent for AI processing."""
def __init__(self):
self.consents: dict[str, dict[ConsentType, ConsentRecord]] = {}
def request_consent(
self,
user_id: str,
consent_type: ConsentType,
purpose: str,
) -> ConsentRecord:
"""Records that consent was requested."""
record = ConsentRecord(
user_id=user_id,
consent_type=consent_type,
status=ConsentStatus.NOT_ASKED,
purpose=purpose,
)
if user_id not in self.consents:
self.consents[user_id] = {}
self.consents[user_id][consent_type] = record
return record
def grant_consent(
self,
user_id: str,
consent_type: ConsentType,
) -> ConsentRecord:
"""Records that the user granted consent."""
record = self.consents.get(user_id, {}).get(consent_type)
if not record:
record = ConsentRecord(
user_id=user_id, consent_type=consent_type,
status=ConsentStatus.GRANTED,
)
if user_id not in self.consents:
self.consents[user_id] = {}
self.consents[user_id][consent_type] = record
record.status = ConsentStatus.GRANTED
record.granted_at = datetime.now(timezone.utc)
return record
def withdraw_consent(
self,
user_id: str,
consent_type: ConsentType,
) -> ConsentRecord:
"""Records that the user withdrew consent."""
record = self.consents.get(user_id, {}).get(consent_type)
if record:
record.status = ConsentStatus.WITHDRAWN
record.withdrawn_at = datetime.now(timezone.utc)
return record
def check_consent(
self,
user_id: str,
consent_type: ConsentType,
) -> bool:
"""Checks whether the user has active consent."""
record = self.consents.get(user_id, {}).get(consent_type)
return record is not None and record.status == ConsentStatus.GRANTED
def get_user_consents(self, user_id: str) -> list[dict]:
"""Returns all of a user's consents."""
user_consents = self.consents.get(user_id, {})
return [
{
"type": ct.value,
"status": cr.status.value,
"purpose": cr.purpose,
"granted_at": cr.granted_at.isoformat() if cr.granted_at else None,
}
for ct, cr in user_consents.items()
]
# --- Demo ---
cm = ConsentManager()
cm.grant_consent("usr-123", ConsentType.AI_PROCESSING)
cm.grant_consent("usr-123", ConsentType.DATA_COLLECTION)
cm.request_consent("usr-123", ConsentType.TRAINING_DATA, "Improve the model with your conversations")
can_process = cm.check_consent("usr-123", ConsentType.AI_PROCESSING)
can_train = cm.check_consent("usr-123", ConsentType.TRAINING_DATA)
print(f"User usr-123:")
print(f" Can process with AI: {can_process}")
print(f" Can use for training: {can_train}")
print(f"\n All consents:")
for consent in cm.get_user_consents("usr-123"):
print(f" {consent['type']}: {consent['status']}")
# Expected output:
# User usr-123:
# Can process with AI: True
# Can use for training: False
#
# All consents:
# ai_processing: granted
# data_collection: granted
# training_data: not_asked
Compliance checklist for AI
compliance_checklist = {
"data_inventory": {
"item": "Do you have an inventory of all the personal data your AI processes?",
"gdpr_article": "Art. 30 — Record of processing activities",
"implementation": "Document what data, whose, for what, and where it's stored",
"module_reference": "DataMinimizer (capsule 05) + audit logs",
},
"legal_basis": {
"item": "Do you have a legal basis for each type of AI data processing?",
"gdpr_article": "Art. 6 — Lawfulness of processing",
"implementation": "ConsentManager + documentation of legal basis per flow",
"module_reference": "ConsentManager (this capsule)",
},
"privacy_notice": {
"item": "Does your privacy policy mention the use of AI and LLMs?",
"gdpr_article": "Art. 13-14 — Information to be provided",
"implementation": "Update the privacy notice with AI processing details",
"module_reference": "Legal documentation",
},
"pii_detection": {
"item": "Do you detect PII before sending it to the LLM?",
"gdpr_article": "Art. 25 — Data protection by design",
"implementation": "PIIScanner integrated in the pipeline",
"module_reference": "PIIScanner (capsule 03)",
},
"pii_redaction": {
"item": "Do you redact PII before and after AI processing?",
"gdpr_article": "Art. 25 + Art. 32 — Security of processing",
"implementation": "PreLLMRedactor + PostLLMRedactor",
"module_reference": "Redactors (capsule 04)",
},
"data_minimization": {
"item": "Do you send only the necessary data to the LLM?",
"gdpr_article": "Art. 5(1)(c) — Data minimisation",
"implementation": "DataMinimizer with per-endpoint policies",
"module_reference": "DataMinimizer (capsule 05)",
},
"retention_policy": {
"item": "Do you have retention policies for AI logs and data?",
"gdpr_article": "Art. 5(1)(e) — Storage limitation",
"implementation": "RetentionScheduler with automatic deletion",
"module_reference": "RetentionScheduler (capsule 06)",
},
"encryption": {
"item": "Is the data encrypted at rest and in transit?",
"gdpr_article": "Art. 32 — Security of processing",
"implementation": "DataEncryptor + HTTPS for all connections",
"module_reference": "Encryption (capsule 06)",
},
"dsar_handling": {
"item": "Can you process data access/deletion requests?",
"gdpr_article": "Art. 15-22 — Rights of the data subject",
"implementation": "DSARHandler + ability to delete by user_id",
"module_reference": "DSARHandler (this capsule)",
},
"breach_response": {
"item": "Do you have a response plan for AI data breaches?",
"gdpr_article": "Art. 33-34 — Notification of data breach",
"implementation": "Documented procedure + disclosure monitoring",
"module_reference": "Audit logging + monitoring (capsule 06)",
},
"ai_transparency": {
"item": "Do you inform users that they're interacting with AI?",
"gdpr_article": "EU AI Act — Art. 52",
"implementation": "Disclaimer in the user interface",
"module_reference": "UI implementation",
},
"vendor_assessment": {
"item": "Have you assessed your LLM provider (OpenAI, etc.) as a data processor?",
"gdpr_article": "Art. 28 — Processor",
"implementation": "Data Processing Agreement (DPA) with the AI provider",
"module_reference": "Legal + procurement",
},
}
print("Compliance Checklist for AI:\n")
completed = 0
total = len(compliance_checklist)
for key, item in compliance_checklist.items():
has_implementation = "capsule" in item["module_reference"].lower()
status = "✅" if has_implementation else "⬜"
if has_implementation:
completed += 1
print(f" {status} {item['item'][:70]}...")
print(f" GDPR: {item['gdpr_article']}")
print(f" Ref: {item['module_reference']}")
print()
print(f"\n Score: {completed}/{total} items with technical implementation")
# Expected output:
# ✅ Do you detect PII before sending it to the LLM?...
# GDPR: Art. 25 — Data protection by design
# Ref: PIIScanner (capsule 03)
# ...
Data Protection Impact Assessment (DPIA)
GDPR Art. 35 requires a DPIA for high-risk processing, including large-scale automated processing of personal data.
@dataclass
class DPIASection:
section: str
description: str
ai_considerations: list[str]
your_answers: list[str] = field(default_factory=list)
dpia_template = [
DPIASection(
section="1. Description of the processing",
description="What data do you process, whose, and for what?",
ai_considerations=[
"User inputs you send to the LLM",
"RAG documents that contain PII",
"Model outputs that may contain PII",
"Logs and auditing of the processing",
],
),
DPIASection(
section="2. Necessity and proportionality",
description="Is the AI processing necessary to achieve the objective?",
ai_considerations=[
"Could you achieve the same without AI?",
"Do you send only the necessary data to the LLM (data minimization)?",
"Does the benefit justify the risk of AI processing?",
],
),
DPIASection(
section="3. Risks to the data subjects",
description="What risks does the person whose data you process face?",
ai_considerations=[
"Risk of disclosure by the LLM (LLM02)",
"Risk of incorrect data generated by AI",
"Risk of re-identification by combining data",
"Risk of discrimination through automated decisions",
],
),
DPIASection(
section="4. Mitigation measures",
description="What measures do you implement to reduce the risks?",
ai_considerations=[
"PII detection and redaction (capsules 03-04)",
"Data minimization (capsule 05)",
"Retention policies and encryption (capsule 06)",
"Consent management (this capsule)",
"Post-LLM filtering of outputs",
],
),
]
print("DPIA Template for AI systems:\n")
for section in dpia_template:
print(f" {section.section}")
print(f" {section.description}")
for consideration in section.ai_considerations[:3]:
print(f" → {consideration}")
print()
Connection to the project
The compliance awareness from this capsule informs the design of the PII Protection Layer:
| Legal requirement | Technical component | Capsule |
|---|---|---|
| GDPR Art. 5(1)(c) Data minimisation | DataMinimizer | 05 |
| GDPR Art. 5(1)(e) Storage limitation | RetentionScheduler | 06 |
| GDPR Art. 5(1)(f) Integrity/confidentiality | DataEncryptor | 06 |
| GDPR Art. 15-22 Data subject rights | DSARHandler | 07 (this one) |
| GDPR Art. 25 Data protection by design | PIIScanner + PreLLMRedactor | 03, 04 |
| GDPR Art. 32 Security of processing | Encryption + access control | 06 |
| CCPA §1798.150 Breach prevention | PostLLMRedactor | 04 |
| EU AI Act Art. 52 Transparency | Disclosure in the UI | UI layer |
Troubleshooting
Problem 1: "I don't know if GDPR applies to my AI system"
If you process data of people in the EU — even if your company is outside Europe — GDPR probably applies. If you have EU users and process any personal data (including email for login), consult your legal team.
Problem 2: "A user requested deletion of their data but I can't delete from a fine-tuned model"
This is one of the hardest problems in AI and compliance. If you fine-tuned a model with the user's data, perfect deletion requires re-training without their data. Document the situation and consult your legal team about acceptable alternatives.
Problem 3: "Does data sent to OpenAI count as a data transfer to a third party?"
Yes, under GDPR. OpenAI acts as a "data processor" for your data. You need a Data Processing Agreement (DPA) with OpenAI. OpenAI offers a standard DPA that you can review with your legal team.
Problem 4: "I don't have a legal team — how do I implement compliance?"
Implement the technical best practices from this module (PII detection, redaction, minimization, retention, encryption). Document what you do and why. When you grow, a legal team will be able to audit your technical implementation and adjust what's needed.
Exercises
Exercise 1: Compliance audit for your AI system
Assess your current AI system against the compliance checklist.
See solution
def run_compliance_audit(system_config: dict) -> dict:
checks = {
"pii_detection": system_config.get("has_pii_scanner", False),
"pii_redaction": system_config.get("has_redactor", False),
"data_minimization": system_config.get("has_minimizer", False),
"retention_policy": system_config.get("has_retention", False),
"encryption": system_config.get("has_encryption", False),
"consent": system_config.get("has_consent_manager", False),
"dsar_handling": system_config.get("has_dsar_handler", False),
"ai_transparency": system_config.get("has_ai_disclosure", False),
}
passed = sum(1 for v in checks.values() if v)
total = len(checks)
return {
"score": f"{passed}/{total}",
"percentage": round(passed / total * 100),
"status": "COMPLIANT" if passed >= 6 else "AT_RISK" if passed >= 3 else "NON_COMPLIANT",
"checks": checks,
"gaps": [k for k, v in checks.items() if not v],
}
system = {
"has_pii_scanner": True,
"has_redactor": True,
"has_minimizer": False,
"has_retention": False,
"has_encryption": True,
"has_consent_manager": False,
"has_dsar_handler": False,
"has_ai_disclosure": True,
}
audit = run_compliance_audit(system)
print(f"Compliance Audit: {audit['score']} ({audit['percentage']}%)")
print(f"Status: {audit['status']}")
print(f"Gaps: {audit['gaps']}")
Exercise 2: AI privacy notice generator
Create a function that generates a privacy notice template that includes the AI processing section.
See solution
def generate_ai_privacy_notice(config: dict) -> str:
notice = f"""
PRIVACY NOTICE — AI PROCESSING
{config.get('company_name', 'Our Company')} uses artificial intelligence
to provide and improve our services.
WHAT DATA WE PROCESS WITH AI:
- Your messages and queries submitted to our assistant
- Relevant context from our knowledge base to answer your questions
HOW WE PROTECT YOUR DATA:
- We detect and redact personal information before sending to AI models
- We minimize the data sent to only what's necessary
- All data is encrypted in transit and at rest
- We retain AI processing logs for {config.get('retention_days', 30)} days
YOUR RIGHTS:
- Access: Request a copy of your data processed by AI
- Deletion: Request removal of your data from our AI systems
- Opt-out: Request that your data not be processed by AI
AI PROVIDER: {config.get('ai_provider', 'Third-party AI provider')}
Data Processing Agreement in place: {config.get('has_dpa', 'Yes')}
Contact: {config.get('dpo_email', 'privacy@company.com')}
"""
return notice.strip()
notice = generate_ai_privacy_notice({
"company_name": "TechStore",
"retention_days": 30,
"ai_provider": "OpenAI",
"has_dpa": "Yes",
"dpo_email": "privacy@techstore.com",
})
print(notice[:300] + "...")
Exercise 3: DSAR tracker with deadline monitoring
Create a system that tracks DSARs and alerts when they approach the deadline.
See solution
from datetime import timedelta
class DSARTracker:
def __init__(self):
self.handler = DSARHandler()
self.alerts: list[dict] = []
def check_deadlines(self):
now = datetime.now(timezone.utc)
for req in self.handler.requests:
if req.status != "pending":
continue
days_remaining = (req.deadline - now).days if req.deadline else 0
if days_remaining <= 0:
self.alerts.append({
"request_id": req.request_id,
"severity": "CRITICAL",
"message": f"DSAR {req.request_id} is OVERDUE",
})
elif days_remaining <= 7:
self.alerts.append({
"request_id": req.request_id,
"severity": "WARNING",
"message": f"DSAR {req.request_id} due in {days_remaining} days",
})
def get_dashboard(self) -> dict:
pending = sum(1 for r in self.handler.requests if r.status == "pending")
completed = sum(1 for r in self.handler.requests if r.status == "completed")
return {
"total": len(self.handler.requests),
"pending": pending,
"completed": completed,
"alerts": len(self.alerts),
}
tracker = DSARTracker()
tracker.handler.submit_request("usr-1", DSARType.ACCESS, "Data access request")
tracker.handler.submit_request("usr-2", DSARType.ERASURE, "Delete my data")
tracker.check_deadlines()
dashboard = tracker.get_dashboard()
print(f"DSAR Dashboard: {dashboard}")
Exercise 4: Consent-aware pipeline gate
Create a middleware that checks consent before processing with AI.
See solution
class ConsentGate:
"""Middleware that checks consent before AI processing."""
def __init__(self, consent_manager: ConsentManager):
self.cm = consent_manager
def check(self, user_id: str, required_consents: list[ConsentType]) -> dict:
missing = []
for consent_type in required_consents:
if not self.cm.check_consent(user_id, consent_type):
missing.append(consent_type.value)
return {
"user_id": user_id,
"allowed": len(missing) == 0,
"missing_consents": missing,
"action": "proceed" if not missing else "request_consent",
}
cm = ConsentManager()
cm.grant_consent("usr-123", ConsentType.AI_PROCESSING)
gate = ConsentGate(cm)
result = gate.check("usr-123", [ConsentType.AI_PROCESSING, ConsentType.ANALYTICS])
print(f"Allowed: {result['allowed']}")
print(f"Missing: {result['missing_consents']}")
# Output: Allowed: False, Missing: ['analytics']
Summary
- 🔑 GDPR applies to any AI system that processes data of people in the EU — the 6 principles (lawfulness, purpose limitation, data minimisation, accuracy, storage limitation, integrity) directly impact the system's design
- 🔑 The data subject rights (access, erasure, rectification, portability, objection) require specific technical capabilities — the DSARHandler implements the management flow
- 🔑 CCPA applies to California residents and has an opt-out model (vs GDPR's opt-in) — it includes a private right of action for data breaches
- 🔑 The EU AI Act classifies AI systems by risk level (unacceptable, high, limited, minimal) — most chatbots are "limited risk" and require transparency disclosure
- 🔑 Consent management for AI processing requires explicit consent per processing type, with the ability to withdraw at any time
- 🔑 The DPIA (Data Protection Impact Assessment) is mandatory for large-scale AI processing of personal data — it documents risks and mitigations
- 🔑 Each technical component of the PII Protection Layer maps to a specific legal requirement: PIIScanner → Art. 25, DataMinimizer → Art. 5(1)(c), RetentionScheduler → Art. 5(1)(e)
- 🔑 This capsule is NOT legal advice — it's technical awareness so your engineering decisions are aligned with the compliance frameworks. Consult your legal team.
Additional resources
- GDPR Official Text — Full text of the GDPR with commentary and guides
- CCPA Official Text — California Consumer Privacy Act official text
- EU AI Act Full Text — Full text of the EU AI Act with analysis
- ICO AI Guidance — The UK regulator's guide on AI and GDPR
- CNIL AI Guidelines — The French regulator's guide on AI
- IAPP AI Governance Center — Resources from the International Association of Privacy Professionals on AI
- NIST AI Risk Management Framework — NIST's AI risk management framework
- OpenAI Data Processing Agreement — OpenAI's DPA for reference
Created: March 2026 Version: 1.0