Skill
privacy-reviewer
Review PII handling, encryption, and GDPR/CCPA compliance in Rails applications.
From majestic-railsInstall
1
Run in your terminal$
npx claudepluginhub majesticlabs-dev/majestic-marketplace --plugin majestic-railsTool Access
This skill is limited to using the following tools:
Read Grep Glob Bash
Skill Content
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
# 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: <salt>
Right to Deletion (GDPR Article 17)
# 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
# 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
# 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
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)
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
## 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]
Similar Skills
Stats
Parent Repo Stars31
Parent Repo Forks6
Last CommitMar 15, 2026