GDPR and Password Protection

GDPR and Password Protection

The General Data Protection Regulation (GDPR) fundamentally changed how organizations approach password storage, treating authentication credentials as personal data requiring special protection. Article 32 mandates "appropriate technical and organisational measures" including "the pseudonymisation and encryption of personal data." While GDPR doesn't specify exact password hashing algorithms, it requires security measures appropriate to the risk level.

GDPR's emphasis on data protection by design and default directly impacts password systems. Organizations must implement state-of-the-art security from the beginning, not as an afterthought. This means using modern password hashing algorithms, implementing proper access controls, and maintaining comprehensive audit trails. The regulation's breach notification requirements—72 hours to authorities and without undue delay to affected individuals—make proper password protection critical for avoiding regulatory penalties.

from datetime import datetime, timedelta
import json
import hashlib
from typing import Dict, List, Optional
from argon2 import PasswordHasher
import logging

class GDPRCompliantPasswordSystem:
    """Password system implementing GDPR requirements"""
    
    def __init__(self):
        self.ph = PasswordHasher(
            time_cost=3,
            memory_cost=65536,
            parallelism=4
        )
        self.audit_logger = self._setup_audit_logging()
        
    def _setup_audit_logging(self):
        """Configure GDPR-compliant audit logging"""
        
        logger = logging.getLogger('gdpr_password_audit')
        handler = logging.FileHandler('gdpr_password_audit.log')
        
        # GDPR requires demonstrable compliance
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S UTC'
        )
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        logger.setLevel(logging.INFO)
        
        return logger
    
    def process_password(self, password: str, user_id: str, 
                        purpose: str = 'authentication') -> Dict:
        """Process password with GDPR compliance tracking"""
        
        # GDPR Article 5(1)(a) - Lawfulness, fairness and transparency
        processing_record = {
            'timestamp': datetime.utcnow().isoformat(),
            'user_id': user_id,
            'purpose': purpose,
            'lawful_basis': 'contract',  # User agreement
            'data_minimization': True,   # Only store hash
        }
        
        # Hash password using state-of-the-art method
        # GDPR Article 32(1)(a) - Pseudonymisation and encryption
        password_hash = self.ph.hash(password)
        
        # Log processing activity (without sensitive data)
        # GDPR Article 30 - Records of processing activities
        self.audit_logger.info(json.dumps({
            'activity': 'password_hashing',
            'user_id': self._pseudonymize_user_id(user_id),
            'purpose': purpose,
            'algorithm': 'argon2id',
            'compliance': {
                'gdpr_article_32': True,
                'data_minimization': True,
                'purpose_limitation': True
            }
        }))
        
        return {
            'hash': password_hash,
            'processing_record': processing_record,
            'retention_period': '6_years',  # Based on legal requirements
            'deletion_date': (datetime.utcnow() + timedelta(days=2190)).isoformat()
        }
    
    def _pseudonymize_user_id(self, user_id: str) -> str:
        """Pseudonymize user ID for audit logs"""
        
        # GDPR encourages pseudonymization
        return hashlib.sha256(f"{user_id}:audit".encode()).hexdigest()[:16]
    
    def handle_data_subject_request(self, user_id: str, request_type: str) -> Dict:
        """Handle GDPR data subject rights requests"""
        
        # GDPR Articles 15-22 - Data subject rights
        handlers = {
            'access': self._handle_access_request,      # Article 15
            'rectification': self._handle_rectification, # Article 16
            'erasure': self._handle_erasure,           # Article 17
            'portability': self._handle_portability,    # Article 20
        }
        
        if request_type not in handlers:
            return {'error': 'Invalid request type'}
            
        # Log the request
        self.audit_logger.info(json.dumps({
            'activity': 'data_subject_request',
            'request_type': request_type,
            'user_id': self._pseudonymize_user_id(user_id),
            'timestamp': datetime.utcnow().isoformat()
        }))
        
        # Process request within 30 days (GDPR requirement)
        return handlers[request_type](user_id)
    
    def _handle_access_request(self, user_id: str) -> Dict:
        """Handle right of access request"""
        
        # Provide information about password data processing
        return {
            'user_id': user_id,
            'data_collected': 'password_hash',
            'purposes': ['authentication', 'account_security'],
            'legal_basis': 'contract',
            'recipients': ['authentication_service'],
            'retention_period': '6_years',
            'security_measures': [
                'Argon2id hashing',
                'Access controls',
                'Encryption at rest',
                'Audit logging'
            ]
        }
    
    def demonstrate_compliance(self) -> Dict:
        """Generate GDPR compliance demonstration"""
        
        return {
            'technical_measures': {
                'pseudonymisation': 'User IDs hashed in logs',
                'encryption': 'Argon2id password hashing',
                'integrity': 'Hash verification prevents tampering',
                'availability': 'Backup and recovery procedures',
                'resilience': 'Rate limiting and DDoS protection'
            },
            'organizational_measures': {
                'access_control': 'Role-based access to password data',
                'training': 'Security awareness for staff',
                'assessment': 'Regular security assessments',
                'review': 'Annual review of measures'
            },
            'accountability': {
                'documentation': 'Comprehensive security documentation',
                'audit_trails': 'All password operations logged',
                'breach_procedures': '72-hour notification process',
                'privacy_by_design': 'Security built into system'
            }
        }

Data minimization principles particularly impact password systems. GDPR requires collecting only necessary data for specified purposes. For passwords, this means storing only the hash—never the plaintext password, password hints, or security questions that could reveal the password. Organizations must also implement appropriate retention periods and automated deletion processes.