adaptive_pipeline_domain/entities/security_context.rs
1// /////////////////////////////////////////////////////////////////////////////
2// Adaptive Pipeline
3// Copyright (c) 2025 Michael Gardner, A Bit of Help, Inc.
4// SPDX-License-Identifier: BSD-3-Clause
5// See LICENSE file in the project root.
6// /////////////////////////////////////////////////////////////////////////////
7
8//! # Security Context Entity
9//!
10//! The `SecurityContext` entity manages security-related information and access
11//! control for pipeline processing operations. It enforces security policies,
12//! tracks permissions, and maintains audit trails for secure data processing.
13//!
14//! ## Overview
15//!
16//! The security context provides:
17//!
18//! - **Access Control**: Permission-based authorization for operations
19//! - **Security Levels**: Hierarchical classification of data sensitivity
20//! - **Audit Tracking**: Session management and operation logging
21//! - **Key Management**: Integration with encryption key infrastructure
22//! - **Policy Enforcement**: Validation of security requirements
23//!
24//! ## Security Model
25//!
26//! The system implements a multi-layered security model:
27//!
28//! ### Permission-Based Access Control
29//! Fine-grained permissions control specific operations:
30//! - Read, Write, Execute for basic file operations
31//! - Encrypt, Decrypt for cryptographic operations
32//! - Compress, Decompress for data transformation
33//! - Admin for administrative functions
34//! - Custom permissions for extensibility
35//!
36//! ### Hierarchical Security Levels
37//! Data classification from Public to TopSecret:
38//! - **Public**: No restrictions, publicly accessible
39//! - **Internal**: Internal use only, basic protection
40//! - **Medium**: Moderate sensitivity, controlled access
41//! - **Confidential**: High sensitivity, restricted access
42//! - **Secret**: Very high sensitivity, need-to-know basis
43//! - **TopSecret**: Maximum sensitivity, highest protection
44//!
45//! ### Session Management
46//! Each context maintains a unique session for audit trails and tracking.
47
48use crate::services::datetime_serde;
49use serde::{Deserialize, Serialize};
50use std::collections::HashMap;
51use uuid::Uuid;
52
53/// Security context entity for managing access control and security policies.
54///
55/// The `SecurityContext` encapsulates all security-related information needed
56/// for pipeline processing operations. It enforces access control policies,
57/// maintains audit information, and integrates with encryption key management.
58///
59/// ## Security Features
60///
61/// - **Permission Management**: Fine-grained access control
62/// - **Security Classification**: Hierarchical data sensitivity levels
63/// - **Session Tracking**: Unique session identification for audit trails
64/// - **Key Integration**: Encryption key management and association
65/// - **Audit Support**: Comprehensive logging and tracking capabilities
66/// - **Policy Validation**: Enforcement of security requirements and
67/// constraints
68///
69/// ## Usage Examples
70///
71/// ### Creating a Basic Security Context
72///
73///
74/// ### Creating Context with Specific Permissions
75///
76///
77/// ### Managing Permissions Dynamically
78///
79///
80/// ### Security Level Validation
81///
82///
83/// ### Encryption Key Management
84///
85///
86/// ### Creating Restricted Contexts
87///
88///
89/// ### Audit and Session Management
90#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct SecurityContext {
92 user_id: Option<String>,
93 session_id: Uuid,
94 permissions: Vec<Permission>,
95 encryption_key_id: Option<String>,
96 integrity_required: bool,
97 audit_enabled: bool,
98 security_level: SecurityLevel,
99 metadata: HashMap<String, String>,
100 #[serde(with = "datetime_serde")]
101 created_at: chrono::DateTime<chrono::Utc>,
102}
103
104/// Security permission enumeration for fine-grained access control.
105///
106/// Permissions define specific operations that can be performed within the
107/// pipeline. The permission system supports both standard operations and custom
108/// extensions for specialized use cases.
109///
110/// ## Standard Permissions
111///
112/// ### File Operations
113/// - **Read**: Access to read files and data
114/// - **Write**: Ability to create and modify files
115/// - **Execute**: Permission to run processing operations
116///
117/// ### Cryptographic Operations
118/// - **Encrypt**: Ability to encrypt data
119/// - **Decrypt**: Ability to decrypt data
120///
121/// ### Data Transformation
122/// - **Compress**: Permission to compress data
123/// - **Decompress**: Permission to decompress data
124///
125/// ### Administrative
126/// - **Admin**: Full administrative access (implies all other permissions)
127///
128/// ### Extensibility
129/// - **Custom(String)**: Application-specific custom permissions
130///
131/// ## Permission Hierarchy
132///
133/// The Admin permission automatically grants all other permissions.
134/// Custom permissions are evaluated independently.
135///
136/// ## Usage Examples
137#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
138pub enum Permission {
139 Read,
140 Write,
141 Execute,
142 Admin,
143 Encrypt,
144 Decrypt,
145 Compress,
146 Decompress,
147 Custom(String),
148}
149
150/// Hierarchical security classification levels for data and operations.
151///
152/// Security levels provide a standardized way to classify the sensitivity of
153/// data and determine appropriate protection measures. Higher levels require
154/// stronger security controls and more restrictive access policies.
155///
156/// ## Security Level Hierarchy
157///
158/// Levels are ordered from lowest to highest sensitivity:
159///
160/// ### Public
161/// - **Sensitivity**: None
162/// - **Access**: Unrestricted public access
163/// - **Protection**: Minimal security controls
164/// - **Use Cases**: Public documentation, marketing materials
165///
166/// ### Internal
167/// - **Sensitivity**: Low
168/// - **Access**: Internal organization members
169/// - **Protection**: Basic access controls
170/// - **Use Cases**: Internal communications, general business data
171///
172/// ### Medium
173/// - **Sensitivity**: Moderate
174/// - **Access**: Authorized personnel only
175/// - **Protection**: Standard security measures
176/// - **Use Cases**: Business plans, financial reports
177///
178/// ### Confidential
179/// - **Sensitivity**: High
180/// - **Access**: Need-to-know basis
181/// - **Protection**: Strong encryption and access controls
182/// - **Use Cases**: Customer data, proprietary information
183///
184/// ### Secret
185/// - **Sensitivity**: Very High
186/// - **Access**: Strictly controlled
187/// - **Protection**: Advanced security measures
188/// - **Use Cases**: Trade secrets, sensitive personal data
189///
190/// ### TopSecret
191/// - **Sensitivity**: Maximum
192/// - **Access**: Highest clearance only
193/// - **Protection**: Maximum security controls
194/// - **Use Cases**: Critical infrastructure, national security data
195///
196/// ## Level Comparison
197///
198/// Security levels support comparison operations for policy enforcement:
199///
200///
201/// ## Usage Examples
202#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
203pub enum SecurityLevel {
204 Public,
205 Internal,
206 Medium,
207 Confidential,
208 Secret,
209 TopSecret,
210}
211
212impl Default for SecurityContext {
213 fn default() -> Self {
214 Self {
215 user_id: None,
216 session_id: Uuid::new_v4(),
217 permissions: vec![Permission::Read],
218 encryption_key_id: None,
219 integrity_required: false,
220 audit_enabled: true,
221 security_level: SecurityLevel::Internal,
222 metadata: HashMap::new(),
223 created_at: chrono::Utc::now(),
224 }
225 }
226}
227
228impl SecurityContext {
229 /// Creates a new security context
230 pub fn new(user_id: Option<String>, security_level: SecurityLevel) -> Self {
231 Self {
232 user_id,
233 security_level,
234 ..Default::default()
235 }
236 }
237
238 /// Creates a security context with permissions
239 pub fn with_permissions(
240 user_id: Option<String>,
241 permissions: Vec<Permission>,
242 security_level: SecurityLevel,
243 ) -> Self {
244 Self {
245 user_id,
246 permissions,
247 security_level,
248 ..Default::default()
249 }
250 }
251
252 /// Gets the user ID
253 pub fn user_id(&self) -> Option<&str> {
254 self.user_id.as_deref()
255 }
256
257 /// Gets the session ID
258 pub fn session_id(&self) -> Uuid {
259 self.session_id
260 }
261
262 /// Gets the permissions
263 pub fn permissions(&self) -> &[Permission] {
264 &self.permissions
265 }
266
267 /// Gets the encryption key ID
268 pub fn encryption_key_id(&self) -> Option<&str> {
269 self.encryption_key_id.as_deref()
270 }
271
272 /// Checks if integrity is required
273 pub fn integrity_required(&self) -> bool {
274 self.integrity_required
275 }
276
277 /// Checks if audit is enabled
278 pub fn audit_enabled(&self) -> bool {
279 self.audit_enabled
280 }
281
282 /// Gets the security level
283 pub fn security_level(&self) -> &SecurityLevel {
284 &self.security_level
285 }
286
287 /// Gets the metadata
288 pub fn metadata(&self) -> &HashMap<String, String> {
289 &self.metadata
290 }
291
292 /// Gets the creation timestamp
293 pub fn created_at(&self) -> chrono::DateTime<chrono::Utc> {
294 self.created_at
295 }
296
297 /// Sets the user ID
298 pub fn set_user_id(&mut self, user_id: Option<String>) {
299 self.user_id = user_id;
300 }
301
302 /// Adds a permission
303 pub fn add_permission(&mut self, permission: Permission) {
304 if !self.permissions.contains(&permission) {
305 self.permissions.push(permission);
306 }
307 }
308
309 /// Removes a permission
310 pub fn remove_permission(&mut self, permission: &Permission) {
311 self.permissions.retain(|p| p != permission);
312 }
313
314 /// Sets the encryption key ID
315 pub fn set_encryption_key_id(&mut self, key_id: Option<String>) {
316 self.encryption_key_id = key_id;
317 }
318
319 /// Sets integrity requirement
320 pub fn set_integrity_required(&mut self, required: bool) {
321 self.integrity_required = required;
322 }
323
324 /// Sets audit enablement
325 pub fn set_audit_enabled(&mut self, enabled: bool) {
326 self.audit_enabled = enabled;
327 }
328
329 /// Sets the security level
330 pub fn set_security_level(&mut self, level: SecurityLevel) {
331 self.security_level = level;
332 }
333
334 /// Adds metadata
335 pub fn add_metadata(&mut self, key: String, value: String) {
336 self.metadata.insert(key, value);
337 }
338
339 /// Removes metadata
340 pub fn remove_metadata(&mut self, key: &str) {
341 self.metadata.remove(key);
342 }
343
344 /// Checks if the context has a specific permission
345 pub fn has_permission(&self, permission: &Permission) -> bool {
346 self.permissions.contains(permission) || self.permissions.contains(&Permission::Admin)
347 }
348
349 /// Checks if the context can perform encryption
350 pub fn can_encrypt(&self) -> bool {
351 self.has_permission(&Permission::Encrypt) || self.has_permission(&Permission::Admin)
352 }
353
354 /// Checks if the context can perform decryption
355 pub fn can_decrypt(&self) -> bool {
356 self.has_permission(&Permission::Decrypt) || self.has_permission(&Permission::Admin)
357 }
358
359 /// Checks if the context can perform compression
360 pub fn can_compress(&self) -> bool {
361 self.has_permission(&Permission::Compress) || self.has_permission(&Permission::Admin)
362 }
363
364 /// Checks if the context can perform decompression
365 pub fn can_decompress(&self) -> bool {
366 self.has_permission(&Permission::Decompress) || self.has_permission(&Permission::Admin)
367 }
368
369 /// Checks if the context can read
370 pub fn can_read(&self) -> bool {
371 self.has_permission(&Permission::Read) || self.has_permission(&Permission::Admin)
372 }
373
374 /// Checks if the context can write
375 pub fn can_write(&self) -> bool {
376 self.has_permission(&Permission::Write) || self.has_permission(&Permission::Admin)
377 }
378
379 /// Checks if the context can execute
380 pub fn can_execute(&self) -> bool {
381 self.has_permission(&Permission::Execute) || self.has_permission(&Permission::Admin)
382 }
383
384 /// Checks if the security level meets the minimum requirement
385 pub fn meets_security_level(&self, minimum_level: &SecurityLevel) -> bool {
386 self.security_level >= *minimum_level
387 }
388
389 /// Creates a restricted copy of the security context
390 pub fn restrict(&self, allowed_permissions: Vec<Permission>) -> Self {
391 let restricted_permissions = self
392 .permissions
393 .iter()
394 .filter(|p| allowed_permissions.contains(p))
395 .cloned()
396 .collect();
397
398 Self {
399 user_id: self.user_id.clone(),
400 session_id: self.session_id,
401 permissions: restricted_permissions,
402 encryption_key_id: self.encryption_key_id.clone(),
403 integrity_required: self.integrity_required,
404 audit_enabled: self.audit_enabled,
405 security_level: self.security_level.clone(),
406 metadata: self.metadata.clone(),
407 created_at: self.created_at,
408 }
409 }
410
411 /// Validates the security context
412 pub fn validate(&self) -> Result<(), crate::PipelineError> {
413 if self.permissions.is_empty() {
414 return Err(crate::PipelineError::SecurityViolation(
415 "Security context must have at least one permission".to_string(),
416 ));
417 }
418
419 if self.integrity_required && self.encryption_key_id.is_none() {
420 return Err(crate::PipelineError::SecurityViolation(
421 "Integrity required but no encryption key specified".to_string(),
422 ));
423 }
424
425 Ok(())
426 }
427}
428
429impl std::fmt::Display for SecurityLevel {
430 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
431 match self {
432 SecurityLevel::Public => write!(f, "Public"),
433 SecurityLevel::Internal => write!(f, "Internal"),
434 SecurityLevel::Medium => write!(f, "Medium"),
435 SecurityLevel::Confidential => write!(f, "Confidential"),
436 SecurityLevel::Secret => write!(f, "Secret"),
437 SecurityLevel::TopSecret => write!(f, "Top Secret"),
438 }
439 }
440}
441
442impl std::fmt::Display for Permission {
443 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
444 match self {
445 Permission::Read => write!(f, "Read"),
446 Permission::Write => write!(f, "Write"),
447 Permission::Execute => write!(f, "Execute"),
448 Permission::Admin => write!(f, "Admin"),
449 Permission::Encrypt => write!(f, "Encrypt"),
450 Permission::Decrypt => write!(f, "Decrypt"),
451 Permission::Compress => write!(f, "Compress"),
452 Permission::Decompress => write!(f, "Decompress"),
453 Permission::Custom(name) => write!(f, "Custom({})", name),
454 }
455 }
456}