Skip to main content

uvb_storage_api/
audit.rs

1use async_trait::async_trait;
2use serde::{Deserialize, Serialize};
3use std::time::SystemTime;
4use thiserror::Error;
5use uvb_core::TenantId;
6
7#[derive(Debug, Error)]
8pub enum AuditError {
9    #[error("storage error: {0}")]
10    Storage(String),
11    #[error("serialization error: {0}")]
12    Serialization(String),
13    #[error("decryption error: {0}")]
14    Decryption(String),
15    #[error("configuration error: {0}")]
16    Configuration(String),
17}
18
19/// Audit event for compliance and security monitoring
20#[derive(Clone, Debug, Serialize, Deserialize)]
21pub struct AuditEvent {
22    pub id: String,
23    pub timestamp: SystemTime,
24    pub event_type: AuditEventType,
25    pub user_id: Option<String>,
26    pub tenant_id: TenantId,
27    pub transaction_id: Option<String>,
28    pub factor_id: Option<String>,
29    pub success: bool,
30    pub ip_address: Option<String>,
31    pub user_agent: Option<String>,
32    pub error_code: Option<String>,
33    pub metadata: serde_json::Value,
34    /// SHA-256 hash of the previous audit event in the chain (for tamper detection)
35    pub previous_hash: Option<String>,
36    /// SHA-256 hash of this audit event (includes previous_hash)
37    pub entry_hash: Option<String>,
38    /// Geographic location - country code (ISO 3166-1 alpha-2)
39    pub geo_country: Option<String>,
40    /// Geographic location - region/state
41    pub geo_region: Option<String>,
42    /// Geographic location - city
43    pub geo_city: Option<String>,
44    /// Geographic coordinates - latitude
45    pub geo_latitude: Option<f64>,
46    /// Geographic coordinates - longitude
47    pub geo_longitude: Option<f64>,
48}
49
50#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
51pub enum AuditEventType {
52    // Verification events
53    VerificationStarted,
54    VerificationSucceeded,
55    VerificationFailed,
56    FactorChallengeIssued,
57    FactorVerified,
58    FactorFailed,
59
60    // Enrollment events
61    FactorEnrolled,
62    FactorUnenrolled,
63    FactorSuspended,
64    FactorRevoked,
65
66    // Session events
67    SessionCreated,
68    SessionExtended,
69    SessionExpired,
70    SessionRevoked,
71
72    // Administrative events
73    PolicyUpdated,
74    ConfigurationChanged,
75    SecretRotated,
76
77    // Security events
78    RateLimitExceeded,
79    SuspiciousActivity,
80    AccountLockout,
81}
82
83/// Trait for pluggable audit logging
84///
85/// Implementations might be:
86/// - PostgreSQL (append-only)
87/// - Elasticsearch/OpenSearch
88/// - CloudWatch Logs
89/// - Splunk
90/// - File-based logging
91#[async_trait]
92pub trait AuditLogStore: Send + Sync {
93    /// Log an audit event (never fails - critical for security)
94    async fn log(&self, event: AuditEvent) -> Result<(), AuditError>;
95
96    /// Query audit events (for admin dashboards, compliance)
97    async fn query(&self, filters: AuditQueryFilters) -> Result<Vec<AuditEvent>, AuditError>;
98
99    /// Count events matching filters
100    async fn count(&self, filters: AuditQueryFilters) -> Result<u64, AuditError>;
101}
102
103#[derive(Clone, Debug, Default)]
104pub struct AuditQueryFilters {
105    pub user_id: Option<String>,
106    pub tenant_id: Option<TenantId>,
107    pub event_types: Option<Vec<AuditEventType>>,
108    pub start_time: Option<SystemTime>,
109    pub end_time: Option<SystemTime>,
110    pub success: Option<bool>,
111    pub limit: Option<usize>,
112    pub offset: Option<usize>,
113}