pub struct PermissionManager {
roles: Arc<RwLock<HashMap<String, Role>>>,
permissions: Arc<RwLock<HashMap<String, Permission>>>,
audit_log: Arc<RwLock<Vec<SecurityEvent>>>,
}Expand description
Permission manager for IPC operations
This is the main security enforcement structure for the IPC layer. It maintains role and permission definitions, validates access requests, and logs security events for auditing.
§Permission Flow
IPC Message arrives
|
| validate_permission(operation, context)
v
Check if operation requires permissions
|
| Yes -> Get required permissions
v
Check user permissions (direct + role-based)
|
| Has all required permissions?
v
Yes -> Log AccessGranted -> Allow operation
No -> Log PermissionDenied -> Deny operation§Default Roles
The PermissionManager initializes with three default roles:
- user: Read-only access to files, configuration, and storage
- developer: Read/write access to files and storage, configuration read
- admin: Full access including system operations and configuration updates
§Default Permissions
Standard permissions include:
- file.read, file.write
- config.read, config.update
- storage.read, storage.write
- system.external
Fields§
§roles: Arc<RwLock<HashMap<String, Role>>>Role definitions with associated permissions
permissions: Arc<RwLock<HashMap<String, Permission>>>Permission definitions with descriptions
audit_log: Arc<RwLock<Vec<SecurityEvent>>>Security audit log (limited to last 1000 events)
Implementations§
Source§impl PermissionManager
impl PermissionManager
Sourcepub async fn validate_permission(
&self,
operation: &str,
context: &SecurityContext,
) -> Result<(), String>
pub async fn validate_permission( &self, operation: &str, context: &SecurityContext, ) -> Result<(), String>
Validate permission for an operation
This method checks if the given security context has sufficient permissions to perform the specified operation.
§Parameters
operation: The operation being attempted (e.g., “file:write”, “config:update”)context: The security context containing user information
§Returns
Ok(())if the operation is allowedErr(String)with reason if denied
§Example
let context = SecurityContext::ipc_default();
permission_manager.validate_permission("file:read", &context).await?;Sourceasync fn get_required_permissions(&self, operation: &str) -> Vec<String>
async fn get_required_permissions(&self, operation: &str) -> Vec<String>
Get required permissions for an operation
This method defines which permissions are required for which operations. Operations not in the mapping require no special permissions by default.
§Operation Permission Mapping
| Operation | Required Permissions |
|---|---|
| file:write | file.write |
| file:delete | file.write |
| configuration:update | config.update |
| storage:set | storage.write |
| native:openExternal | system.external |
Sourceasync fn get_role_permissions(&self, role_name: &str) -> Vec<String>
async fn get_role_permissions(&self, role_name: &str) -> Vec<String>
Get permissions for a role
Sourcepub async fn log_security_event(&self, event: SecurityEvent)
pub async fn log_security_event(&self, event: SecurityEvent)
Log security event
Sourcepub async fn get_audit_log(&self, limit: usize) -> Vec<SecurityEvent>
pub async fn get_audit_log(&self, limit: usize) -> Vec<SecurityEvent>
Get security audit log
Returns the most recent security events up to the specified limit.
Sourcepub async fn initialize_defaults(&self)
pub async fn initialize_defaults(&self)
Initialize default roles and permissions
This method sets up the standard RBAC structure with three default roles and their associated permissions.
Sourcepub async fn add_permission(&self, permission: Permission)
pub async fn add_permission(&self, permission: Permission)
Add a custom permission
Sourcepub async fn clear_audit_log(&self)
pub async fn clear_audit_log(&self)
Clear the audit log
Auto Trait Implementations§
impl Freeze for PermissionManager
impl !RefUnwindSafe for PermissionManager
impl Send for PermissionManager
impl Sync for PermissionManager
impl Unpin for PermissionManager
impl !UnwindSafe for PermissionManager
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].