Skip to main content

a3s_code_core/security/
mod.rs

1//! Security Module
2//!
3//! Provides a trait-based security interface for A3S Code sessions.
4//! External consumers implement `SecurityProvider` to plug in their own
5//! security logic (sanitization, taint tracking, injection detection, etc.).
6
7pub mod config;
8pub mod default;
9
10pub use config::{RedactionStrategy, SecurityConfig, SensitivityLevel};
11pub use default::{DefaultSecurityConfig, DefaultSecurityProvider, SensitivePattern};
12
13use crate::hooks::HookEngine;
14
15/// Trait for pluggable security providers.
16///
17/// Implement this trait to provide custom security logic for sessions.
18/// The default `NoOpSecurityProvider` passes everything through unchanged.
19pub trait SecurityProvider: Send + Sync {
20    /// Classify and register sensitive data found in input text
21    fn taint_input(&self, _text: &str) {}
22
23    /// Sanitize output text by redacting sensitive data.
24    /// Returns the sanitized text.
25    fn sanitize_output(&self, text: &str) -> String {
26        text.to_string()
27    }
28
29    /// Securely wipe all session security state
30    fn wipe(&self) {}
31
32    /// Register security hooks with the given engine
33    fn register_hooks(&self, _hook_engine: &HookEngine) {}
34
35    /// Unregister all hooks from the engine
36    fn teardown(&self, _hook_engine: &HookEngine) {}
37}
38
39/// No-op security provider (default when security is disabled)
40pub struct NoOpSecurityProvider;
41
42impl SecurityProvider for NoOpSecurityProvider {}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn test_noop_provider_passthrough() {
50        let provider = NoOpSecurityProvider;
51        provider.taint_input("SSN: 123-45-6789");
52        let output = provider.sanitize_output("SSN: 123-45-6789");
53        assert_eq!(output, "SSN: 123-45-6789");
54    }
55
56    #[test]
57    fn test_noop_provider_wipe() {
58        let provider = NoOpSecurityProvider;
59        provider.wipe(); // Should not panic
60    }
61
62    #[test]
63    fn test_noop_provider_hooks() {
64        let engine = HookEngine::new();
65        let provider = NoOpSecurityProvider;
66        provider.register_hooks(&engine);
67        provider.teardown(&engine);
68        assert_eq!(engine.hook_count(), 0);
69    }
70}