Skip to main content

PDPL & Global Data Protection

Building healthcare applications for international markets requires understanding multiple data protection frameworks. This module covers Saudi Arabia’s PDPL, GDPR, and how they intersect with HIPAA.
Comparison of HIPAA, PDPL, and GDPR requirements

Global Data Protection Framework Comparison

Learning Objectives:
  • Understand Saudi Arabia’s PDPL requirements
  • Map HIPAA controls to PDPL compliance
  • Navigate cross-border data transfers
  • Implement consent management frameworks
  • Handle data localization requirements

Global Data Protection Landscape

┌─────────────────────────────────────────────────────────────────────────────┐
│                 GLOBAL DATA PROTECTION FRAMEWORKS                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  HIPAA (USA)                    PDPL (Saudi Arabia)                         │
│  ──────────                     ───────────────────                         │
│  • Healthcare-specific          • All personal data                         │
│  • PHI protection              • Consent-based model                        │
│  • Business Associates         • Data localization                          │
│  • 1996, updated 2013          • 2021, effective 2023                       │
│                                                                              │
│  GDPR (European Union)          Other Key Regulations                       │
│  ────────────────────           ─────────────────────                       │
│  • All personal data            • PIPEDA (Canada)                           │
│  • Rights-based approach        • LGPD (Brazil)                             │
│  • Data minimization            • POPIA (South Africa)                      │
│  • 2018                         • PDPA (Singapore, Thailand)                │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Saudi Arabia’s PDPL (نظام حماية البيانات الشخصية)

Overview

The Personal Data Protection Law (PDPL) was issued by Royal Decree in September 2021 and became enforceable in 2023. It represents Saudi Arabia’s first comprehensive data protection framework.

Key Definitions

class PDPLDefinitions:
    """Key terms under Saudi PDPL"""
    
    # Personal Data (البيانات الشخصية)
    PERSONAL_DATA = """
    Any data, regardless of source or form, that would 
    identify an individual or make them identifiable, 
    directly or indirectly.
    
    Includes: name, ID number, addresses, contact info,
    photos, financial data, employment data, etc.
    """
    
    # Sensitive Personal Data (البيانات الشخصية الحساسة)
    SENSITIVE_DATA = """
    Personal data revealing:
    - Ethnic or tribal origin
    - Religious, intellectual, or political beliefs
    - Membership in associations
    - Criminal records
    - Health data (including genetic/biometric)
    - Location data
    - Financial data (credit, bank accounts)
    """
    
    # Data Controller (جهة التحكم)
    DATA_CONTROLLER = """
    Any entity that determines the purpose and means 
    of processing personal data.
    """
    
    # Data Subject (صاحب البيانات)
    DATA_SUBJECT = """
    The individual whose personal data is being processed.
    """

PDPL Principles

Lawfulness & Transparency

Processing must be lawful, fair, and transparent to the data subject

Purpose Limitation

Data collected for specific, explicit, and legitimate purposes

Data Minimization

Only collect data necessary for the specified purpose

Accuracy

Keep personal data accurate and up-to-date

Storage Limitation

Retain data only as long as necessary for the purpose

Security

Implement appropriate technical and organizational measures

PDPL vs HIPAA Comparison

┌─────────────────────────────────────────────────────────────────────────────┐
│                        PDPL vs HIPAA COMPARISON                              │
├───────────────────────┬─────────────────────────┬───────────────────────────┤
│       ASPECT          │         PDPL            │          HIPAA            │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ Scope                 │ All personal data       │ Healthcare data only      │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ Legal Basis           │ Consent primary         │ TPO without consent       │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ Data Localization     │ Required (with          │ No requirement            │
│                       │ exceptions)             │                           │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ Breach Notification   │ 72 hours to authority   │ 60 days to individuals    │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ DPO Requirement       │ Yes (for certain        │ No explicit requirement   │
│                       │ entities)               │                           │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ Penalties             │ Up to 5M SAR            │ Up to $1.9M per violation │
│                       │ (~$1.3M USD)            │                           │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ Right to Access       │ Yes                     │ Yes                       │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ Right to Erasure      │ Yes                     │ No (record retention      │
│                       │                         │ requirements)             │
├───────────────────────┼─────────────────────────┼───────────────────────────┤
│ Consent Withdrawal    │ Yes, at any time        │ Limited applicability     │
└───────────────────────┴─────────────────────────┴───────────────────────────┘

Implementing PDPL Compliance

from datetime import datetime
from typing import Optional, List
from enum import Enum
from dataclasses import dataclass, field
import uuid

class ConsentPurpose(Enum):
    """PDPL-defined processing purposes"""
    HEALTHCARE_TREATMENT = "healthcare_treatment"
    HEALTHCARE_PAYMENT = "healthcare_payment"
    HEALTHCARE_OPERATIONS = "healthcare_operations"
    RESEARCH = "research"
    MARKETING = "marketing"
    ANALYTICS = "analytics"
    THIRD_PARTY_SHARING = "third_party_sharing"
    CROSS_BORDER_TRANSFER = "cross_border_transfer"

class ConsentStatus(Enum):
    GRANTED = "granted"
    WITHDRAWN = "withdrawn"
    EXPIRED = "expired"
    PENDING = "pending"

@dataclass
class ConsentRecord:
    """PDPL-compliant consent record"""
    
    consent_id: str = field(default_factory=lambda: str(uuid.uuid4()))
    
    # Data subject
    subject_id: str = ""
    subject_identifier_type: str = "national_id"  # Or passport, etc.
    
    # Consent details
    purpose: ConsentPurpose = ConsentPurpose.HEALTHCARE_TREATMENT
    status: ConsentStatus = ConsentStatus.PENDING
    
    # When and how
    granted_at: Optional[datetime] = None
    withdrawn_at: Optional[datetime] = None
    expires_at: Optional[datetime] = None
    
    # Consent mechanism
    collection_method: str = "electronic"  # electronic, written, verbal
    consent_text_version: str = ""  # Version of consent form
    consent_language: str = "ar"  # Arabic or English
    
    # Evidence
    evidence_type: str = ""  # signature, checkbox, etc.
    evidence_reference: str = ""  # Link to stored evidence
    ip_address: str = ""
    user_agent: str = ""
    
    # Scope
    data_categories: List[str] = field(default_factory=list)
    retention_period_days: int = 0
    third_parties: List[str] = field(default_factory=list)
    
    def is_valid(self) -> bool:
        """Check if consent is currently valid"""
        if self.status != ConsentStatus.GRANTED:
            return False
        if self.expires_at and datetime.utcnow() > self.expires_at:
            return False
        return True


class ConsentManager:
    """Manage consent lifecycle for PDPL compliance"""
    
    def __init__(self, storage, audit_logger):
        self.storage = storage
        self.audit_logger = audit_logger
        
    async def request_consent(
        self,
        subject_id: str,
        purpose: ConsentPurpose,
        consent_text: str,
        data_categories: List[str],
        third_parties: List[str] = None,
        retention_days: int = 365,
    ) -> ConsentRecord:
        """Create a pending consent request"""
        
        record = ConsentRecord(
            subject_id=subject_id,
            purpose=purpose,
            status=ConsentStatus.PENDING,
            consent_text_version=self._hash_consent_text(consent_text),
            data_categories=data_categories,
            third_parties=third_parties or [],
            retention_period_days=retention_days,
        )
        
        await self.storage.save_consent(record)
        await self.audit_logger.log_consent_request(record)
        
        return record
    
    async def grant_consent(
        self,
        consent_id: str,
        evidence_type: str,
        evidence_reference: str,
        ip_address: str,
        user_agent: str,
    ) -> ConsentRecord:
        """Record consent grant with evidence"""
        
        record = await self.storage.get_consent(consent_id)
        if not record:
            raise ValueError("Consent record not found")
            
        record.status = ConsentStatus.GRANTED
        record.granted_at = datetime.utcnow()
        record.expires_at = datetime.utcnow() + timedelta(
            days=record.retention_period_days
        )
        record.evidence_type = evidence_type
        record.evidence_reference = evidence_reference
        record.ip_address = ip_address
        record.user_agent = user_agent
        
        await self.storage.save_consent(record)
        await self.audit_logger.log_consent_grant(record)
        
        return record
    
    async def withdraw_consent(
        self,
        consent_id: str,
        reason: str = None,
    ) -> ConsentRecord:
        """Process consent withdrawal (PDPL requirement)"""
        
        record = await self.storage.get_consent(consent_id)
        if not record:
            raise ValueError("Consent record not found")
            
        record.status = ConsentStatus.WITHDRAWN
        record.withdrawn_at = datetime.utcnow()
        
        await self.storage.save_consent(record)
        await self.audit_logger.log_consent_withdrawal(record, reason)
        
        # Trigger downstream actions (stop processing, schedule deletion)
        await self._handle_withdrawal_consequences(record)
        
        return record
    
    async def check_consent(
        self,
        subject_id: str,
        purpose: ConsentPurpose,
    ) -> bool:
        """Check if valid consent exists for processing"""
        
        records = await self.storage.get_consents_for_subject(
            subject_id, purpose
        )
        
        return any(r.is_valid() for r in records)
    
    async def _handle_withdrawal_consequences(self, record: ConsentRecord):
        """Handle consequences of consent withdrawal"""
        
        # Notify relevant systems to stop processing
        await self.event_bus.publish("consent.withdrawn", {
            "subject_id": record.subject_id,
            "purpose": record.purpose.value,
            "withdrawn_at": record.withdrawn_at.isoformat(),
        })
        
        # Schedule data deletion if no other legal basis
        if not await self._has_other_legal_basis(record):
            await self.deletion_scheduler.schedule(
                subject_id=record.subject_id,
                data_categories=record.data_categories,
                reason="consent_withdrawn",
            )
// React component for PDPL-compliant consent collection

interface ConsentFormProps {
  purposes: ConsentPurpose[];
  onConsent: (consents: ConsentGrant[]) => void;
  language: 'ar' | 'en';
}

const ConsentForm: React.FC<ConsentFormProps> = ({
  purposes,
  onConsent,
  language
}) => {
  const [consents, setConsents] = useState<Record<string, boolean>>({});
  
  const consentTexts = {
    ar: {
      treatment: 'أوافق على معالجة بياناتي الصحية لغرض العلاج الطبي',
      research: 'أوافق على استخدام بياناتي المجهولة لأغراض البحث العلمي',
      marketing: 'أوافق على تلقي اتصالات تسويقية',
      crossBorder: 'أوافق على نقل بياناتي خارج المملكة العربية السعودية',
    },
    en: {
      treatment: 'I consent to processing my health data for medical treatment',
      research: 'I consent to use of my anonymized data for research purposes',
      marketing: 'I consent to receiving marketing communications',
      crossBorder: 'I consent to transfer of my data outside Saudi Arabia',
    }
  };

  const handleSubmit = () => {
    const grants = Object.entries(consents)
      .filter(([_, granted]) => granted)
      .map(([purpose, _]) => ({
        purpose,
        grantedAt: new Date().toISOString(),
        consentTextVersion: hashConsentText(consentTexts[language][purpose]),
      }));
    
    onConsent(grants);
  };

  return (
    <form onSubmit={handleSubmit} dir={language === 'ar' ? 'rtl' : 'ltr'}>
      <h2>{language === 'ar' ? 'الموافقة على معالجة البيانات' : 'Data Processing Consent'}</h2>
      
      {purposes.map(purpose => (
        <div key={purpose} className="consent-item">
          <input
            type="checkbox"
            id={purpose}
            checked={consents[purpose] || false}
            onChange={(e) => setConsents({
              ...consents,
              [purpose]: e.target.checked
            })}
          />
          <label htmlFor={purpose}>
            {consentTexts[language][purpose]}
          </label>
          
          {/* Required indicator for mandatory consents */}
          {purpose === 'treatment' && (
            <span className="required">
              {language === 'ar' ? 'مطلوب' : 'Required'}
            </span>
          )}
        </div>
      ))}
      
      <div className="privacy-notice">
        <a href="/privacy-policy">
          {language === 'ar' ? 'سياسة الخصوصية' : 'Privacy Policy'}
        </a>
      </div>
      
      <button type="submit">
        {language === 'ar' ? 'تأكيد الموافقة' : 'Confirm Consent'}
      </button>
    </form>
  );
};

Data Localization

PDPL Data Residency Requirements

class DataLocalizationManager:
    """
    Manage PDPL data localization requirements
    
    PDPL requires personal data to be stored within Saudi Arabia,
    with limited exceptions for cross-border transfer.
    """
    
    # Countries with adequate protection (as determined by SDAIA)
    ADEQUATE_COUNTRIES = [
        # To be updated as SDAIA issues adequacy decisions
        # Similar to GDPR adequacy decisions
    ]
    
    # Legal bases for cross-border transfer
    TRANSFER_BASES = [
        "explicit_consent",
        "contract_performance",
        "legal_obligation",
        "vital_interests",
        "public_interest",
        "legal_claims",
    ]
    
    def __init__(self, primary_region: str = "me-south-1"):  # AWS Bahrain
        self.primary_region = primary_region
        
    async def can_transfer(
        self,
        destination_country: str,
        data_category: str,
        legal_basis: str,
        has_consent: bool = False,
    ) -> dict:
        """Check if cross-border transfer is permitted"""
        
        result = {
            "permitted": False,
            "requirements": [],
            "recommendations": [],
        }
        
        # Check adequacy
        if destination_country in self.ADEQUATE_COUNTRIES:
            result["permitted"] = True
            result["requirements"].append("Document adequacy decision reference")
            return result
            
        # Check legal basis
        if legal_basis not in self.TRANSFER_BASES:
            result["requirements"].append(f"Valid legal basis required. Options: {self.TRANSFER_BASES}")
            return result
            
        # Explicit consent for sensitive data
        if data_category == "health_data" and not has_consent:
            result["requirements"].append("Explicit consent required for health data transfer")
            return result
            
        # Standard contractual clauses
        result["requirements"].extend([
            "Execute Standard Contractual Clauses with recipient",
            "Conduct Transfer Impact Assessment",
            "Implement supplementary measures if needed",
        ])
        
        result["permitted"] = True
        return result
    
    async def get_storage_location(self, data_category: str) -> dict:
        """Get appropriate storage location for data category"""
        
        if data_category in ["health_data", "sensitive_data"]:
            return {
                "region": self.primary_region,
                "cloud_provider": "aws",
                "compliance": ["PDPL", "data_localization"],
                "encryption": "required",
            }
        
        return {
            "region": self.primary_region,  # Default to Saudi/GCC region
            "cloud_provider": "aws",
            "compliance": ["PDPL"],
            "encryption": "recommended",
        }


# AWS/GCP region configuration for Saudi compliance
COMPLIANT_REGIONS = {
    "aws": {
        "primary": "me-south-1",  # Bahrain (closest to Saudi)
        "backup": "me-central-1",  # UAE
    },
    "gcp": {
        "primary": "me-central2",  # Dammam, Saudi Arabia
        "backup": "me-central1",  # Doha
    },
    "azure": {
        "primary": "uae-north",  # Dubai
        "backup": "uae-central",
    }
}

Data Subject Rights

Rights Implementation

class DataSubjectRightsManager:
    """
    Implement PDPL data subject rights
    
    Rights include:
    - Right to be informed
    - Right of access
    - Right to rectification
    - Right to erasure
    - Right to restrict processing
    - Right to data portability
    - Right to object
    - Rights related to automated decision-making
    """
    
    def __init__(self, storage, audit_logger, notification_service):
        self.storage = storage
        self.audit_logger = audit_logger
        self.notifications = notification_service
        
    async def handle_access_request(
        self,
        subject_id: str,
        request_details: dict,
    ) -> dict:
        """
        Handle data subject access request
        
        PDPL: Must respond within 30 days
        """
        
        request_id = str(uuid.uuid4())
        
        # Log the request
        await self.audit_logger.log({
            "event_type": "DSR_ACCESS_REQUEST",
            "subject_id": subject_id,
            "request_id": request_id,
        })
        
        # Verify identity before proceeding
        if not await self._verify_identity(subject_id, request_details):
            return {
                "status": "identity_verification_required",
                "request_id": request_id,
            }
        
        # Collect all data about the subject
        data = await self._collect_subject_data(subject_id)
        
        # Generate portable format
        export = {
            "request_id": request_id,
            "subject_id": subject_id,
            "generated_at": datetime.utcnow().isoformat(),
            "data_categories": list(data.keys()),
            "data": data,
        }
        
        # Store for secure download
        download_url = await self._create_secure_download(export)
        
        # Notify subject
        await self.notifications.send(
            subject_id,
            "data_access_ready",
            {"download_url": download_url, "expires_in": "7 days"}
        )
        
        return {
            "status": "completed",
            "request_id": request_id,
            "download_url": download_url,
        }
    
    async def handle_erasure_request(
        self,
        subject_id: str,
        request_details: dict,
    ) -> dict:
        """
        Handle right to erasure (right to be forgotten)
        
        Must balance with record retention requirements
        """
        
        request_id = str(uuid.uuid4())
        
        # Check for legal retention requirements
        retention_holds = await self._check_retention_requirements(subject_id)
        
        if retention_holds:
            return {
                "status": "partially_completed",
                "request_id": request_id,
                "message": "Some data retained due to legal requirements",
                "retained_categories": [h["category"] for h in retention_holds],
                "retention_reasons": [h["reason"] for h in retention_holds],
            }
        
        # Collect all data locations
        data_locations = await self._find_all_data(subject_id)
        
        # Delete from each location
        deletion_results = []
        for location in data_locations:
            result = await self._delete_from_location(location, subject_id)
            deletion_results.append(result)
        
        # Verify deletion
        remaining = await self._verify_deletion(subject_id)
        
        # Log completion
        await self.audit_logger.log({
            "event_type": "DSR_ERASURE_COMPLETED",
            "subject_id": subject_id,
            "request_id": request_id,
            "locations_processed": len(data_locations),
            "remaining_records": len(remaining),
        })
        
        return {
            "status": "completed",
            "request_id": request_id,
            "deleted_from": len(data_locations),
        }
    
    async def handle_portability_request(
        self,
        subject_id: str,
        format: str = "json",
        destination: str = None,
    ) -> dict:
        """
        Handle data portability request
        
        Provide data in machine-readable format
        """
        
        # Collect portable data
        data = await self._collect_subject_data(subject_id)
        
        # Convert to requested format
        if format == "json":
            export_data = json.dumps(data, indent=2, ensure_ascii=False)
        elif format == "csv":
            export_data = self._convert_to_csv(data)
        elif format == "xml":
            export_data = self._convert_to_xml(data)
        else:
            raise ValueError(f"Unsupported format: {format}")
        
        # If destination provided, transfer directly
        if destination:
            await self._transfer_to_destination(destination, export_data)
            return {"status": "transferred", "destination": destination}
        
        # Otherwise, provide download
        download_url = await self._create_secure_download(export_data)
        return {"status": "ready", "download_url": download_url}
    
    async def _check_retention_requirements(
        self,
        subject_id: str
    ) -> List[dict]:
        """Check for legal/regulatory retention requirements"""
        
        holds = []
        
        # HIPAA: Medical records retention
        medical_records = await self.storage.get_medical_records(subject_id)
        if medical_records:
            holds.append({
                "category": "medical_records",
                "reason": "HIPAA 6-year retention requirement",
                "retention_until": self._calculate_retention_date(medical_records),
            })
        
        # Financial records
        financial_records = await self.storage.get_financial_records(subject_id)
        if financial_records:
            holds.append({
                "category": "financial_records",
                "reason": "Tax/accounting retention requirements",
                "retention_until": self._calculate_retention_date(financial_records),
            })
        
        return holds

Breach Notification

PDPL Breach Requirements

class PDPLBreachManager:
    """
    Manage breach notification per PDPL requirements
    
    PDPL requires:
    - Notify SDAIA within 72 hours
    - Notify affected individuals without undue delay
    - Maintain breach register
    """
    
    NOTIFICATION_DEADLINE_HOURS = 72
    
    def __init__(self, authority_api, notification_service, audit_logger):
        self.authority_api = authority_api
        self.notifications = notification_service
        self.audit_logger = audit_logger
        
    async def report_breach(self, breach_details: dict) -> dict:
        """Report a data breach"""
        
        breach_id = str(uuid.uuid4())
        discovery_time = datetime.utcnow()
        deadline = discovery_time + timedelta(hours=self.NOTIFICATION_DEADLINE_HOURS)
        
        breach_record = {
            "breach_id": breach_id,
            "discovered_at": discovery_time.isoformat(),
            "notification_deadline": deadline.isoformat(),
            "status": "investigating",
            **breach_details,
        }
        
        # Store breach record
        await self.storage.save_breach(breach_record)
        
        # Assess severity
        severity = await self._assess_severity(breach_details)
        
        if severity in ["high", "critical"]:
            # Immediate internal escalation
            await self._escalate_internally(breach_record)
        
        return {
            "breach_id": breach_id,
            "deadline": deadline.isoformat(),
            "severity": severity,
            "next_steps": self._get_next_steps(severity),
        }
    
    async def notify_authority(self, breach_id: str) -> dict:
        """
        Notify SDAIA (Saudi Data & AI Authority)
        
        Must be done within 72 hours of discovery
        """
        
        breach = await self.storage.get_breach(breach_id)
        
        notification = {
            "breach_id": breach_id,
            "organization": self.organization_details,
            "discovery_date": breach["discovered_at"],
            "nature_of_breach": breach["description"],
            "data_categories_affected": breach["data_categories"],
            "approximate_subjects_affected": breach["affected_count"],
            "likely_consequences": breach["impact_assessment"],
            "measures_taken": breach["remediation_steps"],
            "contact_details": self.dpo_contact,
        }
        
        # Submit to SDAIA
        response = await self.authority_api.submit_breach_notification(notification)
        
        # Update breach record
        breach["authority_notified_at"] = datetime.utcnow().isoformat()
        breach["authority_reference"] = response["reference_number"]
        await self.storage.save_breach(breach)
        
        return response
    
    async def notify_affected_subjects(self, breach_id: str) -> dict:
        """Notify affected data subjects"""
        
        breach = await self.storage.get_breach(breach_id)
        affected_subjects = await self._get_affected_subjects(breach_id)
        
        notification_content = {
            "ar": {
                "subject": "إشعار بحادث أمني",
                "body": self._generate_notification_ar(breach),
            },
            "en": {
                "subject": "Security Incident Notification",
                "body": self._generate_notification_en(breach),
            }
        }
        
        results = {
            "total": len(affected_subjects),
            "notified": 0,
            "failed": 0,
        }
        
        for subject in affected_subjects:
            try:
                await self.notifications.send_breach_notification(
                    subject["id"],
                    notification_content[subject.get("language", "en")],
                    breach_id,
                )
                results["notified"] += 1
            except Exception as e:
                results["failed"] += 1
                await self.audit_logger.log_notification_failure(
                    breach_id, subject["id"], str(e)
                )
        
        return results
    
    def _generate_notification_ar(self, breach: dict) -> str:
        """Generate Arabic breach notification"""
        return f"""
        عزيزي/عزيزتي،
        
        نود إبلاغكم بوقوع حادث أمني قد يكون أثر على بياناتكم الشخصية.
        
        ماذا حدث:
        {breach['description']}
        
        ما هي البيانات المتأثرة:
        {', '.join(breach['data_categories'])}
        
        ماذا نفعل:
        {breach['remediation_steps']}
        
        ماذا يمكنكم فعله:
        - مراقبة حساباتكم للنشاط المشبوه
        - تغيير كلمات المرور الخاصة بكم
        - الاتصال بنا في حال لاحظتم أي نشاط غير عادي
        
        للتواصل:
        {self.contact_details}
        """
    
    def _generate_notification_en(self, breach: dict) -> str:
        """Generate English breach notification"""
        return f"""
        Dear Valued Customer,
        
        We are writing to inform you of a security incident that may have affected your personal data.
        
        What Happened:
        {breach['description']}
        
        What Data Was Affected:
        {', '.join(breach['data_categories'])}
        
        What We Are Doing:
        {breach['remediation_steps']}
        
        What You Can Do:
        - Monitor your accounts for suspicious activity
        - Change your passwords
        - Contact us if you notice any unusual activity
        
        Contact Information:
        {self.contact_details}
        """

Compliance Mapping

HIPAA to PDPL Control Mapping

COMPLIANCE_MAPPING = {
    "access_control": {
        "hipaa": "§164.312(a) - Access Control",
        "pdpl": "Article 14 - Security of Personal Data",
        "controls": [
            "unique_user_identification",
            "automatic_logoff",
            "encryption",
            "mfa",
        ]
    },
    "audit_controls": {
        "hipaa": "§164.312(b) - Audit Controls",
        "pdpl": "Article 14 - Processing Records",
        "controls": [
            "audit_logging",
            "log_retention",
            "log_review",
        ]
    },
    "integrity": {
        "hipaa": "§164.312(c) - Integrity",
        "pdpl": "Article 8 - Data Accuracy",
        "controls": [
            "data_validation",
            "checksums",
            "version_control",
        ]
    },
    "transmission_security": {
        "hipaa": "§164.312(e) - Transmission Security",
        "pdpl": "Article 14 - Security Measures",
        "controls": [
            "tls_encryption",
            "vpn",
            "secure_protocols",
        ]
    },
    "breach_notification": {
        "hipaa": "§164.404 - Notification to Individuals",
        "pdpl": "Article 20 - Personal Data Breach Notification",
        "controls": [
            "breach_detection",
            "notification_within_72h",
            "breach_documentation",
        ]
    },
}

Key Takeaways

Consent is King

PDPL requires explicit consent for most processing, unlike HIPAA’s TPO exceptions

Data Must Stay Local

Keep personal data in Saudi Arabia/GCC unless you have valid legal basis for transfer

72-Hour Notification

Breach notification to SDAIA must occur within 72 hours of discovery

Rights Implementation

Build systems to handle access, erasure, and portability requests

Practice Exercise

1

Consent Flow

Design a consent collection flow for a healthcare app targeting Saudi users.
2

Data Mapping

Map your data flows and identify where PDPL data localization applies.
3

Rights Portal

Build a data subject rights portal supporting Arabic and English.
4

Breach Playbook

Create a breach response playbook meeting the 72-hour notification requirement.

Next Steps