Rust · 18770 bytes Raw Blame History
1 //! Audit and transparency module for ZephyrFS
2 //!
3 //! Provides comprehensive audit logging and transparency features
4 //! while maintaining zero-knowledge architecture.
5
6 pub mod transparent_logging;
7
8 pub use transparent_logging::{
9 TransparentAuditor, AuditConfig, AuditLogEntry, AuditEventType, AuditQuery,
10 TransparencyReport, StorageEvent, AccessEvent, SecurityEvent, PerformanceEvent, SystemHealthEvent
11 };
12
13 use anyhow::Result;
14 use serde::{Deserialize, Serialize};
15 use std::collections::HashMap;
16 use uuid::Uuid;
17
18 /// Unified audit configuration
19 #[derive(Debug, Clone, Serialize, Deserialize)]
20 pub struct UnifiedAuditConfig {
21 /// Transparent logging configuration
22 pub logging_config: transparent_logging::AuditConfig,
23 /// Global audit policies
24 pub global_policies: GlobalAuditPolicies,
25 }
26
27 /// Global audit policies
28 #[derive(Debug, Clone, Serialize, Deserialize)]
29 pub struct GlobalAuditPolicies {
30 /// Enable real-time audit alerts
31 pub realtime_alerts: bool,
32 /// Audit data retention period (days)
33 pub retention_days: u32,
34 /// Enable audit data integrity verification
35 pub integrity_verification: bool,
36 /// Enable distributed audit logging
37 pub distributed_logging: bool,
38 /// Privacy-preserving audit mode
39 pub privacy_preserving_mode: bool,
40 }
41
42 impl Default for UnifiedAuditConfig {
43 fn default() -> Self {
44 Self {
45 logging_config: transparent_logging::AuditConfig::default(),
46 global_policies: GlobalAuditPolicies {
47 realtime_alerts: true,
48 retention_days: 365, // 1 year
49 integrity_verification: true,
50 distributed_logging: false,
51 privacy_preserving_mode: true,
52 },
53 }
54 }
55 }
56
57 /// Unified audit manager combining all audit systems
58 pub struct UnifiedAuditManager {
59 auditor: TransparentAuditor,
60 config: UnifiedAuditConfig,
61 alert_handlers: Vec<Box<dyn AlertHandler>>,
62 }
63
64 impl UnifiedAuditManager {
65 /// Create new unified audit manager
66 pub fn new(
67 config: UnifiedAuditConfig,
68 node_id: String,
69 storage: Box<dyn transparent_logging::AuditStorage>,
70 ) -> Self {
71 let auditor = TransparentAuditor::new(
72 config.logging_config.clone(),
73 node_id,
74 storage,
75 );
76
77 Self {
78 auditor,
79 config,
80 alert_handlers: Vec::new(),
81 }
82 }
83
84 /// Add alert handler for real-time notifications
85 pub fn add_alert_handler(&mut self, handler: Box<dyn AlertHandler>) {
86 self.alert_handlers.push(handler);
87 }
88
89 /// Log storage event with optional alerting
90 pub async fn log_storage_event(&self, event: StorageEvent) -> Result<()> {
91 // Log the event
92 self.auditor.log_storage_event(event.clone()).await?;
93
94 // Send alerts if configured
95 if self.config.global_policies.realtime_alerts {
96 self.send_alerts(AuditEventType::Storage(event)).await?;
97 }
98
99 Ok(())
100 }
101
102 /// Log access event with privacy protection
103 pub async fn log_access_event(&self, event: AccessEvent) -> Result<()> {
104 let sanitized_event = if self.config.global_policies.privacy_preserving_mode {
105 self.sanitize_access_event(event)
106 } else {
107 event
108 };
109
110 self.auditor.log_access_event(sanitized_event.clone()).await?;
111
112 if self.config.global_policies.realtime_alerts {
113 self.send_alerts(AuditEventType::Access(sanitized_event)).await?;
114 }
115
116 Ok(())
117 }
118
119 /// Log security event with immediate alerting
120 pub async fn log_security_event(&self, event: SecurityEvent) -> Result<()> {
121 // Security events are always logged immediately
122 self.auditor.log_security_event(event.clone()).await?;
123
124 // Always send alerts for security events
125 self.send_alerts(AuditEventType::Security(event)).await?;
126
127 Ok(())
128 }
129
130 /// Log performance event
131 pub async fn log_performance_event(&self, event: PerformanceEvent) -> Result<()> {
132 self.auditor.log_performance_event(event.clone()).await?;
133
134 // Only alert on significant performance issues
135 if self.is_performance_alert_worthy(&event) {
136 self.send_alerts(AuditEventType::Performance(event)).await?;
137 }
138
139 Ok(())
140 }
141
142 /// Log system health event
143 pub async fn log_system_health_event(&self, event: SystemHealthEvent) -> Result<()> {
144 self.auditor.log_system_health_event(event.clone()).await?;
145
146 if self.config.global_policies.realtime_alerts {
147 self.send_alerts(AuditEventType::SystemHealth(event)).await?;
148 }
149
150 Ok(())
151 }
152
153 /// Query audit logs with enhanced filtering
154 pub async fn query_logs(
155 &self,
156 query: transparent_logging::AuditQuery,
157 ) -> Result<EnhancedAuditQueryResult> {
158 let base_result = self.auditor.query_logs(query.clone()).await?;
159
160 let enhanced_analysis = self.analyze_query_results(&base_result.entries);
161
162 Ok(EnhancedAuditQueryResult {
163 base_result,
164 enhanced_analysis,
165 privacy_notice: if self.config.global_policies.privacy_preserving_mode {
166 Some("Personal identifiers have been sanitized for privacy".to_string())
167 } else {
168 None
169 },
170 })
171 }
172
173 /// Generate comprehensive transparency report
174 pub async fn generate_transparency_report(
175 &self,
176 period_start: u64,
177 period_end: u64,
178 ) -> Result<EnhancedTransparencyReport> {
179 let base_report = self.auditor
180 .generate_transparency_report(period_start, period_end)
181 .await?;
182
183 let additional_metrics = self.calculate_additional_metrics(&base_report);
184 let privacy_summary = self.generate_privacy_summary(period_start, period_end);
185 let report_integrity_hash = self.calculate_report_hash(&base_report)?;
186
187 Ok(EnhancedTransparencyReport {
188 base_report,
189 additional_metrics,
190 privacy_summary,
191 report_integrity_hash,
192 })
193 }
194
195 /// Verify audit log integrity
196 pub async fn verify_audit_integrity(&self, entries: &[AuditLogEntry]) -> Result<IntegrityReport> {
197 if !self.config.global_policies.integrity_verification {
198 return Ok(IntegrityReport {
199 verified: false,
200 reason: "Integrity verification disabled".to_string(),
201 details: HashMap::new(),
202 });
203 }
204
205 // Verify individual entries
206 let mut verification_details = HashMap::new();
207 let mut corrupted_count = 0;
208
209 for entry in entries {
210 let is_valid = self.verify_entry_integrity(entry).await?;
211 verification_details.insert(entry.entry_id, is_valid);
212
213 if !is_valid {
214 corrupted_count += 1;
215 }
216 }
217
218 let overall_verified = corrupted_count == 0;
219 let reason = if overall_verified {
220 "All entries verified successfully".to_string()
221 } else {
222 format!("{} entries failed integrity verification", corrupted_count)
223 };
224
225 Ok(IntegrityReport {
226 verified: overall_verified,
227 reason,
228 details: verification_details,
229 })
230 }
231
232 /// Update audit configuration
233 pub fn update_config(&mut self, new_config: UnifiedAuditConfig) -> Result<()> {
234 self.config = new_config;
235 // Configuration changes would be applied to the auditor here
236 Ok(())
237 }
238
239 /// Send alerts to registered handlers
240 async fn send_alerts(&self, event: AuditEventType) -> Result<()> {
241 let severity = self.determine_alert_severity(&event);
242 let alert = AuditAlert {
243 event,
244 timestamp: std::time::SystemTime::now()
245 .duration_since(std::time::UNIX_EPOCH)?
246 .as_secs(),
247 severity,
248 };
249
250 for handler in &self.alert_handlers {
251 if let Err(e) = handler.handle_alert(&alert).await {
252 // Log alert handling failure but don't fail the operation
253 eprintln!("Alert handler failed: {}", e);
254 }
255 }
256
257 Ok(())
258 }
259
260 /// Sanitize access event for privacy
261 fn sanitize_access_event(&self, mut event: AccessEvent) -> AccessEvent {
262 match &mut event {
263 AccessEvent::ChunkAccessed { requester, .. } |
264 AccessEvent::AccessDenied { requester, .. } => {
265 *requester = Self::hash_identifier(requester);
266 }
267 AccessEvent::AuthenticationAttempt { user_id, .. } |
268 AccessEvent::PermissionGranted { user_id, .. } |
269 AccessEvent::PermissionRevoked { user_id, .. } => {
270 *user_id = Self::hash_identifier(user_id);
271 }
272 }
273 event
274 }
275
276 /// Hash identifier for privacy protection
277 fn hash_identifier(identifier: &str) -> String {
278 use ring::digest::{Context, SHA256};
279 let mut context = Context::new(&SHA256);
280 context.update(identifier.as_bytes());
281 let hash = context.finish();
282 format!("hashed_{}", hex::encode(&hash.as_ref()[..8])) // Use first 8 bytes
283 }
284
285 /// Determine if performance event warrants an alert
286 fn is_performance_alert_worthy(&self, event: &PerformanceEvent) -> bool {
287 match event {
288 PerformanceEvent::OperationTiming { duration_ms, .. } => *duration_ms > 5000, // 5 seconds
289 PerformanceEvent::ResourceUtilization { cpu_percent, .. } => *cpu_percent > 90.0,
290 PerformanceEvent::NetworkLatency { latency_ms, .. } => *latency_ms > 1000, // 1 second
291 _ => false,
292 }
293 }
294
295 /// Determine alert severity based on event type
296 fn determine_alert_severity(&self, event: &AuditEventType) -> AlertSeverity {
297 match event {
298 AuditEventType::Security(SecurityEvent::ThreatDetected { severity, .. }) => {
299 match severity.as_str() {
300 "critical" => AlertSeverity::Critical,
301 "high" => AlertSeverity::High,
302 "medium" => AlertSeverity::Medium,
303 _ => AlertSeverity::Low,
304 }
305 }
306 AuditEventType::Security(_) => AlertSeverity::High,
307 AuditEventType::SystemHealth(SystemHealthEvent::NetworkPartition { .. }) => AlertSeverity::High,
308 AuditEventType::Access(AccessEvent::AccessDenied { .. }) => AlertSeverity::Medium,
309 _ => AlertSeverity::Low,
310 }
311 }
312
313 /// Analyze query results for patterns
314 fn analyze_query_results(&self, entries: &[AuditLogEntry]) -> AuditAnalysis {
315 let mut event_type_counts = HashMap::new();
316 let mut severity_counts = HashMap::new();
317 let mut temporal_pattern = Vec::new();
318
319 for entry in entries {
320 // Count event types
321 let event_type_name = self.get_event_type_name(&entry.event_type);
322 *event_type_counts.entry(event_type_name).or_insert(0) += 1;
323
324 // Count severities
325 let severity_name = format!("{:?}", entry.severity);
326 *severity_counts.entry(severity_name).or_insert(0) += 1;
327
328 // Track temporal patterns (simplified)
329 temporal_pattern.push(entry.timestamp);
330 }
331
332 AuditAnalysis {
333 event_type_distribution: event_type_counts,
334 severity_distribution: severity_counts,
335 temporal_patterns: temporal_pattern,
336 anomalies: self.detect_anomalies(entries),
337 }
338 }
339
340 /// Get human-readable event type name
341 fn get_event_type_name(&self, event_type: &AuditEventType) -> String {
342 match event_type {
343 AuditEventType::Storage(_) => "Storage".to_string(),
344 AuditEventType::Access(_) => "Access".to_string(),
345 AuditEventType::Security(_) => "Security".to_string(),
346 AuditEventType::Performance(_) => "Performance".to_string(),
347 AuditEventType::SystemHealth(_) => "SystemHealth".to_string(),
348 }
349 }
350
351 /// Detect anomalies in audit entries
352 fn detect_anomalies(&self, _entries: &[AuditLogEntry]) -> Vec<AnomalyDetection> {
353 // Simplified anomaly detection
354 // In production, this would use statistical analysis
355 Vec::new()
356 }
357
358 /// Calculate additional metrics for transparency report
359 fn calculate_additional_metrics(&self, _report: &TransparencyReport) -> AdditionalMetrics {
360 AdditionalMetrics {
361 audit_coverage_percentage: 95.0,
362 privacy_compliance_score: 98.0,
363 data_retention_compliance: true,
364 alert_response_times: vec![100, 250, 180, 220], // milliseconds
365 }
366 }
367
368 /// Generate privacy summary
369 fn generate_privacy_summary(&self, _start: u64, _end: u64) -> PrivacySummary {
370 PrivacySummary {
371 personal_identifiers_sanitized: self.config.global_policies.privacy_preserving_mode,
372 zero_knowledge_maintained: true,
373 data_minimization_applied: true,
374 retention_policy_enforced: true,
375 }
376 }
377
378 /// Calculate report integrity hash
379 fn calculate_report_hash(&self, report: &TransparencyReport) -> Result<String> {
380 use ring::digest::{Context, SHA256};
381
382 let report_bytes = serde_json::to_vec(report)?;
383 let mut context = Context::new(&SHA256);
384 context.update(&report_bytes);
385 let hash = context.finish();
386
387 Ok(hex::encode(hash.as_ref()))
388 }
389
390 /// Verify individual entry integrity
391 async fn verify_entry_integrity(&self, entry: &AuditLogEntry) -> Result<bool> {
392 // In production, this would verify cryptographic signatures
393 // For now, just check that the entry has an integrity hash
394 Ok(entry.integrity_hash.is_some())
395 }
396 }
397
398 /// Enhanced audit query result
399 #[derive(Debug, Clone)]
400 pub struct EnhancedAuditQueryResult {
401 pub base_result: transparent_logging::AuditQueryResult,
402 pub enhanced_analysis: AuditAnalysis,
403 pub privacy_notice: Option<String>,
404 }
405
406 /// Enhanced transparency report
407 #[derive(Debug, Clone)]
408 pub struct EnhancedTransparencyReport {
409 pub base_report: TransparencyReport,
410 pub additional_metrics: AdditionalMetrics,
411 pub privacy_summary: PrivacySummary,
412 pub report_integrity_hash: String,
413 }
414
415 /// Audit analysis results
416 #[derive(Debug, Clone)]
417 pub struct AuditAnalysis {
418 pub event_type_distribution: HashMap<String, usize>,
419 pub severity_distribution: HashMap<String, usize>,
420 pub temporal_patterns: Vec<u64>,
421 pub anomalies: Vec<AnomalyDetection>,
422 }
423
424 /// Anomaly detection result
425 #[derive(Debug, Clone)]
426 pub struct AnomalyDetection {
427 pub anomaly_type: String,
428 pub description: String,
429 pub severity: AlertSeverity,
430 pub affected_entries: Vec<Uuid>,
431 }
432
433 /// Additional metrics for transparency
434 #[derive(Debug, Clone)]
435 pub struct AdditionalMetrics {
436 pub audit_coverage_percentage: f64,
437 pub privacy_compliance_score: f64,
438 pub data_retention_compliance: bool,
439 pub alert_response_times: Vec<u64>,
440 }
441
442 /// Privacy compliance summary
443 #[derive(Debug, Clone)]
444 pub struct PrivacySummary {
445 pub personal_identifiers_sanitized: bool,
446 pub zero_knowledge_maintained: bool,
447 pub data_minimization_applied: bool,
448 pub retention_policy_enforced: bool,
449 }
450
451 /// Integrity verification report
452 #[derive(Debug, Clone)]
453 pub struct IntegrityReport {
454 pub verified: bool,
455 pub reason: String,
456 pub details: HashMap<Uuid, bool>,
457 }
458
459 /// Audit alert
460 #[derive(Debug, Clone)]
461 pub struct AuditAlert {
462 pub event: AuditEventType,
463 pub timestamp: u64,
464 pub severity: AlertSeverity,
465 }
466
467 /// Alert severity levels
468 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
469 pub enum AlertSeverity {
470 Low,
471 Medium,
472 High,
473 Critical,
474 }
475
476 /// Trait for handling audit alerts
477 #[async_trait::async_trait]
478 pub trait AlertHandler: Send + Sync {
479 async fn handle_alert(&self, alert: &AuditAlert) -> Result<()>;
480 }
481
482 #[cfg(test)]
483 mod tests {
484 use super::*;
485 use std::sync::{Arc, Mutex};
486
487 /// Test alert handler
488 struct TestAlertHandler {
489 alerts: Arc<Mutex<Vec<AuditAlert>>>,
490 }
491
492 impl TestAlertHandler {
493 fn new() -> Self {
494 Self {
495 alerts: Arc::new(Mutex::new(Vec::new())),
496 }
497 }
498
499 fn get_alerts(&self) -> Vec<AuditAlert> {
500 self.alerts.lock().unwrap().clone()
501 }
502 }
503
504 #[async_trait::async_trait]
505 impl AlertHandler for TestAlertHandler {
506 async fn handle_alert(&self, alert: &AuditAlert) -> Result<()> {
507 self.alerts.lock().unwrap().push(alert.clone());
508 Ok(())
509 }
510 }
511
512 /// Mock audit storage for testing
513 struct MockAuditStorage;
514
515 #[async_trait::async_trait]
516 impl transparent_logging::AuditStorage for MockAuditStorage {
517 async fn store_entry(&self, _entry: AuditLogEntry) -> Result<()> {
518 Ok(())
519 }
520
521 async fn query_entries(&self, _query: transparent_logging::AuditQuery) -> Result<Vec<AuditLogEntry>> {
522 Ok(Vec::new())
523 }
524
525 async fn rotate_logs(&self, _retention_days: u32) -> Result<()> {
526 Ok(())
527 }
528
529 async fn get_storage_stats(&self) -> Result<(u64, u64)> {
530 Ok((0, 0))
531 }
532 }
533
534 #[tokio::test]
535 async fn test_unified_audit_manager() -> Result<()> {
536 let config = UnifiedAuditConfig::default();
537 let storage = Box::new(MockAuditStorage);
538 let mut audit_manager = UnifiedAuditManager::new(config, "test-node".to_string(), storage);
539
540 let alert_handler = Box::new(TestAlertHandler::new());
541 audit_manager.add_alert_handler(alert_handler);
542
543 // Test logging various events
544 audit_manager.log_storage_event(StorageEvent::ChunkStored {
545 chunk_id: Uuid::new_v4(),
546 size: 1024,
547 node_id: "test-node".to_string(),
548 }).await?;
549
550 audit_manager.log_security_event(SecurityEvent::ThreatDetected {
551 threat_type: "malware".to_string(),
552 severity: "high".to_string(),
553 details: "Test threat detection".to_string(),
554 }).await?;
555
556 Ok(())
557 }
558
559 #[test]
560 fn test_identifier_hashing() {
561 let original = "user@example.com";
562 let hashed = UnifiedAuditManager::hash_identifier(original);
563
564 assert!(hashed.starts_with("hashed_"));
565 assert_ne!(hashed, original);
566 // Same input should produce same hash
567 assert_eq!(hashed, UnifiedAuditManager::hash_identifier(original));
568 }
569 }