uvb-storage-api 0.2.1

Storage backend trait abstractions for UVB data persistence
Documentation
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::time::SystemTime;
use thiserror::Error;
use uvb_core::TenantId;

#[derive(Debug, Error)]
pub enum AuditError {
    #[error("storage error: {0}")]
    Storage(String),
    #[error("serialization error: {0}")]
    Serialization(String),
    #[error("decryption error: {0}")]
    Decryption(String),
    #[error("configuration error: {0}")]
    Configuration(String),
}

/// Audit event for compliance and security monitoring
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AuditEvent {
    pub id: String,
    pub timestamp: SystemTime,
    pub event_type: AuditEventType,
    pub user_id: Option<String>,
    pub tenant_id: TenantId,
    pub transaction_id: Option<String>,
    pub factor_id: Option<String>,
    pub success: bool,
    pub ip_address: Option<String>,
    pub user_agent: Option<String>,
    pub error_code: Option<String>,
    pub metadata: serde_json::Value,
    /// SHA-256 hash of the previous audit event in the chain (for tamper detection)
    pub previous_hash: Option<String>,
    /// SHA-256 hash of this audit event (includes previous_hash)
    pub entry_hash: Option<String>,
    /// Geographic location - country code (ISO 3166-1 alpha-2)
    pub geo_country: Option<String>,
    /// Geographic location - region/state
    pub geo_region: Option<String>,
    /// Geographic location - city
    pub geo_city: Option<String>,
    /// Geographic coordinates - latitude
    pub geo_latitude: Option<f64>,
    /// Geographic coordinates - longitude
    pub geo_longitude: Option<f64>,
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum AuditEventType {
    // Verification events
    VerificationStarted,
    VerificationSucceeded,
    VerificationFailed,
    FactorChallengeIssued,
    FactorVerified,
    FactorFailed,

    // Enrollment events
    FactorEnrolled,
    FactorUnenrolled,
    FactorSuspended,
    FactorRevoked,

    // Session events
    SessionCreated,
    SessionExtended,
    SessionExpired,
    SessionRevoked,

    // Administrative events
    PolicyUpdated,
    ConfigurationChanged,
    SecretRotated,

    // Security events
    RateLimitExceeded,
    SuspiciousActivity,
    AccountLockout,
}

/// Trait for pluggable audit logging
///
/// Implementations might be:
/// - PostgreSQL (append-only)
/// - Elasticsearch/OpenSearch
/// - CloudWatch Logs
/// - Splunk
/// - File-based logging
#[async_trait]
pub trait AuditLogStore: Send + Sync {
    /// Log an audit event (never fails - critical for security)
    async fn log(&self, event: AuditEvent) -> Result<(), AuditError>;

    /// Query audit events (for admin dashboards, compliance)
    async fn query(&self, filters: AuditQueryFilters) -> Result<Vec<AuditEvent>, AuditError>;

    /// Count events matching filters
    async fn count(&self, filters: AuditQueryFilters) -> Result<u64, AuditError>;
}

#[derive(Clone, Debug, Default)]
pub struct AuditQueryFilters {
    pub user_id: Option<String>,
    pub tenant_id: Option<TenantId>,
    pub event_types: Option<Vec<AuditEventType>>,
    pub start_time: Option<SystemTime>,
    pub end_time: Option<SystemTime>,
    pub success: Option<bool>,
    pub limit: Option<usize>,
    pub offset: Option<usize>,
}