role-system

Crates.iorole-system
lib.rsrole-system
version1.1.1
created_at2025-07-13 01:50:06.441248+00
updated_at2025-08-19 18:12:36.442186+00
descriptionA flexible and powerful role-based access control (RBAC) library for Rust applications
homepage
repositoryhttps://github.com/ciresnave/role-system
max_upload_size
id1749891
size668,667
CireSnave (ciresnave)

documentation

README

Role System

A flexible and powerful role-based access control (RBAC) library for Rust applications.

Crates.io Documentation License Security Audit CI Coverage

🚀 Production-ready RBAC system with hierarchical roles, conditional permissions, and async support.

Features

✨ Core Features

  • Hierarchical Roles with inheritance
  • Fine-grained Permissions with wildcards
  • Dynamic Role Management and elevation
  • Context-based Conditional Permissions
  • Thread-safe Concurrent Access

🔒 Security

  • Fail-safe Default Deny
  • Comprehensive Audit Logging
  • Input Validation and Sanitization
  • Security-first Design

âš¡ Performance

🔧 Integration

📚 Documentation

  • Comprehensive API Docs

  • Versioning Policy

  • Security Policy

  • Contributing Guide

  • Hierarchical Roles: Support for role inheritance and hierarchy

  • Fine-grained Permissions: Detailed permission control with action and resource type specifications

  • Dynamic Role Management: Runtime role assignment, removal, and temporary elevation

  • Conditional Permissions: Context-based permission validation

  • Multiple Subject Types: Support for users, groups, services, and devices

  • Thread-safe: Built with concurrent access in mind using DashMap

  • Async Support: Optional async/await support with Tokio

  • Persistence: Optional serialization support with Serde

  • Audit Logging: Optional audit trail with tracing

  • Caching: Built-in permission caching for performance

  • Flexible Storage: Pluggable storage backends (memory, file, custom)

Quick Start

Add this to your Cargo.toml:

[dependencies]
role-system = "0.1"

âš¡ 5-Minute Integration

For web applications, check out our comprehensive middleware examples that show how to integrate with popular frameworks in just 5-10 lines of code:

  • Actix Web - Custom middleware with Transform trait
  • Axum - Type-safe extractors and layers
  • Rocket - Request guards and fairings
  • Warp - Filter-based authorization

Each example includes JWT authentication, role-based authorization, and production-ready error handling.

Basic Example

use role_system::{RoleSystem, Role, Permission, Subject, Resource};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize the role system
    let mut role_system = RoleSystem::new();
    
    // Define permissions
    let read_docs = Permission::new("read", "documents");
    let write_docs = Permission::new("write", "documents");
    
    // Define roles with permissions
    let reader = Role::new("reader").add_permission(read_docs.clone());
    let writer = Role::new("writer")
        .add_permission(read_docs.clone())
        .add_permission(write_docs.clone());
    
    // Register roles
    role_system.register_role(reader)?;
    role_system.register_role(writer)?;
    
    // Create hierarchical roles (writer inherits from reader)
    role_system.add_role_inheritance("writer", "reader")?;
    
    // Assign roles to subjects
    let user = Subject::new("user1");
    role_system.assign_role(&user, "reader")?;
    
    // Check permissions
    let document = Resource::new("doc1", "documents");
    let can_read = role_system.check_permission(&user, "read", &document)?;
    let can_write = role_system.check_permission(&user, "write", &document)?;
    
    println!("User can read: {}", can_read);   // true
    println!("User can write: {}", can_write); // false
    
    Ok(())
}

Advanced Example with Conditional Permissions

use role_system::{RoleSystem, Role, Permission, Subject, Resource};
use std::collections::HashMap;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut role_system = RoleSystem::new();
    
    // Create a conditional permission that only works during business hours
    let conditional_print = Permission::with_condition("print", "documents", |context| {
        context.get("time") == Some(&"business_hours".to_string()) && 
        context.get("location") == Some(&"office".to_string())
    });
    
    let office_worker = Role::new("office_worker")
        .add_permission(Permission::new("read", "documents"))
        .add_permission(conditional_print);
    
    role_system.register_role(office_worker)?;
    
    let user = Subject::new("employee1");
    role_system.assign_role(&user, "office_worker")?;
    
    let document = Resource::new("report.pdf", "documents");
    
    // Create context
    let mut context = HashMap::new();
    context.insert("time".to_string(), "business_hours".to_string());
    context.insert("location".to_string(), "office".to_string());
    
    // Check permission with context
    let can_print = role_system.check_permission_with_context(
        &user, "print", &document, &context
    )?;
    
    println!("Can print during business hours at office: {}", can_print); // true
    
    // Change context - now at home
    context.insert("location".to_string(), "home".to_string());
    let can_print_home = role_system.check_permission_with_context(
        &user, "print", &document, &context
    )?;
    
    println!("Can print from home: {}", can_print_home); // false
    
    Ok(())
}

Async Example

use role_system::{
    async_support::{AsyncRoleSystem, AsyncRoleSystemBuilder},
    Role, Permission, Subject, Resource,
    storage::MemoryStorage,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create async role system
    let async_system = AsyncRoleSystemBuilder::<MemoryStorage>::new()
        .enable_caching(true)
        .build();
    
    // Define role and permissions
    let admin_role = Role::new("admin")
        .add_permission(Permission::super_admin()); // Grants access to everything
    
    async_system.register_role(admin_role).await?;
    
    // Assign role to user
    let admin_user = Subject::user("admin1");
    async_system.assign_role(&admin_user, "admin").await?;
    
    // Check permission
    let sensitive_data = Resource::new("secrets.txt", "files");
    let can_access = async_system
        .check_permission(&admin_user, "read", &sensitive_data)
        .await?;
    
    println!("Admin can access sensitive data: {}", can_access); // true
    
    Ok(())
}

Features and Configuration

Feature Flags

  • async (default): Enables async/await support with Tokio
  • persistence: Enables serialization support with Serde
  • audit: Enables audit logging with tracing
[dependencies]
role-system = { version = "0.1", features = ["persistence", "audit"] }

Storage Backends

The role system supports multiple storage backends:

Memory Storage (Default)

use role_system::{RoleSystem, storage::MemoryStorage};

let role_system = RoleSystem::<MemoryStorage>::new();

File Storage (with persistence feature)

use role_system::{RoleSystem, storage::FileStorage, core::RoleSystemConfig};

let storage = FileStorage::new("./roles.json")?;
let config = RoleSystemConfig::default();
let role_system = RoleSystem::with_storage(storage, config);

Custom Storage

Implement the Storage trait to create your own storage backend:

use role_system::storage::Storage;

struct DatabaseStorage {
    // Your database connection
}

impl Storage for DatabaseStorage {
    fn store_role(&mut self, role: Role) -> Result<()> {
        // Store role in database
    }
    
    fn get_role(&self, name: &str) -> Result<Option<Role>> {
        // Retrieve role from database
    }
    
    // ... implement other methods
}

Architecture

Core Components

  • RoleSystem: Main entry point for role-based access control
  • Role: Represents a collection of permissions that can be assigned to subjects
  • Permission: Represents an action that can be performed on a resource type
  • Subject: Represents an entity that can have roles (user, group, service, device)
  • Resource: Represents something that can be accessed or acted upon
  • Storage: Pluggable storage backend for persisting role data

Permission Model

Permissions follow the format action:resource_type:

  • read:documents - Read access to documents
  • write:users - Write access to user records
  • admin:* - Admin access to all resource types
  • *:documents - All actions on documents

Role Hierarchy

Roles can inherit from other roles, creating a hierarchy:

// admin inherits all permissions from writer
role_system.add_role_inheritance("admin", "writer")?;

// writer inherits all permissions from reader
role_system.add_role_inheritance("writer", "reader")?;

Subject Types

The system supports different types of subjects:

  • User: Human users
  • Group: Collections of users
  • Service: Applications or services
  • Device: IoT devices or systems
  • Custom: User-defined subject types

Temporary Role Elevation

Users can be temporarily granted additional roles:

// Elevate user to admin role for 1 hour
role_system.elevate_role(&user, "admin", Some(Duration::from_secs(3600)))?;

Performance

  • Caching: Built-in permission caching to avoid repeated calculations
  • Thread-safe: Uses DashMap for concurrent access without locks
  • Efficient hierarchy: Smart hierarchy traversal with cycle detection
  • Lazy evaluation: Permissions are only calculated when needed

Security Considerations

  • Fail-safe defaults: Permissions are denied by default
  • Explicit grants: All permissions must be explicitly granted
  • Hierarchy validation: Prevents circular dependencies in role hierarchy
  • Audit logging: Optional comprehensive audit trail
  • Context validation: Conditional permissions based on runtime context

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License

This project is licensed under either of

at your option.

Acknowledgments

This library was extracted and evolved from the role management system originally developed for the COAD (Code Organization and Analysis Dashboard) project, providing a standalone, reusable RBAC solution for the Rust ecosystem.

Commit count: 7

cargo fmt