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
11pub 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#[derive(Debug, Clone, Serialize, Deserialize, Default)]
29pub struct SecurityConfig {
30 pub tls: TlsConfig,
32
33 pub auth: AuthConfig,
35
36 pub rate_limiting: RateLimitConfig,
38
39 pub audit_logging: AuditConfig,
41
42 pub pii_protection: PiiConfig,
44
45 pub rbac: RbacConfig,
47
48 pub secrets: SecretsConfig,
50
51 pub gdpr: GdprConfig,
53
54 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>>, 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, 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(), r"\b[\w\.-]+@[\w\.-]+\.\w+\b".to_string(), r"\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b".to_string(), ],
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, 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, 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>;