1use anyhow::{anyhow, Result};
7use chrono::{DateTime, Duration as ChronoDuration, Utc};
8use serde::{Deserialize, Serialize};
9use std::collections::{HashMap, HashSet};
10use std::sync::Arc;
11use std::time::Instant;
12use tokio::sync::RwLock;
13use uuid::Uuid;
14
15#[derive(Debug, Clone, Serialize, Deserialize, Default)]
17pub struct SecurityConfig {
18 pub authentication: AuthConfig,
20 pub authorization: AuthzConfig,
22 pub encryption: EncryptionConfig,
24 pub post_quantum: PostQuantumConfig,
26 pub quantum_resistant_certs: QuantumResistantCerts,
28 pub audit: AuditConfig,
30 pub threat_detection: ThreatDetectionConfig,
32 pub rate_limiting: RateLimitConfig,
34 pub session: SessionConfig,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct AuthConfig {
41 pub methods: Vec<AuthMethod>,
43 pub mfa: MfaConfig,
45 pub token: TokenConfig,
47 pub password_policy: PasswordPolicy,
49}
50
51impl Default for AuthConfig {
52 fn default() -> Self {
53 Self {
54 methods: vec![AuthMethod::ApiKey, AuthMethod::JWT],
55 mfa: MfaConfig::default(),
56 token: TokenConfig::default(),
57 password_policy: PasswordPolicy::default(),
58 }
59 }
60}
61
62#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
64pub enum AuthMethod {
65 ApiKey,
66 JWT,
67 OAuth2,
68 SAML,
69 Certificate,
70 Basic,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct MfaConfig {
76 pub enabled: bool,
77 pub required_for_admin: bool,
78 pub methods: Vec<MfaMethod>,
79 pub backup_codes: bool,
80}
81
82impl Default for MfaConfig {
83 fn default() -> Self {
84 Self {
85 enabled: false,
86 required_for_admin: true,
87 methods: vec![MfaMethod::TOTP],
88 backup_codes: true,
89 }
90 }
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
95pub enum MfaMethod {
96 TOTP, SMS, Email, Hardware, }
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct TokenConfig {
105 pub jwt_secret: String,
106 pub access_token_ttl: ChronoDuration,
107 pub refresh_token_ttl: ChronoDuration,
108 pub issuer: String,
109 pub audience: String,
110}
111
112impl Default for TokenConfig {
113 fn default() -> Self {
114 Self {
115 jwt_secret: "change-this-secret".to_string(),
116 access_token_ttl: ChronoDuration::hours(1),
117 refresh_token_ttl: ChronoDuration::days(30),
118 issuer: "oxirs-stream".to_string(),
119 audience: "oxirs-api".to_string(),
120 }
121 }
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct PasswordPolicy {
127 pub min_length: usize,
128 pub require_uppercase: bool,
129 pub require_lowercase: bool,
130 pub require_numbers: bool,
131 pub require_symbols: bool,
132 pub max_age_days: Option<u32>,
133 pub history_count: usize,
134}
135
136impl Default for PasswordPolicy {
137 fn default() -> Self {
138 Self {
139 min_length: 12,
140 require_uppercase: true,
141 require_lowercase: true,
142 require_numbers: true,
143 require_symbols: true,
144 max_age_days: Some(90),
145 history_count: 5,
146 }
147 }
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct AuthzConfig {
153 pub model: AuthzModel,
155 pub default_permissions: Vec<Permission>,
157 pub rbac: RbacConfig,
159 pub abac: AbacConfig,
161}
162
163impl Default for AuthzConfig {
164 fn default() -> Self {
165 Self {
166 model: AuthzModel::RBAC,
167 default_permissions: vec![Permission::Read],
168 rbac: RbacConfig::default(),
169 abac: AbacConfig::default(),
170 }
171 }
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
176pub enum AuthzModel {
177 RBAC, ABAC, MAC, DAC, }
182
183#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
185pub enum Permission {
186 Read,
187 Write,
188 Delete,
189 Admin,
190 Execute,
191 Stream,
192 Query,
193 Configure,
194}
195
196impl std::fmt::Display for Permission {
197 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
198 match self {
199 Permission::Read => write!(f, "read"),
200 Permission::Write => write!(f, "write"),
201 Permission::Delete => write!(f, "delete"),
202 Permission::Admin => write!(f, "admin"),
203 Permission::Execute => write!(f, "execute"),
204 Permission::Stream => write!(f, "stream"),
205 Permission::Query => write!(f, "query"),
206 Permission::Configure => write!(f, "configure"),
207 }
208 }
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct RbacConfig {
214 pub enabled: bool,
215 pub default_role: String,
216 pub role_hierarchy: HashMap<String, Vec<String>>,
217 pub role_permissions: HashMap<String, Vec<Permission>>,
218}
219
220impl Default for RbacConfig {
221 fn default() -> Self {
222 let mut role_permissions = HashMap::new();
223 role_permissions.insert(
224 "viewer".to_string(),
225 vec![Permission::Read, Permission::Query],
226 );
227 role_permissions.insert(
228 "user".to_string(),
229 vec![
230 Permission::Read,
231 Permission::Write,
232 Permission::Stream,
233 Permission::Query,
234 ],
235 );
236 role_permissions.insert(
237 "admin".to_string(),
238 vec![
239 Permission::Read,
240 Permission::Write,
241 Permission::Delete,
242 Permission::Admin,
243 Permission::Execute,
244 Permission::Stream,
245 Permission::Query,
246 Permission::Configure,
247 ],
248 );
249
250 let mut role_hierarchy = HashMap::new();
251 role_hierarchy.insert(
252 "admin".to_string(),
253 vec!["user".to_string(), "viewer".to_string()],
254 );
255 role_hierarchy.insert("user".to_string(), vec!["viewer".to_string()]);
256
257 Self {
258 enabled: true,
259 default_role: "viewer".to_string(),
260 role_hierarchy,
261 role_permissions,
262 }
263 }
264}
265
266#[derive(Debug, Clone, Serialize, Deserialize)]
268pub struct AbacConfig {
269 pub enabled: bool,
270 pub policy_engine: PolicyEngine,
271 pub attributes: Vec<AttributeDefinition>,
272}
273
274impl Default for AbacConfig {
275 fn default() -> Self {
276 Self {
277 enabled: false,
278 policy_engine: PolicyEngine::default(),
279 attributes: vec![
280 AttributeDefinition {
281 name: "department".to_string(),
282 attribute_type: AttributeType::String,
283 required: false,
284 },
285 AttributeDefinition {
286 name: "security_level".to_string(),
287 attribute_type: AttributeType::Integer,
288 required: true,
289 },
290 ],
291 }
292 }
293}
294
295#[derive(Debug, Clone, Serialize, Deserialize)]
297pub struct PolicyEngine {
298 pub language: PolicyLanguage,
299 pub cache_policies: bool,
300 pub cache_ttl: ChronoDuration,
301}
302
303impl Default for PolicyEngine {
304 fn default() -> Self {
305 Self {
306 language: PolicyLanguage::OPA,
307 cache_policies: true,
308 cache_ttl: ChronoDuration::minutes(30),
309 }
310 }
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
315pub enum PolicyLanguage {
316 OPA, Cedar, Custom, }
320
321#[derive(Debug, Clone, Serialize, Deserialize)]
323pub struct AttributeDefinition {
324 pub name: String,
325 pub attribute_type: AttributeType,
326 pub required: bool,
327}
328
329#[derive(Debug, Clone, Serialize, Deserialize)]
331pub enum AttributeType {
332 String,
333 Integer,
334 Boolean,
335 DateTime,
336 Array,
337}
338
339#[derive(Debug, Clone, Serialize, Deserialize, Default)]
341pub struct EncryptionConfig {
342 pub at_rest: EncryptionAtRest,
344 pub in_transit: EncryptionInTransit,
346 pub field_level: FieldLevelEncryption,
348}
349
350#[derive(Debug, Clone, Serialize, Deserialize)]
352pub struct EncryptionAtRest {
353 pub enabled: bool,
354 pub algorithm: EncryptionAlgorithm,
355 pub key_management: KeyManagement,
356}
357
358impl Default for EncryptionAtRest {
359 fn default() -> Self {
360 Self {
361 enabled: true,
362 algorithm: EncryptionAlgorithm::AES256GCM,
363 key_management: KeyManagement::default(),
364 }
365 }
366}
367
368#[derive(Debug, Clone, Serialize, Deserialize)]
370pub struct EncryptionInTransit {
371 pub enabled: bool,
372 pub tls_version: TlsVersion,
373 pub cipher_suites: Vec<String>,
374 pub certificate_validation: bool,
375}
376
377impl Default for EncryptionInTransit {
378 fn default() -> Self {
379 Self {
380 enabled: true,
381 tls_version: TlsVersion::V1_3,
382 cipher_suites: vec![
383 "TLS_AES_256_GCM_SHA384".to_string(),
384 "TLS_CHACHA20_POLY1305_SHA256".to_string(),
385 ],
386 certificate_validation: true,
387 }
388 }
389}
390
391#[derive(Debug, Clone, Serialize, Deserialize)]
393pub struct FieldLevelEncryption {
394 pub enabled: bool,
395 pub fields: Vec<String>,
396 pub algorithm: EncryptionAlgorithm,
397}
398
399impl Default for FieldLevelEncryption {
400 fn default() -> Self {
401 Self {
402 enabled: false,
403 fields: vec!["password".to_string(), "ssn".to_string()],
404 algorithm: EncryptionAlgorithm::AES256GCM,
405 }
406 }
407}
408
409#[derive(Debug, Clone, Serialize, Deserialize)]
411pub enum EncryptionAlgorithm {
412 AES256GCM,
414 AES256CBC,
415 ChaCha20Poly1305,
416
417 Kyber512,
419 Kyber768,
420 Kyber1024,
421
422 NewHope1024,
424 FrodoKEM640,
425 FrodoKEM976,
426 FrodoKEM1344,
427
428 Rainbow1,
430 Rainbow3,
431 Rainbow5,
432
433 SphincsPlus128s,
435 SphincsPlus256s,
436
437 SikeP434,
439 SikeP503,
440 SikeP751,
441
442 McEliece348864,
444 McEliece460896,
445 McEliece6688128,
446
447 HybridAesKyber768,
449 HybridChaCha20NewHope,
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
454pub enum TlsVersion {
455 V1_2,
456 V1_3,
457}
458
459#[derive(Debug, Clone, Serialize, Deserialize)]
461pub struct KeyManagement {
462 pub provider: KeyProvider,
463 pub rotation_interval: ChronoDuration,
464 pub key_derivation: KeyDerivation,
465}
466
467impl Default for KeyManagement {
468 fn default() -> Self {
469 Self {
470 provider: KeyProvider::Local,
471 rotation_interval: ChronoDuration::days(90),
472 key_derivation: KeyDerivation::PBKDF2,
473 }
474 }
475}
476
477#[derive(Debug, Clone, Serialize, Deserialize)]
479pub enum KeyProvider {
480 Local,
481 HSM,
482 AwsKms,
483 AzureKeyVault,
484 HashiCorpVault,
485}
486
487#[derive(Debug, Clone, Serialize, Deserialize)]
489pub enum KeyDerivation {
490 PBKDF2,
492 Scrypt,
493 Argon2,
494
495 LatticeBasedKDF,
497 HashBasedKDF,
498 CodeBasedKDF,
499
500 HybridArgon2Lattice,
502 HybridScryptHash,
503}
504
505#[derive(Debug, Clone, Serialize, Deserialize)]
507pub enum PostQuantumSignature {
508 Dilithium2,
510 Dilithium3,
511 Dilithium5,
512
513 SphincsPlusSha2128s,
515 SphincsPlusSha2128f,
516 SphincsPlusSha2192s,
517 SphincsPlusSha2192f,
518 SphincsPlusSha2256s,
519 SphincsPlusSha2256f,
520 SphincsPlusShake128s,
521 SphincsPlusShake128f,
522 SphincsPlusShake192s,
523 SphincsPlusShake192f,
524 SphincsPlusShake256s,
525 SphincsPlusShake256f,
526
527 RainbowIClassic,
529 RainbowICircumzenithal,
530 RainbowICompressed,
531 RainbowIiiClassic,
532 RainbowIiiCircumzenithal,
533 RainbowIiiCompressed,
534 RainbowVClassic,
535 RainbowVCircumzenithal,
536 RainbowVCompressed,
537
538 Falcon512,
540 Falcon1024,
541
542 PicnicL1Fs,
544 PicnicL1Ur,
545 PicnicL3Fs,
546 PicnicL3Ur,
547 PicnicL5Fs,
548 PicnicL5Ur,
549}
550
551#[derive(Debug, Clone, Serialize, Deserialize)]
553pub struct PostQuantumConfig {
554 pub enabled: bool,
555 pub primary_kem: Option<EncryptionAlgorithm>,
556 pub signature_algorithm: Option<PostQuantumSignature>,
557 pub hybrid_mode: bool,
558 pub classical_fallback: bool,
559 pub quantum_security_level: QuantumSecurityLevel,
560 pub key_size_preferences: KeySizePreferences,
561}
562
563impl Default for PostQuantumConfig {
564 fn default() -> Self {
565 Self {
566 enabled: true,
567 primary_kem: Some(EncryptionAlgorithm::Kyber768),
568 signature_algorithm: Some(PostQuantumSignature::Dilithium3),
569 hybrid_mode: true,
570 classical_fallback: true,
571 quantum_security_level: QuantumSecurityLevel::Level3,
572 key_size_preferences: KeySizePreferences::default(),
573 }
574 }
575}
576
577#[derive(Debug, Clone, Serialize, Deserialize)]
579pub enum QuantumSecurityLevel {
580 Level1, Level2, Level3, Level4, Level5, }
586
587#[derive(Debug, Clone, Serialize, Deserialize)]
589pub struct KeySizePreferences {
590 pub prefer_smaller_keys: bool,
591 pub prefer_faster_signing: bool,
592 pub prefer_faster_verification: bool,
593 pub max_signature_size_kb: Option<u32>,
594 pub max_public_key_size_kb: Option<u32>,
595}
596
597impl Default for KeySizePreferences {
598 fn default() -> Self {
599 Self {
600 prefer_smaller_keys: true,
601 prefer_faster_signing: false,
602 prefer_faster_verification: true,
603 max_signature_size_kb: Some(50),
604 max_public_key_size_kb: Some(10),
605 }
606 }
607}
608
609#[derive(Debug, Clone, Serialize, Deserialize)]
611pub struct QuantumResistantCerts {
612 pub enabled: bool,
613 pub use_hybrid_certificates: bool,
614 pub pq_signature_algorithm: PostQuantumSignature,
615 pub classical_signature_fallback: bool,
616 pub certificate_chain_validation: PQCertValidation,
617}
618
619impl Default for QuantumResistantCerts {
620 fn default() -> Self {
621 Self {
622 enabled: false,
623 use_hybrid_certificates: true,
624 pq_signature_algorithm: PostQuantumSignature::Dilithium3,
625 classical_signature_fallback: true,
626 certificate_chain_validation: PQCertValidation::default(),
627 }
628 }
629}
630
631#[derive(Debug, Clone, Serialize, Deserialize)]
633pub struct PQCertValidation {
634 pub require_pq_signatures: bool,
635 pub allow_mixed_chain: bool,
636 pub minimum_security_level: QuantumSecurityLevel,
637 pub validate_quantum_resistance: bool,
638}
639
640impl Default for PQCertValidation {
641 fn default() -> Self {
642 Self {
643 require_pq_signatures: false,
644 allow_mixed_chain: true,
645 minimum_security_level: QuantumSecurityLevel::Level3,
646 validate_quantum_resistance: true,
647 }
648 }
649}
650
651#[derive(Debug, Clone, Serialize, Deserialize)]
653pub struct AuditConfig {
654 pub enabled: bool,
655 pub events: Vec<AuditEvent>,
656 pub retention_days: u32,
657 pub log_format: AuditLogFormat,
658 pub output: AuditOutput,
659}
660
661impl Default for AuditConfig {
662 fn default() -> Self {
663 Self {
664 enabled: true,
665 events: vec![
666 AuditEvent::Authentication,
667 AuditEvent::Authorization,
668 AuditEvent::DataAccess,
669 AuditEvent::ConfigChange,
670 ],
671 retention_days: 365,
672 log_format: AuditLogFormat::JSON,
673 output: AuditOutput::File("/var/log/oxirs/audit.log".to_string()),
674 }
675 }
676}
677
678#[derive(Debug, Clone, Serialize, Deserialize)]
680pub enum AuditEvent {
681 Authentication,
682 Authorization,
683 DataAccess,
684 ConfigChange,
685 UserManagement,
686 SecurityAlert,
687}
688
689#[derive(Debug, Clone, Serialize, Deserialize)]
691pub enum AuditLogFormat {
692 JSON,
693 CEF, LEEF, Syslog,
696}
697
698#[derive(Debug, Clone, Serialize, Deserialize)]
700pub enum AuditOutput {
701 File(String),
702 Syslog,
703 Database,
704 SIEM(String), }
706
707#[derive(Debug, Clone, Serialize, Deserialize)]
709pub struct ThreatDetectionConfig {
710 pub enabled: bool,
711 pub rules: Vec<ThreatRule>,
712 pub anomaly_detection: AnomalyDetectionConfig,
713 pub response: ThreatResponseConfig,
714}
715
716impl Default for ThreatDetectionConfig {
717 fn default() -> Self {
718 Self {
719 enabled: true,
720 rules: vec![
721 ThreatRule {
722 name: "Multiple Failed Logins".to_string(),
723 description: "Detect multiple failed login attempts".to_string(),
724 condition: "failed_logins > 5 in 5m".to_string(),
725 severity: ThreatSeverity::High,
726 enabled: true,
727 },
728 ThreatRule {
729 name: "Unusual Access Pattern".to_string(),
730 description: "Detect unusual access patterns".to_string(),
731 condition: "requests > 1000 in 1m".to_string(),
732 severity: ThreatSeverity::Medium,
733 enabled: true,
734 },
735 ],
736 anomaly_detection: AnomalyDetectionConfig::default(),
737 response: ThreatResponseConfig::default(),
738 }
739 }
740}
741
742#[derive(Debug, Clone, Serialize, Deserialize)]
744pub struct ThreatRule {
745 pub name: String,
746 pub description: String,
747 pub condition: String,
748 pub severity: ThreatSeverity,
749 pub enabled: bool,
750}
751
752#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
754pub enum ThreatSeverity {
755 Low,
756 Medium,
757 High,
758 Critical,
759}
760
761#[derive(Debug, Clone, Serialize, Deserialize)]
763pub struct AnomalyDetectionConfig {
764 pub enabled: bool,
765 pub algorithms: Vec<AnomalyAlgorithm>,
766 pub sensitivity: f64,
767 pub learning_period_days: u32,
768}
769
770impl Default for AnomalyDetectionConfig {
771 fn default() -> Self {
772 Self {
773 enabled: true,
774 algorithms: vec![
775 AnomalyAlgorithm::IsolationForest,
776 AnomalyAlgorithm::StatisticalOutlier,
777 ],
778 sensitivity: 0.8,
779 learning_period_days: 30,
780 }
781 }
782}
783
784#[derive(Debug, Clone, Serialize, Deserialize)]
786pub enum AnomalyAlgorithm {
787 IsolationForest,
788 StatisticalOutlier,
789 LSTM,
790 KMeans,
791}
792
793#[derive(Debug, Clone, Serialize, Deserialize)]
795pub struct ThreatResponseConfig {
796 pub auto_response: bool,
797 pub actions: Vec<ResponseAction>,
798 pub escalation: EscalationConfig,
799}
800
801impl Default for ThreatResponseConfig {
802 fn default() -> Self {
803 Self {
804 auto_response: true,
805 actions: vec![
806 ResponseAction::Block,
807 ResponseAction::RateLimit,
808 ResponseAction::Alert,
809 ],
810 escalation: EscalationConfig::default(),
811 }
812 }
813}
814
815#[derive(Debug, Clone, Serialize, Deserialize)]
817pub enum ResponseAction {
818 Block,
819 RateLimit,
820 Alert,
821 Quarantine,
822 Notify,
823}
824
825#[derive(Debug, Clone, Serialize, Deserialize)]
827pub struct EscalationConfig {
828 pub enabled: bool,
829 pub thresholds: HashMap<ThreatSeverity, u32>,
830 pub notifications: Vec<String>, }
832
833impl Default for EscalationConfig {
834 fn default() -> Self {
835 let mut thresholds = HashMap::new();
836 thresholds.insert(ThreatSeverity::Low, 10);
837 thresholds.insert(ThreatSeverity::Medium, 5);
838 thresholds.insert(ThreatSeverity::High, 1);
839 thresholds.insert(ThreatSeverity::Critical, 1);
840
841 Self {
842 enabled: true,
843 thresholds,
844 notifications: vec!["security@example.com".to_string()],
845 }
846 }
847}
848
849#[derive(Debug, Clone, Serialize, Deserialize)]
851pub struct RateLimitConfig {
852 pub enabled: bool,
853 pub global_limit: RateLimit,
854 pub per_user_limit: RateLimit,
855 pub per_ip_limit: RateLimit,
856 pub burst_limit: RateLimit,
857}
858
859impl Default for RateLimitConfig {
860 fn default() -> Self {
861 Self {
862 enabled: true,
863 global_limit: RateLimit {
864 requests: 10000,
865 window: ChronoDuration::minutes(1),
866 },
867 per_user_limit: RateLimit {
868 requests: 100,
869 window: ChronoDuration::minutes(1),
870 },
871 per_ip_limit: RateLimit {
872 requests: 1000,
873 window: ChronoDuration::minutes(1),
874 },
875 burst_limit: RateLimit {
876 requests: 50,
877 window: ChronoDuration::seconds(10),
878 },
879 }
880 }
881}
882
883#[derive(Debug, Clone, Serialize, Deserialize)]
885pub struct RateLimit {
886 pub requests: u32,
887 pub window: ChronoDuration,
888}
889
890#[derive(Debug, Clone, Serialize, Deserialize)]
892pub struct SessionConfig {
893 pub timeout: ChronoDuration,
894 pub max_concurrent: u32,
895 pub secure_cookies: bool,
896 pub same_site: SameSite,
897}
898
899impl Default for SessionConfig {
900 fn default() -> Self {
901 Self {
902 timeout: ChronoDuration::hours(8),
903 max_concurrent: 5,
904 secure_cookies: true,
905 same_site: SameSite::Strict,
906 }
907 }
908}
909
910#[derive(Debug, Clone, Serialize, Deserialize)]
912pub enum SameSite {
913 Strict,
914 Lax,
915 None,
916}
917
918#[derive(Debug, Clone)]
920pub struct SecurityContext {
921 pub user_id: Option<String>,
922 pub session_id: Option<String>,
923 pub roles: HashSet<String>,
924 pub permissions: HashSet<Permission>,
925 pub attributes: HashMap<String, String>,
926 pub ip_address: Option<String>,
927 pub user_agent: Option<String>,
928 pub authentication_method: Option<AuthMethod>,
929 pub authenticated_at: Option<DateTime<Utc>>,
930}
931
932impl SecurityContext {
933 pub fn has_permission(&self, permission: &Permission) -> bool {
935 self.permissions.contains(permission)
936 }
937
938 pub fn has_role(&self, role: &str) -> bool {
940 self.roles.contains(role)
941 }
942
943 pub fn has_any_role(&self, roles: &[String]) -> bool {
945 roles.iter().any(|role| self.roles.contains(role))
946 }
947
948 pub fn get_attribute(&self, name: &str) -> Option<&String> {
950 self.attributes.get(name)
951 }
952}
953
954pub struct SecurityManager {
956 config: SecurityConfig,
957 auth_provider: Arc<dyn AuthenticationProvider>,
958 authz_provider: Arc<dyn AuthorizationProvider>,
959 audit_logger: Arc<dyn AuditLogger>,
960 threat_detector: Arc<dyn ThreatDetector>,
961 rate_limiter: Arc<dyn RateLimiter>,
962 metrics: Arc<RwLock<SecurityMetrics>>,
963}
964
965impl SecurityManager {
966 pub fn new(
968 config: SecurityConfig,
969 auth_provider: Arc<dyn AuthenticationProvider>,
970 authz_provider: Arc<dyn AuthorizationProvider>,
971 audit_logger: Arc<dyn AuditLogger>,
972 threat_detector: Arc<dyn ThreatDetector>,
973 rate_limiter: Arc<dyn RateLimiter>,
974 ) -> Self {
975 Self {
976 config,
977 auth_provider,
978 authz_provider,
979 audit_logger,
980 threat_detector,
981 rate_limiter,
982 metrics: Arc::new(RwLock::new(SecurityMetrics::default())),
983 }
984 }
985
986 pub async fn authenticate(&self, credentials: &Credentials) -> Result<SecurityContext> {
988 let start_time = Instant::now();
989
990 if self.config.rate_limiting.enabled {
992 self.rate_limiter
993 .check_limit(&credentials.identifier())
994 .await?;
995 }
996
997 let result = self.auth_provider.authenticate(credentials).await;
999
1000 let audit_event = AuditLogEntry {
1002 event_type: AuditEvent::Authentication,
1003 timestamp: Utc::now(),
1004 user_id: credentials.user_id().map(|s| s.to_string()),
1005 ip_address: credentials.ip_address().map(|s| s.to_string()),
1006 success: result.is_ok(),
1007 details: format!("Authentication attempt for {}", credentials.identifier()),
1008 };
1009
1010 let _ = self.audit_logger.log(audit_event).await;
1011
1012 {
1014 let mut metrics = self.metrics.write().await;
1015 metrics.authentication_attempts += 1;
1016 if result.is_ok() {
1017 metrics.authentication_successes += 1;
1018 } else {
1019 metrics.authentication_failures += 1;
1020 }
1021 metrics.authentication_latency_ms = start_time.elapsed().as_millis() as f64;
1022 }
1023
1024 if result.is_err() {
1026 let _ = self
1027 .threat_detector
1028 .detect_threat(&ThreatContext {
1029 event_type: "authentication_failure".to_string(),
1030 user_id: credentials.user_id().map(|s| s.to_string()),
1031 ip_address: credentials.ip_address().map(|s| s.to_string()),
1032 timestamp: Utc::now(),
1033 details: HashMap::new(),
1034 })
1035 .await;
1036 }
1037
1038 result
1039 }
1040
1041 pub async fn authorize(
1043 &self,
1044 context: &SecurityContext,
1045 resource: &str,
1046 action: &Permission,
1047 ) -> Result<bool> {
1048 let start_time = Instant::now();
1049
1050 let result = self
1051 .authz_provider
1052 .authorize(context, resource, action)
1053 .await;
1054 let success = result.as_ref().map(|&b| b).unwrap_or(false);
1055
1056 let audit_event = AuditLogEntry {
1058 event_type: AuditEvent::Authorization,
1059 timestamp: Utc::now(),
1060 user_id: context.user_id.clone(),
1061 ip_address: context.ip_address.clone(),
1062 success,
1063 details: format!("Authorization check for {action} on {resource}"),
1064 };
1065
1066 let _ = self.audit_logger.log(audit_event).await;
1067
1068 {
1070 let mut metrics = self.metrics.write().await;
1071 metrics.authorization_checks += 1;
1072 if success {
1073 metrics.authorization_successes += 1;
1074 } else {
1075 metrics.authorization_failures += 1;
1076 }
1077 metrics.authorization_latency_ms = start_time.elapsed().as_millis() as f64;
1078 }
1079
1080 result
1081 }
1082
1083 pub async fn log_data_access(
1085 &self,
1086 context: &SecurityContext,
1087 resource: &str,
1088 operation: &str,
1089 ) -> Result<()> {
1090 let audit_event = AuditLogEntry {
1091 event_type: AuditEvent::DataAccess,
1092 timestamp: Utc::now(),
1093 user_id: context.user_id.clone(),
1094 ip_address: context.ip_address.clone(),
1095 success: true,
1096 details: format!("Data access: {operation} on {resource}"),
1097 };
1098
1099 self.audit_logger.log(audit_event).await
1100 }
1101
1102 pub async fn get_metrics(&self) -> SecurityMetrics {
1104 self.metrics.read().await.clone()
1105 }
1106}
1107
1108#[async_trait::async_trait]
1110pub trait AuthenticationProvider: Send + Sync {
1111 async fn authenticate(&self, credentials: &Credentials) -> Result<SecurityContext>;
1112 async fn validate_token(&self, token: &str) -> Result<SecurityContext>;
1113 async fn refresh_token(&self, refresh_token: &str) -> Result<(String, String)>; }
1115
1116#[async_trait::async_trait]
1118pub trait AuthorizationProvider: Send + Sync {
1119 async fn authorize(
1120 &self,
1121 context: &SecurityContext,
1122 resource: &str,
1123 action: &Permission,
1124 ) -> Result<bool>;
1125 async fn get_user_permissions(&self, user_id: &str) -> Result<HashSet<Permission>>;
1126 async fn get_user_roles(&self, user_id: &str) -> Result<HashSet<String>>;
1127}
1128
1129#[async_trait::async_trait]
1131pub trait AuditLogger: Send + Sync {
1132 async fn log(&self, entry: AuditLogEntry) -> Result<()>;
1133 async fn query(&self, filter: AuditFilter) -> Result<Vec<AuditLogEntry>>;
1134}
1135
1136#[async_trait::async_trait]
1138pub trait ThreatDetector: Send + Sync {
1139 async fn detect_threat(&self, context: &ThreatContext) -> Result<Option<ThreatAlert>>;
1140 async fn learn_pattern(&self, context: &ThreatContext) -> Result<()>;
1141}
1142
1143#[async_trait::async_trait]
1145pub trait RateLimiter: Send + Sync {
1146 async fn check_limit(&self, identifier: &str) -> Result<()>;
1147 async fn reset_limit(&self, identifier: &str) -> Result<()>;
1148}
1149
1150#[derive(Debug, Clone)]
1152pub enum Credentials {
1153 ApiKey {
1154 key: String,
1155 ip_address: Option<String>,
1156 },
1157 JWT {
1158 token: String,
1159 ip_address: Option<String>,
1160 },
1161 UserPassword {
1162 username: String,
1163 password: String,
1164 ip_address: Option<String>,
1165 },
1166 Certificate {
1167 cert: Vec<u8>,
1168 ip_address: Option<String>,
1169 },
1170}
1171
1172impl Credentials {
1173 pub fn identifier(&self) -> String {
1174 match self {
1175 Credentials::ApiKey { key, .. } => format!("api_key:{key}"),
1176 Credentials::JWT { token, .. } => format!("jwt:{token}"),
1177 Credentials::UserPassword { username, .. } => format!("user:{username}"),
1178 Credentials::Certificate { .. } => "certificate".to_string(),
1179 }
1180 }
1181
1182 pub fn user_id(&self) -> Option<&str> {
1183 match self {
1184 Credentials::UserPassword { username, .. } => Some(username),
1185 _ => None,
1186 }
1187 }
1188
1189 pub fn ip_address(&self) -> Option<&str> {
1190 match self {
1191 Credentials::ApiKey { ip_address, .. }
1192 | Credentials::JWT { ip_address, .. }
1193 | Credentials::UserPassword { ip_address, .. }
1194 | Credentials::Certificate { ip_address, .. } => ip_address.as_deref(),
1195 }
1196 }
1197}
1198
1199#[derive(Debug, Clone, Serialize, Deserialize)]
1201pub struct AuditLogEntry {
1202 pub event_type: AuditEvent,
1203 pub timestamp: DateTime<Utc>,
1204 pub user_id: Option<String>,
1205 pub ip_address: Option<String>,
1206 pub success: bool,
1207 pub details: String,
1208}
1209
1210#[derive(Debug, Clone)]
1212pub struct AuditFilter {
1213 pub event_types: Option<Vec<AuditEvent>>,
1214 pub user_id: Option<String>,
1215 pub ip_address: Option<String>,
1216 pub start_time: Option<DateTime<Utc>>,
1217 pub end_time: Option<DateTime<Utc>>,
1218 pub success: Option<bool>,
1219}
1220
1221#[derive(Debug, Clone)]
1223pub struct ThreatContext {
1224 pub event_type: String,
1225 pub user_id: Option<String>,
1226 pub ip_address: Option<String>,
1227 pub timestamp: DateTime<Utc>,
1228 pub details: HashMap<String, String>,
1229}
1230
1231#[derive(Debug, Clone)]
1233pub struct ThreatAlert {
1234 pub id: Uuid,
1235 pub rule_name: String,
1236 pub severity: ThreatSeverity,
1237 pub description: String,
1238 pub context: ThreatContext,
1239 pub timestamp: DateTime<Utc>,
1240 pub resolved: bool,
1241}
1242
1243#[derive(Debug, Clone, Default)]
1245pub struct SecurityMetrics {
1246 pub authentication_attempts: u64,
1247 pub authentication_successes: u64,
1248 pub authentication_failures: u64,
1249 pub authorization_checks: u64,
1250 pub authorization_successes: u64,
1251 pub authorization_failures: u64,
1252 pub threat_alerts: u64,
1253 pub rate_limit_violations: u64,
1254 pub authentication_latency_ms: f64,
1255 pub authorization_latency_ms: f64,
1256}
1257
1258pub struct PostQuantumCryptoEngine {
1260 config: Arc<PostQuantumConfig>,
1261 key_store: Arc<RwLock<HashMap<String, PostQuantumKeyPair>>>,
1262 signature_cache: Arc<RwLock<HashMap<String, SignatureInfo>>>,
1263 metrics: Arc<RwLock<PQCryptoMetrics>>,
1264}
1265
1266impl PostQuantumCryptoEngine {
1267 pub fn new(config: PostQuantumConfig) -> Self {
1269 Self {
1270 config: Arc::new(config),
1271 key_store: Arc::new(RwLock::new(HashMap::new())),
1272 signature_cache: Arc::new(RwLock::new(HashMap::new())),
1273 metrics: Arc::new(RwLock::new(PQCryptoMetrics::default())),
1274 }
1275 }
1276
1277 pub async fn generate_keypair(
1279 &self,
1280 algorithm: &PostQuantumSignature,
1281 ) -> Result<PostQuantumKeyPair> {
1282 let start_time = Instant::now();
1283
1284 let keypair = match algorithm {
1285 PostQuantumSignature::Dilithium2
1286 | PostQuantumSignature::Dilithium3
1287 | PostQuantumSignature::Dilithium5 => {
1288 self.generate_dilithium_keypair(algorithm).await?
1289 }
1290 PostQuantumSignature::SphincsPlusSha2128s
1291 | PostQuantumSignature::SphincsPlusSha2256s => {
1292 self.generate_sphincs_keypair(algorithm).await?
1293 }
1294 PostQuantumSignature::Falcon512 | PostQuantumSignature::Falcon1024 => {
1295 self.generate_falcon_keypair(algorithm).await?
1296 }
1297 _ => {
1298 return Err(anyhow!("Algorithm {:?} not yet implemented", algorithm));
1299 }
1300 };
1301
1302 {
1304 let mut metrics = self.metrics.write().await;
1305 metrics.key_generation_count += 1;
1306 metrics.avg_key_generation_time_ms = (metrics.avg_key_generation_time_ms
1307 + start_time.elapsed().as_millis() as f64)
1308 / 2.0;
1309 }
1310
1311 {
1313 let mut store = self.key_store.write().await;
1314 store.insert(keypair.id.clone(), keypair.clone());
1315 }
1316
1317 Ok(keypair)
1318 }
1319
1320 pub async fn sign(&self, key_id: &str, data: &[u8]) -> Result<PostQuantumSignature> {
1322 let start_time = Instant::now();
1323
1324 let key_store = self.key_store.read().await;
1325 let keypair = key_store
1326 .get(key_id)
1327 .ok_or_else(|| anyhow!("Key not found: {}", key_id))?;
1328
1329 let signature = match keypair.algorithm {
1330 PostQuantumSignature::Dilithium3 => {
1331 self.dilithium_sign(&keypair.private_key, data).await?
1332 }
1333 PostQuantumSignature::SphincsPlusSha2256s => {
1334 self.sphincs_sign(&keypair.private_key, data).await?
1335 }
1336 PostQuantumSignature::Falcon1024 => {
1337 self.falcon_sign(&keypair.private_key, data).await?
1338 }
1339 _ => {
1340 return Err(anyhow!(
1341 "Signing with {:?} not implemented",
1342 keypair.algorithm
1343 ));
1344 }
1345 };
1346
1347 {
1349 let mut metrics = self.metrics.write().await;
1350 metrics.signature_count += 1;
1351 metrics.avg_signing_time_ms =
1352 (metrics.avg_signing_time_ms + start_time.elapsed().as_millis() as f64) / 2.0;
1353 }
1354
1355 Ok(signature)
1356 }
1357
1358 pub async fn verify(
1360 &self,
1361 public_key: &[u8],
1362 data: &[u8],
1363 signature: &[u8],
1364 algorithm: &PostQuantumSignature,
1365 ) -> Result<bool> {
1366 let start_time = Instant::now();
1367
1368 let is_valid = match algorithm {
1369 PostQuantumSignature::Dilithium3 => {
1370 self.dilithium_verify(public_key, data, signature).await?
1371 }
1372 PostQuantumSignature::SphincsPlusSha2256s => {
1373 self.sphincs_verify(public_key, data, signature).await?
1374 }
1375 PostQuantumSignature::Falcon1024 => {
1376 self.falcon_verify(public_key, data, signature).await?
1377 }
1378 _ => {
1379 return Err(anyhow!("Verification for {:?} not implemented", algorithm));
1380 }
1381 };
1382
1383 {
1385 let mut metrics = self.metrics.write().await;
1386 metrics.verification_count += 1;
1387 metrics.avg_verification_time_ms =
1388 (metrics.avg_verification_time_ms + start_time.elapsed().as_millis() as f64) / 2.0;
1389 if is_valid {
1390 metrics.successful_verifications += 1;
1391 }
1392 }
1393
1394 Ok(is_valid)
1395 }
1396
1397 pub async fn encapsulate(
1399 &self,
1400 public_key: &[u8],
1401 algorithm: &EncryptionAlgorithm,
1402 ) -> Result<(Vec<u8>, Vec<u8>)> {
1403 match algorithm {
1404 EncryptionAlgorithm::Kyber768 => self.kyber_encapsulate(public_key).await,
1405 EncryptionAlgorithm::NewHope1024 => self.newhope_encapsulate(public_key).await,
1406 EncryptionAlgorithm::FrodoKEM976 => self.frodokem_encapsulate(public_key).await,
1407 _ => Err(anyhow!("KEM algorithm {:?} not implemented", algorithm)),
1408 }
1409 }
1410
1411 pub async fn decapsulate(
1413 &self,
1414 private_key: &[u8],
1415 ciphertext: &[u8],
1416 algorithm: &EncryptionAlgorithm,
1417 ) -> Result<Vec<u8>> {
1418 match algorithm {
1419 EncryptionAlgorithm::Kyber768 => self.kyber_decapsulate(private_key, ciphertext).await,
1420 EncryptionAlgorithm::NewHope1024 => {
1421 self.newhope_decapsulate(private_key, ciphertext).await
1422 }
1423 EncryptionAlgorithm::FrodoKEM976 => {
1424 self.frodokem_decapsulate(private_key, ciphertext).await
1425 }
1426 _ => Err(anyhow!("KEM algorithm {:?} not implemented", algorithm)),
1427 }
1428 }
1429
1430 async fn generate_dilithium_keypair(
1433 &self,
1434 _variant: &PostQuantumSignature,
1435 ) -> Result<PostQuantumKeyPair> {
1436 Ok(PostQuantumKeyPair {
1438 id: Uuid::new_v4().to_string(),
1439 algorithm: _variant.clone(),
1440 public_key: vec![0u8; 1312], private_key: vec![0u8; 4000], created_at: Utc::now(),
1443 })
1444 }
1445
1446 async fn generate_sphincs_keypair(
1447 &self,
1448 _variant: &PostQuantumSignature,
1449 ) -> Result<PostQuantumKeyPair> {
1450 Ok(PostQuantumKeyPair {
1452 id: Uuid::new_v4().to_string(),
1453 algorithm: _variant.clone(),
1454 public_key: vec![0u8; 32], private_key: vec![0u8; 64], created_at: Utc::now(),
1457 })
1458 }
1459
1460 async fn generate_falcon_keypair(
1461 &self,
1462 _variant: &PostQuantumSignature,
1463 ) -> Result<PostQuantumKeyPair> {
1464 Ok(PostQuantumKeyPair {
1466 id: Uuid::new_v4().to_string(),
1467 algorithm: _variant.clone(),
1468 public_key: vec![0u8; 1793], private_key: vec![0u8; 2305], created_at: Utc::now(),
1471 })
1472 }
1473
1474 async fn dilithium_sign(
1475 &self,
1476 _private_key: &[u8],
1477 _data: &[u8],
1478 ) -> Result<PostQuantumSignature> {
1479 Ok(PostQuantumSignature::Dilithium3)
1481 }
1482
1483 async fn sphincs_sign(
1484 &self,
1485 _private_key: &[u8],
1486 _data: &[u8],
1487 ) -> Result<PostQuantumSignature> {
1488 Ok(PostQuantumSignature::SphincsPlusSha2256s)
1490 }
1491
1492 async fn falcon_sign(&self, _private_key: &[u8], _data: &[u8]) -> Result<PostQuantumSignature> {
1493 Ok(PostQuantumSignature::Falcon1024)
1495 }
1496
1497 async fn dilithium_verify(
1498 &self,
1499 _public_key: &[u8],
1500 _data: &[u8],
1501 _signature: &[u8],
1502 ) -> Result<bool> {
1503 Ok(true)
1505 }
1506
1507 async fn sphincs_verify(
1508 &self,
1509 _public_key: &[u8],
1510 _data: &[u8],
1511 _signature: &[u8],
1512 ) -> Result<bool> {
1513 Ok(true)
1515 }
1516
1517 async fn falcon_verify(
1518 &self,
1519 _public_key: &[u8],
1520 _data: &[u8],
1521 _signature: &[u8],
1522 ) -> Result<bool> {
1523 Ok(true)
1525 }
1526
1527 async fn kyber_encapsulate(&self, _public_key: &[u8]) -> Result<(Vec<u8>, Vec<u8>)> {
1528 Ok((vec![0u8; 1088], vec![0u8; 32])) }
1531
1532 async fn newhope_encapsulate(&self, _public_key: &[u8]) -> Result<(Vec<u8>, Vec<u8>)> {
1533 Ok((vec![0u8; 2048], vec![0u8; 32])) }
1536
1537 async fn frodokem_encapsulate(&self, _public_key: &[u8]) -> Result<(Vec<u8>, Vec<u8>)> {
1538 Ok((vec![0u8; 15744], vec![0u8; 24])) }
1541
1542 async fn kyber_decapsulate(&self, _private_key: &[u8], _ciphertext: &[u8]) -> Result<Vec<u8>> {
1543 Ok(vec![0u8; 32]) }
1546
1547 async fn newhope_decapsulate(
1548 &self,
1549 _private_key: &[u8],
1550 _ciphertext: &[u8],
1551 ) -> Result<Vec<u8>> {
1552 Ok(vec![0u8; 32]) }
1555
1556 async fn frodokem_decapsulate(
1557 &self,
1558 _private_key: &[u8],
1559 _ciphertext: &[u8],
1560 ) -> Result<Vec<u8>> {
1561 Ok(vec![0u8; 24]) }
1564
1565 pub async fn get_metrics(&self) -> PQCryptoMetrics {
1567 self.metrics.read().await.clone()
1568 }
1569}
1570
1571#[derive(Debug, Clone, Serialize, Deserialize)]
1573pub struct PostQuantumKeyPair {
1574 pub id: String,
1575 pub algorithm: PostQuantumSignature,
1576 pub public_key: Vec<u8>,
1577 pub private_key: Vec<u8>,
1578 pub created_at: DateTime<Utc>,
1579}
1580
1581#[derive(Debug, Clone)]
1583struct SignatureInfo {
1584 signature: Vec<u8>,
1585 algorithm: PostQuantumSignature,
1586 created_at: DateTime<Utc>,
1587}
1588
1589#[derive(Debug, Clone, Default)]
1591pub struct PQCryptoMetrics {
1592 pub key_generation_count: u64,
1593 pub signature_count: u64,
1594 pub verification_count: u64,
1595 pub successful_verifications: u64,
1596 pub avg_key_generation_time_ms: f64,
1597 pub avg_signing_time_ms: f64,
1598 pub avg_verification_time_ms: f64,
1599 pub encapsulation_count: u64,
1600 pub decapsulation_count: u64,
1601 pub avg_encapsulation_time_ms: f64,
1602 pub avg_decapsulation_time_ms: f64,
1603}
1604
1605#[cfg(test)]
1606mod tests {
1607 use super::*;
1608
1609 #[test]
1610 fn test_security_config_defaults() {
1611 let config = SecurityConfig::default();
1612 assert!(config.authentication.methods.contains(&AuthMethod::ApiKey));
1613 assert!(config.authorization.rbac.enabled);
1614 assert!(config.encryption.at_rest.enabled);
1615 assert!(config.audit.enabled);
1616 }
1617
1618 #[test]
1619 fn test_security_context_permissions() {
1620 let mut context = SecurityContext {
1621 user_id: Some("test_user".to_string()),
1622 session_id: None,
1623 roles: HashSet::new(),
1624 permissions: HashSet::new(),
1625 attributes: HashMap::new(),
1626 ip_address: None,
1627 user_agent: None,
1628 authentication_method: None,
1629 authenticated_at: None,
1630 };
1631
1632 context.permissions.insert(Permission::Read);
1633 assert!(context.has_permission(&Permission::Read));
1634 assert!(!context.has_permission(&Permission::Write));
1635 }
1636
1637 #[test]
1638 fn test_credentials_identifier() {
1639 let creds = Credentials::ApiKey {
1640 key: "test_key".to_string(),
1641 ip_address: None,
1642 };
1643
1644 assert_eq!(creds.identifier(), "api_key:test_key");
1645 }
1646
1647 #[test]
1648 fn test_rbac_config_default_roles() {
1649 let rbac = RbacConfig::default();
1650 assert!(rbac.role_permissions.contains_key("admin"));
1651 assert!(rbac.role_permissions.contains_key("user"));
1652 assert!(rbac.role_permissions.contains_key("viewer"));
1653
1654 let admin_perms = rbac.role_permissions.get("admin").unwrap();
1655 assert!(admin_perms.contains(&Permission::Admin));
1656 assert!(admin_perms.contains(&Permission::Read));
1657 assert!(admin_perms.contains(&Permission::Write));
1658 }
1659}