--- name: privacy-reviewer description: Review PII handling, encryption, and GDPR/CCPA compliance in Rails applications. allowed-tools: Read Grep Glob Bash --- # Privacy Compliance Review Review PII identification, encryption, data deletion, and regulatory compliance. ## PII Identification Checklist | Category | Examples | Treatment | |----------|----------|-----------| | Direct identifiers | Name, email, phone, SSN | Encrypt at rest | | Indirect identifiers | IP address, device ID | Hash or encrypt | | Location data | GPS, address, zip code | Encrypt, retention limits | | Financial | Card numbers, bank accounts | PCI compliance required | | Health | Medical records, conditions | HIPAA compliance required | | Behavioral | Browsing history, preferences | Consent required | ## Encryption for Sensitive Fields ```ruby # Rails 7+ built-in encryption class User < ApplicationRecord encrypts :ssn encrypts :date_of_birth encrypts :medical_notes, deterministic: false # Non-searchable end # Configuration in credentials # active_record_encryption: # primary_key: <32-byte key> # deterministic_key: <32-byte key> # key_derivation_salt: ``` ## Right to Deletion (GDPR Article 17) ```ruby # PROBLEM: Hard delete loses audit trail user.destroy # SOLUTION: Anonymization with audit preservation def anonymize! transaction do update!( email: "deleted_#{id}@anonymized.local", name: "Deleted User", phone: nil, address: nil, deleted_at: Time.current ) # Keep orders for accounting, anonymize PII orders.update_all( customer_name: "Anonymized", shipping_address: nil ) end end ``` ## Data Retention ```ruby # Automated cleanup job class PiiRetentionJob < ApplicationJob def perform # Delete inactive users after retention period User.where("last_activity_at < ?", 3.years.ago) .find_each(&:anonymize!) # Purge old logs AuditLog.where("created_at < ?", 7.years.ago).delete_all end end ``` ## Audit Trails ```ruby # Track PII access class PiiAccessLog < ApplicationRecord belongs_to :user # Whose data was accessed belongs_to :accessed_by, class_name: 'User' # Log: what, when, why, who # user_id, accessed_by_id, field_accessed, purpose, created_at end # In model def ssn PiiAccessLog.create!(user: self, accessed_by: Current.user, field_accessed: 'ssn') super end ``` ## Consent Management ```ruby class UserConsent < ApplicationRecord belongs_to :user # Track: what consented, when, version, withdrawal # consent_type, granted_at, policy_version, withdrawn_at end # Check before processing def can_send_marketing?(user) user.consents.active.exists?(consent_type: 'marketing') end ``` ## Data Export (GDPR Article 20) ```ruby def export_personal_data { profile: attributes.slice('name', 'email', 'phone'), orders: orders.map(&:export_data), activity: activity_logs.map(&:export_data), exported_at: Time.current.iso8601 }.to_json end ``` ## Review Checklist - [ ] All PII fields identified and documented? - [ ] Sensitive fields encrypted at rest? - [ ] Anonymization method exists for deletion requests? - [ ] Data retention policies implemented? - [ ] PII access logged for audit? - [ ] Consent tracked before data processing? - [ ] Data export available for portability requests? ## Output Format ```markdown ## Privacy Review: [PASS/WARN/FAIL] ### Unencrypted PII - [model.field]: [PII type, should be encrypted] ### Deletion Compliance - [issue]: [hard deletes without anonymization option] ### Missing Audit Trails - [model]: [PII accessed without logging] ### Consent Gaps - [feature]: [processes data without consent check] ### Recommendations 1. [Prioritized fixes] ```