Skip to main content

oxios_kernel/kernel_handle/
security_api.rs

1//! Security API — authentication, audit trail, RBAC, approvals.
2
3use crate::access_manager::{
4    AccessManager, AgentPermissions, ApprovalStatus, PendingApproval, PermissionUpdate,
5};
6use crate::audit_trail::{AuditAction, AuditEntry, AuditTrail};
7use crate::auth::AuthManager;
8use crate::state_store::StateStore;
9use std::sync::Arc;
10
11/// Security system calls.
12pub struct SecurityApi {
13    pub(crate) auth_manager: Arc<parking_lot::Mutex<AuthManager>>,
14    pub(crate) audit_trail: Arc<AuditTrail>,
15    pub(crate) access_manager: Arc<parking_lot::Mutex<AccessManager>>,
16    pub(crate) state_store: Arc<StateStore>,
17}
18
19impl SecurityApi {
20    /// Create a new SecurityApi.
21    pub fn new(
22        auth_manager: Arc<parking_lot::Mutex<AuthManager>>,
23        audit_trail: Arc<AuditTrail>,
24        access_manager: Arc<parking_lot::Mutex<AccessManager>>,
25        state_store: Arc<StateStore>,
26    ) -> Self {
27        Self {
28            auth_manager,
29            audit_trail,
30            access_manager,
31            state_store,
32        }
33    }
34    /// Audit an action.
35    pub fn audit(&self, actor: &str, action: AuditAction, resource: &str) -> String {
36        self.audit_trail
37            .append(actor.to_string(), action, resource.to_string())
38    }
39
40    /// Verify audit chain integrity.
41    pub fn verify_chain(&self) -> anyhow::Result<bool> {
42        self.audit_trail
43            .verify()
44            .map_err(|e| anyhow::anyhow!("audit verify failed: {:?}", e))
45    }
46
47    /// Query audit entries by sequence range.
48    pub fn query_audit(&self, from_seq: u64, to_seq: u64) -> Vec<AuditEntry> {
49        self.audit_trail.entries(from_seq, to_seq)
50    }
51
52    /// Query audit by agent.
53    pub fn query_audit_by_agent(&self, agent_id: &str) -> Vec<AuditEntry> {
54        self.audit_trail.by_agent(agent_id)
55    }
56
57    /// Get audit entry count.
58    pub fn audit_count(&self) -> usize {
59        self.audit_trail.len()
60    }
61
62    /// Flush audit trail to disk and commit to git.
63    ///
64    /// Persists all in-memory audit entries to the state store,
65    /// then commits the audit file to git for versioning.
66    pub fn flush(&self, git: &crate::git_layer::GitLayer) -> anyhow::Result<()> {
67        // 1. Persist entries to state store
68        self.audit_trail.flush(&self.state_store)?;
69        // 2. Commit to git
70        if git.is_enabled() {
71            let _ = git.commit_file("audit", "audit trail flush");
72        }
73        Ok(())
74    }
75
76    /// Validate a bearer token.
77    pub fn validate_token(&self, token: &str) -> bool {
78        self.auth_manager.lock().validate(token)
79    }
80
81    /// Get audit log entries from access manager.
82    pub fn get_audit_log(&self) -> Vec<crate::access_manager::AuditEntry> {
83        self.access_manager.lock().audit_log().to_vec()
84    }
85
86    /// Get permissions for an agent.
87    pub fn get_permissions(&self, agent: &str) -> Option<AgentPermissions> {
88        self.access_manager.lock().get_permissions(agent).cloned()
89    }
90
91    /// Ensure permissions exist for an agent (get or create).
92    pub fn ensure_permissions(&self, agent: &str) -> AgentPermissions {
93        self.access_manager
94            .lock()
95            .get_or_create_permissions(agent)
96            .clone()
97    }
98
99    /// Update permissions for an agent.
100    pub fn update_permissions(&self, agent: &str, update: PermissionUpdate) -> anyhow::Result<()> {
101        self.access_manager.lock().update_permissions(agent, update)
102    }
103
104    /// Log an audit action.
105    pub fn log_action(&self, agent_name: &str, action: &str, resource: &str) {
106        let mut am = self.access_manager.lock();
107        am.log_access(agent_name, action, resource, true, None);
108    }
109
110    /// List all pending approvals.
111    pub fn list_approvals(&self) -> Vec<(PendingApproval, ApprovalStatus)> {
112        self.access_manager
113            .lock()
114            .rbac_manager()
115            .all_approvals()
116            .to_vec()
117    }
118
119    /// Approve a pending request.
120    pub fn approve(&self, id: uuid::Uuid) -> bool {
121        self.access_manager.lock().rbac_manager_mut().approve(id)
122    }
123
124    /// Reject a pending request.
125    pub fn reject(&self, id: uuid::Uuid) -> bool {
126        self.access_manager.lock().rbac_manager_mut().reject(id)
127    }
128}