Skip to main content
โšก Calmops

Patient Data Privacy: GDPR, HIPAA, CCPA Compliance

Introduction

Healthcare data privacy regulations are complex and overlapping. Navigating GDPR, HIPAA, and CCPA requires understanding each framework’s requirements and how they interact.

Key Statistics:

  • 73% of healthcare organizations struggle with multi-regulation compliance
  • Average data breach cost in healthcare: $10.1 million
  • 87% of consumers care about data privacy
  • Non-compliance fines can reach โ‚ฌ20 million or 4% of revenue

Regulatory Comparison

Aspect HIPAA GDPR CCPA
Scope US Healthcare EU Residents California Residents
PHI Definition 18 identifiers Personal data Personal info
Consent Authorization Opt-in consent Opt-out
Breach Notification 60 days 72 hours “Expeditious”
Individual Rights Access, Amendment 8 rights 4 rights
Penalty $1.5M/violation โ‚ฌ20M or 4% revenue $7,500/intent

HIPAA Authorization

#!/usr/bin/env python3
"""HIPAA authorization management."""

from datetime import datetime, timedelta
from enum import Enum

class AuthorizationType(Enum):
    TREATMENT = "treatment"
    PAYMENT = "payment"
    HEALTHCARE_OPERATIONS = "healthcare_operations"
    RESEARCH = "research"
    MARKETING = "marketing"

class HIPAAAuthorization:
    """Manage HIPAA authorizations."""
    
    def __init__(self, patient_id: str):
        self.patient_id = patient_id
        self.authorizations = []
    
    def create_authorizations(self, auth_type: AuthorizationType, 
                           purpose: str, 
                           expiration: datetime,
                           recipient: str = None):
        """Create new authorization."""
        
        auth = {
            'authorization_id': generate_uuid(),
            'patient_id': self.patient_id,
            'type': auth_type.value,
            'purpose': purpose,
            'recipient': recipient,
            'effective_date': datetime.now(),
            'expiration_date': expiration,
            'status': 'active',
            'revoked': False,
            'created_at': datetime.now()
        }
        
        self.authorizations.append(auth)
        return auth
    
    def revoke_authorization(self, authorization_id: str):
        """Revoke authorization."""
        
        for auth in self.authorizations:
            if auth['authorization_id'] == authorization_id:
                auth['revoked'] = True
                auth['revoked_at'] = datetime.now()
                return True
        
        return False
    
    def check_authorization(self, auth_type: AuthorizationType, 
                          recipient: str = None) -> bool:
        """Check if valid authorization exists."""
        
        for auth in self.authorizations:
            if (auth['type'] == auth_type.value and 
                not auth['revoked'] and 
                auth['expiration_date'] > datetime.now()):
                
                if recipient is None or auth['recipient'] == recipient:
                    return True
        
        return False
    
    def get_valid_authorizations(self):
        """Get all valid authorizations."""
        
        return [
            auth for auth in self.authorizations
            if (not auth['revoked'] and 
                auth['expiration_date'] > datetime.now())
        ]
#!/usr/bin/env python3
"""GDPR consent management."""

class GDPRConsent:
    """Manage GDPR consent."""
    
    def __init__(self, data_subject_id: str):
        self.data_subject_id = data_subject_id
        self.consents = {}
    
    def record_consent(self, purpose: str, granted: bool, 
                      legal_basis: str = 'consent'):
        """Record consent for processing purpose."""
        
        consent = {
            'consent_id': generate_uuid(),
            'data_subject_id': self.data_subject_id,
            'purpose': purpose,
            'granted': granted,
            'legal_basis': legal_basis,
            'timestamp': datetime.now(),
            'ip_address': get_client_ip(),
            'user_agent': get_user_agent(),
            'version': get_consent_version()
        }
        
        self.consents[purpose] = consent
        return consent
    
    def withdraw_consent(self, purpose: str):
        """Withdraw consent."""
        
        if purpose in self.consents:
            self.consents[purpose]['withdrawn'] = True
            self.consents[purpose]['withdrawn_at'] = datetime.now()
    
    def has_valid_consent(self, purpose: str) -> bool:
        """Check if valid consent exists."""
        
        consent = self.consents.get(purpose)
        
        if not consent:
            return False
        
        return (consent.get('granted') and 
                not consent.get('withdrawn', False))

Data Subject Rights

Implementation

#!/usr/bin/env python3
"""Data subject rights implementation."""

from datetime import datetime
import json

class DataSubjectRights:
    """Implement data subject rights."""
    
    def __init__(self, data_store):
        self.data_store = data_store
    
    def handle_access_request(self, data_subject_id: str) -> dict:
        """Handle right to access (GDPR Art 15 / HIPAA)."""
        
        data = self.data_store.get_all_for_subject(data_subject_id)
        
        return {
            'request_id': generate_uuid(),
            'data_subject_id': data_subject_id,
            'request_type': 'access',
            'data_categories': list(data.keys()),
            'data': self._redact_sensitive(data),
            'generated_at': datetime.now()
        }
    
    def handle_rectification_request(self, data_subject_id: str, 
                                   corrections: dict) -> dict:
        """Handle right to rectification (GDPR Art 16)."""
        
        for field, new_value in corrections.items():
            self.data_store.update(data_subject_id, field, new_value)
        
        return {
            'request_id': generate_uuid(),
            'request_type': 'rectification',
            'applied_corrections': corrections,
            'completed_at': datetime.now()
        }
    
    def handle_erasure_request(self, data_subject_id: str, 
                             grounds: str) -> dict:
        """Handle right to erasure (GDPR Art 17)."""
        
        # Check if exceptions apply
        if self._has_legal_obligation(data_subject_id):
            return {
                'request_id': generate_uuid(),
                'request_type': 'erasure',
                'status': 'denied',
                'reason': 'Legal retention obligation applies',
                'completed_at': datetime.now()
            }
        
        # Execute erasure
        self.data_store.delete_all_for_subject(data_subject_id)
        
        return {
            'request_id': generate_uuid(),
            'request_type': 'erasure',
            'status': 'completed',
            'completed_at': datetime.now()
        }
    
    def handle_portability_request(self, data_subject_id: str) -> dict:
        """Handle right to data portability (GDPR Art 20)."""
        
        data = self.data_store.get_all_for_subject(data_subject_id)
        
        return {
            'request_id': generate_uuid(),
            'request_type': 'portability',
            'format': 'json',
            'data': json.dumps(data),
            'generated_at': datetime.now()
        }
    
    def handle_restriction_request(self, data_subject_id: str, 
                                  processing_types: list) -> dict:
        """Handle right to restriction."""
        
        for processing_type in processing_types:
            self.data_store.restrict_processing(
                data_subject_id, 
                processing_type
            )
        
        return {
            'request_id': generate_uuid(),
            'request_type': 'restriction',
            'restricted_processing': processing_types,
            'completed_at': datetime.now()
        }
    
    def _redact_sensitive(self, data: dict) -> dict:
        """Redact sensitive information."""
        
        sensitive_fields = ['ssn', 'password', 'credit_card']
        
        redacted = data.copy()
        for field in sensitive_fields:
            if field in redacted:
                redacted[field] = '***REDACTED***'
        
        return redacted
    
    def _has_legal_obligation(self, data_subject_id: str) -> bool:
        """Check if data has legal retention obligation."""
        
        return self.data_store.has_legal_hold(data_subject_id)

Breach Notification

#!/usr/bin/env python3
"""Healthcare breach notification handling."""

from datetime import datetime, timedelta

class BreachNotificationHandler:
    """Handle breach notifications."""
    
    # Thresholds
    HIPAA_NOTIFICATION_DEADLINE = 60  # days
    GDPR_NOTIFICATION_DEADLINE = 72   # hours
    
    def assess_breach(self, breach_data: dict) -> dict:
        """Assess breach and required notifications."""
        
        affected_subjects = breach_data.get('affected_subjects', [])
        phi_involved = breach_data.get('phi_involved', False)
        encryption_applied = breach_data.get('encryption_applied', False)
        
        risk_score = self._calculate_risk(
            len(affected_subjects),
            phi_involved,
            encryption_applied
        )
        
        notifications = []
        
        # HIPAA notification (if PHI involved)
        if phi_involved and risk_score > 0.5:
            notifications.append({
                'type': 'hipaa',
                'required': True,
                'deadline': datetime.now() + timedelta(days=self.HIPAA_NOTIFICATION_DEADLINE),
                'authorities': ['HHS', 'OCR'],
                'individuals': affected_subjects
            })
        
        # GDPR notification (if EU subjects affected)
        if breach_data.get('eu_subjects_present'):
            notifications.append({
                'type': 'gdpr',
                'required': True,
                'deadline': datetime.now() + timedelta(hours=self.GDPR_NOTIFICATION_DEADLINE),
                'authorities': ['Lead DPA'],
                'risk_level': 'high' if risk_score > 0.5 else 'low'
            })
        
        return {
            'breach_id': generate_uuid(),
            'risk_score': risk_score,
            'notifications': notifications,
            'recommended_actions': self._get_recommended_actions(risk_score)
        }
    
    def _calculate_risk(self, affected_count: int, 
                       phi_involved: bool, 
                       encrypted: bool) -> float:
        """Calculate breach risk score."""
        
        base_score = 0.0
        
        if affected_count > 500:
            base_score += 0.3
        elif affected_count > 100:
            base_score += 0.2
        else:
            base_score += 0.1
        
        if phi_involved:
            base_score += 0.4
        
        if not encrypted:
            base_score += 0.3
        
        return min(1.0, base_score)
    
    def _get_recommended_actions(self, risk_score: float) -> list:
        """Get recommended actions based on risk."""
        
        actions = ['Contain breach', 'Preserve evidence']
        
        if risk_score > 0.7:
            actions.extend([
                'Engage legal counsel',
                'Notify cyber insurance',
                'Prepare public communication'
            ])
        elif risk_score > 0.4:
            actions.append('Notify affected individuals')
        
        return actions

External Resources


Comments