#![deny(clippy::unwrap_used, clippy::expect_used)] #![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))] #![allow(dead_code)] #![allow(missing_docs)] #![allow(missing_debug_implementations)] #![allow(unused_crate_dependencies)] #![allow(clippy::float_arithmetic)] #![allow(clippy::non_ascii_literal)] #![allow(clippy::str_to_string)] #![allow(clippy::partial_pub_fields)] #![allow(clippy::multiple_inherent_impl)] #![allow(clippy::same_name_method)] #![allow(clippy::shadow_reuse)] #![allow(clippy::shadow_unrelated)] #![allow(clippy::shadow_same)] #![allow(clippy::doc_markdown)] #![allow(clippy::indexing_slicing)] #![allow(clippy::missing_const_for_fn)] #![allow(clippy::module_name_repetitions)] #![allow(clippy::integer_division)] #![allow(clippy::cognitive_complexity)] #![allow(clippy::similar_names)] #![allow(clippy::clone_on_ref_ptr)] #![allow(clippy::too_many_lines)] #![allow(clippy::as_conversions)] #![allow(clippy::cast_precision_loss)] #![allow(clippy::cast_possible_truncation)] #![allow(clippy::default_numeric_fallback)] #![allow(clippy::arithmetic_side_effects)] #![allow(clippy::needless_range_loop)] #![allow(clippy::into_iter_on_ref)] #![allow(clippy::new_without_default)] #![allow(clippy::manual_let_else)] #![allow(clippy::unnecessary_wraps)] #![allow(clippy::too_many_arguments)] #![allow(clippy::must_use_candidate)] #![allow(clippy::missing_errors_doc)] #![allow(clippy::cast_sign_loss)] #![allow(clippy::cast_possible_wrap)] #![allow(clippy::cast_lossless)] #![allow(clippy::unused_async)] #![allow(clippy::match_same_arms)] #![allow(clippy::unused_self)] #![allow(clippy::map_err_ignore)] #![allow(clippy::single_match_else)] #![allow(clippy::wildcard_imports)] #![allow(clippy::unnecessary_cast)] //! ML Security Module //! //! Provides comprehensive security features for ML inference: //! - Prediction validation and model poisoning detection //! - Ensemble anomaly detection //! - Security event logging //! //! # Architecture //! //! ```text //! ┌──────────────────┐ ┌──────────────────┐ //! │ Prediction │ │ Ensemble │ //! │ Validator │──────│ Anomaly │ //! │ │ │ Detector │ //! └────────┬─────────┘ └────────┬─────────┘ //! │ │ //! └─────────┬───────────────┘ //! │ //! ▼ //! ┌──────────────────┐ //! │ Security Event │ //! │ Logger │ //! └──────────────────┘ //! ``` pub mod anomaly_detector; pub mod prediction_validator; pub use anomaly_detector::{ Anomaly, AnomalyDetectorConfig, AnomalyReport, AnomalySeverity, DetectorStatistics, EnsembleAnomalyDetector, }; pub use prediction_validator::{ PredictionStats, PredictionValidator, ValidatedPrediction, ValidationConfig, ValidationFlag, }; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; /// Security event types for ML system #[derive(Debug, Clone, Serialize, Deserialize)] pub enum SecurityEventType { // Checkpoint security CheckpointSignatureFailure, CheckpointSignatureMissing, CheckpointTamperingDetected, // Prediction validation PredictionOutlierDetected, PredictionOutOfBounds, ExtremeRateExceeded, // Ensemble anomalies EnsembleSuddenShift, CoordinatedAttackSuspected, ModelBehavioralDrift, // System events AutomaticRollback, ManualIntervention, } /// Security event for logging #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SecurityEvent { /// Event type pub event_type: SecurityEventType, /// Severity level pub severity: SecuritySeverity, /// Event timestamp pub timestamp: DateTime, /// Model ID (if applicable) pub model_id: Option, /// Checkpoint ID (if applicable) pub checkpoint_id: Option, /// Prediction ID (if applicable) pub prediction_id: Option, /// Human-readable description pub description: String, /// Additional metadata pub metadata: serde_json::Value, /// Action taken in response pub action_taken: Option, } /// Security severity levels #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub enum SecuritySeverity { Low, Medium, High, Critical, } impl SecurityEvent { /// Create a new security event pub fn new( event_type: SecurityEventType, severity: SecuritySeverity, description: String, ) -> Self { Self { event_type, severity, timestamp: Utc::now(), model_id: None, checkpoint_id: None, prediction_id: None, description, metadata: serde_json::Value::Null, action_taken: None, } } /// Set model ID pub fn with_model_id(mut self, model_id: String) -> Self { self.model_id = Some(model_id); self } /// Set checkpoint ID pub fn with_checkpoint_id(mut self, checkpoint_id: String) -> Self { self.checkpoint_id = Some(checkpoint_id); self } /// Set prediction ID pub fn with_prediction_id(mut self, prediction_id: String) -> Self { self.prediction_id = Some(prediction_id); self } /// Set metadata pub fn with_metadata(mut self, metadata: serde_json::Value) -> Self { self.metadata = metadata; self } /// Set action taken pub fn with_action(mut self, action: String) -> Self { self.action_taken = Some(action); self } } #[cfg(test)] mod tests { use super::*; #[test] fn test_security_event_builder() { let event = SecurityEvent::new( SecurityEventType::PredictionOutlierDetected, SecuritySeverity::Medium, "Test outlier detection".to_owned(), ) .with_model_id("DQN".to_owned()) .with_action("Flagged for review".to_owned()); assert_eq!(event.severity, SecuritySeverity::Medium); assert_eq!(event.model_id, Some("DQN".to_owned())); assert_eq!(event.action_taken, Some("Flagged for review".to_owned())); } #[test] fn test_severity_ordering() { assert!(SecuritySeverity::Critical > SecuritySeverity::High); assert!(SecuritySeverity::High > SecuritySeverity::Medium); assert!(SecuritySeverity::Medium > SecuritySeverity::Low); } }