codex_memory/security/
mod.rs

1pub mod audit;
2pub mod auth;
3pub mod compliance;
4pub mod pii;
5pub mod rate_limit;
6pub mod rbac;
7pub mod secrets;
8pub mod tls;
9pub mod validation;
10
11// Complex integration tests removed for now
12
13pub use audit::*;
14pub use auth::*;
15pub use compliance::*;
16pub use pii::*;
17pub use rate_limit::*;
18pub use rbac::*;
19pub use secrets::*;
20pub use tls::*;
21pub use validation::*;
22
23use serde::{Deserialize, Serialize};
24use std::collections::HashMap;
25use std::path::PathBuf;
26
27/// Main security configuration
28#[derive(Debug, Clone, Serialize, Deserialize, Default)]
29pub struct SecurityConfig {
30    /// TLS configuration
31    pub tls: TlsConfig,
32
33    /// Authentication configuration
34    pub auth: AuthConfig,
35
36    /// Rate limiting configuration
37    pub rate_limiting: RateLimitConfig,
38
39    /// Audit logging configuration
40    pub audit_logging: AuditConfig,
41
42    /// PII detection and masking configuration
43    pub pii_protection: PiiConfig,
44
45    /// RBAC configuration
46    pub rbac: RbacConfig,
47
48    /// Secrets management configuration
49    pub secrets: SecretsConfig,
50
51    /// GDPR compliance configuration
52    pub gdpr: GdprConfig,
53
54    /// Input validation configuration
55    pub validation: ValidationConfig,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct TlsConfig {
60    pub enabled: bool,
61    pub cert_path: PathBuf,
62    pub key_path: PathBuf,
63    pub port: u16,
64    pub require_client_cert: bool,
65    pub client_ca_path: Option<PathBuf>,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct AuthConfig {
70    pub enabled: bool,
71    pub jwt_secret: String,
72    pub jwt_expiry_seconds: u64,
73    pub api_key_enabled: bool,
74    pub mtls_enabled: bool,
75    pub session_timeout_minutes: u64,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct RateLimitConfig {
80    pub enabled: bool,
81    pub requests_per_minute: u32,
82    pub burst_size: u32,
83    pub per_ip: bool,
84    pub per_user: bool,
85    pub whitelist_ips: Vec<String>,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct AuditConfig {
90    pub enabled: bool,
91    pub log_all_requests: bool,
92    pub log_data_access: bool,
93    pub log_modifications: bool,
94    pub log_auth_events: bool,
95    pub retention_days: u32,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct PiiConfig {
100    pub enabled: bool,
101    pub detect_patterns: Vec<String>,
102    pub mask_in_logs: bool,
103    pub mask_in_responses: bool,
104    pub anonymize_storage: bool,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct RbacConfig {
109    pub enabled: bool,
110    pub default_role: String,
111    pub roles: HashMap<String, Vec<String>>, // role -> permissions
112    pub admin_users: Vec<String>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct SecretsConfig {
117    pub vault_enabled: bool,
118    pub vault_address: Option<String>,
119    pub vault_token_path: Option<PathBuf>,
120    pub env_fallback: bool,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct GdprConfig {
125    pub enabled: bool,
126    pub data_retention_days: u32,
127    pub auto_cleanup: bool,
128    pub consent_required: bool,
129    pub right_to_be_forgotten: bool,
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct ValidationConfig {
134    pub enabled: bool,
135    pub max_request_size: u64,
136    pub sanitize_input: bool,
137    pub xss_protection: bool,
138    pub sql_injection_protection: bool,
139}
140
141impl Default for TlsConfig {
142    fn default() -> Self {
143        Self {
144            enabled: false,
145            cert_path: PathBuf::from("/etc/ssl/certs/codex.crt"),
146            key_path: PathBuf::from("/etc/ssl/private/codex.key"),
147            port: 8443,
148            require_client_cert: false,
149            client_ca_path: None,
150        }
151    }
152}
153
154impl Default for AuthConfig {
155    fn default() -> Self {
156        Self {
157            enabled: false,
158            jwt_secret: "change-me-in-production".to_string(),
159            jwt_expiry_seconds: 3600, // 1 hour
160            api_key_enabled: false,
161            mtls_enabled: false,
162            session_timeout_minutes: 30,
163        }
164    }
165}
166
167impl Default for RateLimitConfig {
168    fn default() -> Self {
169        Self {
170            enabled: false,
171            requests_per_minute: 100,
172            burst_size: 10,
173            per_ip: true,
174            per_user: true,
175            whitelist_ips: vec!["127.0.0.1".to_string(), "::1".to_string()],
176        }
177    }
178}
179
180impl Default for AuditConfig {
181    fn default() -> Self {
182        Self {
183            enabled: false,
184            log_all_requests: false,
185            log_data_access: true,
186            log_modifications: true,
187            log_auth_events: true,
188            retention_days: 90,
189        }
190    }
191}
192
193impl Default for PiiConfig {
194    fn default() -> Self {
195        Self {
196            enabled: false,
197            detect_patterns: vec![
198                r"\b\d{3}-\d{2}-\d{4}\b".to_string(),                      // SSN
199                r"\b[\w\.-]+@[\w\.-]+\.\w+\b".to_string(),                 // Email
200                r"\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b".to_string(), // Credit card
201            ],
202            mask_in_logs: true,
203            mask_in_responses: false,
204            anonymize_storage: false,
205        }
206    }
207}
208
209impl Default for RbacConfig {
210    fn default() -> Self {
211        let mut roles = HashMap::new();
212        roles.insert("user".to_string(), vec!["read".to_string()]);
213        roles.insert(
214            "admin".to_string(),
215            vec![
216                "read".to_string(),
217                "write".to_string(),
218                "delete".to_string(),
219            ],
220        );
221
222        Self {
223            enabled: false,
224            default_role: "user".to_string(),
225            roles,
226            admin_users: Vec::new(),
227        }
228    }
229}
230
231impl Default for SecretsConfig {
232    fn default() -> Self {
233        Self {
234            vault_enabled: false,
235            vault_address: None,
236            vault_token_path: None,
237            env_fallback: true,
238        }
239    }
240}
241
242impl Default for GdprConfig {
243    fn default() -> Self {
244        Self {
245            enabled: false,
246            data_retention_days: 730, // 2 years
247            auto_cleanup: false,
248            consent_required: false,
249            right_to_be_forgotten: false,
250        }
251    }
252}
253
254impl Default for ValidationConfig {
255    fn default() -> Self {
256        Self {
257            enabled: true,
258            max_request_size: 10 * 1024 * 1024, // 10MB
259            sanitize_input: true,
260            xss_protection: true,
261            sql_injection_protection: true,
262        }
263    }
264}
265
266#[derive(Debug, thiserror::Error)]
267pub enum SecurityError {
268    #[error("Authentication failed: {message}")]
269    AuthenticationFailed { message: String },
270
271    #[error("Authorization failed: {message}")]
272    AuthorizationFailed { message: String },
273
274    #[error("Rate limit exceeded")]
275    RateLimitExceeded,
276
277    #[error("TLS error: {message}")]
278    TlsError { message: String },
279
280    #[error("Validation error: {message}")]
281    ValidationError { message: String },
282
283    #[error("PII detected in content")]
284    PiiDetected,
285
286    #[error("GDPR compliance error: {message}")]
287    GdprError { message: String },
288
289    #[error("Audit error: {message}")]
290    AuditError { message: String },
291
292    #[error("Secrets management error: {message}")]
293    SecretsError { message: String },
294}
295
296pub type Result<T> = std::result::Result<T, SecurityError>;