Compliance
EventCore’s immutable audit trail helps with compliance, but you must implement specific controls.
📋 Comprehensive Compliance Checklist
For a detailed compliance checklist covering OWASP, NIST, SOC2, PCI DSS, GDPR, and HIPAA requirements, see our COMPLIANCE_CHECKLIST.md.
This checklist provides actionable items for achieving compliance with major security frameworks and regulations.
GDPR Compliance
Data Protection Principles
- Lawfulness: Store only data with legal basis
- Purpose Limitation: Use data only for stated purposes
- Data Minimization: Store only necessary data
- Accuracy: Provide mechanisms to correct data
- Storage Limitation: Implement retention policies
- Security: Encrypt and protect personal data
Right to Erasure (Right to be Forgotten)
Since events are immutable, use crypto-shredding:
#![allow(unused)] fn main() { use std::collections::HashMap; use uuid::Uuid; struct GdprCompliantEventStore { event_store: Box<dyn EventStore>, key_vault: Box<dyn KeyVault>, user_keys: HashMap<UserId, KeyId>, } impl GdprCompliantEventStore { async fn forget_user(&mut self, user_id: UserId) -> Result<(), Error> { // 1. Delete user's encryption key if let Some(key_id) = self.user_keys.remove(&user_id) { self.key_vault.delete_key(key_id).await?; } // 2. Store erasure event for audit let erasure_event = UserDataErased { user_id: user_id.clone(), erased_at: Timestamp::now(), reason: "GDPR Article 17 Request".to_string(), }; self.event_store .append_events( &StreamId::from_user(&user_id), vec![Event::from(erasure_event)], ) .await?; // 3. Events remain but PII is now unreadable Ok(()) } } }
Data Portability
Export user data in machine-readable format:
#![allow(unused)] fn main() { #[async_trait] trait GdprExport { async fn export_user_data( &self, user_id: UserId, ) -> Result<UserDataExport, Error>; } #[derive(Serialize)] struct UserDataExport { user_id: UserId, export_date: Timestamp, profile: UserProfile, events: Vec<UserEvent>, projections: HashMap<String, Value>, } impl EventStore { async fn export_user_events( &self, user_id: &UserId, ) -> Result<Vec<UserEvent>, Error> { // Collect all events related to user let streams = self.find_user_streams(user_id).await?; let mut events = Vec::new(); for stream_id in streams { let stream_events = self.read_stream(&stream_id).await?; events.extend( stream_events .into_iter() .filter(|e| e.involves_user(user_id)) .map(|e| e.decrypt_for_export()) ); } Ok(events) } } }
PCI DSS Compliance
Never Store in Events
#![allow(unused)] fn main() { // BAD - Never do this #[derive(Serialize, Deserialize)] struct PaymentProcessed { card_number: String, // NEVER! cvv: String, // NEVER! pin: String, // NEVER! } // GOOD - Store only tokens #[derive(Serialize, Deserialize)] struct PaymentProcessed { payment_id: PaymentId, card_token: CardToken, // From PCI-compliant tokenizer last_four: String, // "****1234" amount: Money, merchant_ref: String, } }
Audit Requirements
#![allow(unused)] fn main() { struct PciAuditLogger { logger: Box<dyn AuditLogger>, } impl PciAuditLogger { async fn log_payment_access( &self, user: &User, action: PaymentAction, resource: &str, ) -> Result<(), Error> { let entry = AuditEntry { timestamp: Timestamp::now(), user_id: user.id.clone(), action: action.to_string(), resource: resource.to_string(), ip_address: user.ip_address.clone(), success: true, }; self.logger.log(entry).await } } }
HIPAA Compliance
Protected Health Information (PHI)
Always encrypt PHI:
#![allow(unused)] fn main() { #[derive(Serialize, Deserialize)] struct PatientRecord { patient_id: PatientId, // All PHI must be encrypted encrypted_name: EncryptedField, encrypted_ssn: EncryptedField, encrypted_diagnosis: EncryptedField, encrypted_medications: EncryptedField, // Non-PHI can be unencrypted admission_date: Date, room_number: String, } struct HipaaCompliantStore { encryption: EncryptionService, audit: AuditService, } impl HipaaCompliantStore { async fn store_patient_event( &self, event: PatientEvent, accessed_by: UserId, ) -> Result<(), Error> { // Audit the access self.audit.log_phi_access( &accessed_by, &event.patient_id(), "WRITE", ).await?; // Encrypt and store let encrypted = self.encryption.encrypt_event(event)?; self.event_store.append(encrypted).await?; Ok(()) } } }
Access Controls
#![allow(unused)] fn main() { #[derive(Debug, Clone)] enum HipaaRole { Doctor, Nurse, Admin, Billing, } impl HipaaRole { fn can_access_phi(&self) -> bool { matches!(self, HipaaRole::Doctor | HipaaRole::Nurse) } fn can_access_billing(&self) -> bool { matches!(self, HipaaRole::Admin | HipaaRole::Billing) } } }
SOX Compliance
Financial Controls
#![allow(unused)] fn main() { struct SoxCompliantExecutor { executor: CommandExecutor, approvals: ApprovalService, } impl SoxCompliantExecutor { async fn execute_financial_command( &self, command: FinancialCommand, requester: User, ) -> Result<(), Error> { // Segregation of duties if command.amount() > Money::from_dollars(10_000) { let approver = self.approvals .get_approver(&requester) .await?; self.approvals .request_approval(&command, &approver) .await?; } // Execute with full audit trail let result = self.executor .execute_with_metadata( command, metadata! { "sox_requester" => requester.id, "sox_timestamp" => Timestamp::now(), "sox_ip" => requester.ip_address, }, ) .await?; Ok(result) } } }
General Compliance Features
Audit Trail
#![allow(unused)] fn main() { #[derive(Debug, Serialize)] struct ComplianceAuditEntry { timestamp: Timestamp, event_id: EventId, stream_id: StreamId, user_id: UserId, action: String, regulation: String, // "GDPR", "PCI", "HIPAA" details: HashMap<String, String>, } trait ComplianceAuditor { async fn log_access(&self, entry: ComplianceAuditEntry) -> Result<(), Error>; async fn generate_report( &self, regulation: &str, from: Date, to: Date, ) -> Result<ComplianceReport, Error>; } }
Data Retention
#![allow(unused)] fn main() { struct RetentionPolicy { regulation: String, data_type: String, retention_days: u32, action: RetentionAction, } enum RetentionAction { Delete, Archive, Anonymize, } struct RetentionManager { policies: Vec<RetentionPolicy>, } impl RetentionManager { async fn apply_retention(&self, event_store: &EventStore) -> Result<(), Error> { for policy in &self.policies { let cutoff = Timestamp::now() - Duration::days(policy.retention_days); match policy.action { RetentionAction::Delete => { // For GDPR compliance self.crypto_shred_old_data(cutoff).await?; } RetentionAction::Archive => { // Move to cold storage self.archive_old_events(cutoff).await?; } RetentionAction::Anonymize => { // Remove PII but keep analytics data self.anonymize_old_events(cutoff).await?; } } } Ok(()) } } }
Compliance Checklist
- Implement encryption for all PII/PHI
- Set up audit logging for all access
- Configure data retention policies
- Implement right to erasure (GDPR)
- Set up data export capabilities
- Configure access controls (RBAC/ABAC)
- Implement approval workflows (SOX)
- Set up monitoring and alerting
- Document all compliance measures
- Regular compliance audits