| Crates.io | role-system |
| lib.rs | role-system |
| version | 1.1.1 |
| created_at | 2025-07-13 01:50:06.441248+00 |
| updated_at | 2025-08-19 18:12:36.442186+00 |
| description | A flexible and powerful role-based access control (RBAC) library for Rust applications |
| homepage | |
| repository | https://github.com/ciresnave/role-system |
| max_upload_size | |
| id | 1749891 |
| size | 668,667 |
A flexible and powerful role-based access control (RBAC) library for Rust applications.
🚀 Production-ready RBAC system with hierarchical roles, conditional permissions, and async support.
✨ Core Features
🔒 Security
âš¡ Performance
🔧 Integration
📚 Documentation
Comprehensive API Docs
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)
Add this to your Cargo.toml:
[dependencies]
role-system = "0.1"
For web applications, check out our comprehensive middleware examples that show how to integrate with popular frameworks in just 5-10 lines of code:
Each example includes JWT authentication, role-based authorization, and production-ready error handling.
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(())
}
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(())
}
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(())
}
async (default): Enables async/await support with Tokiopersistence: Enables serialization support with Serdeaudit: Enables audit logging with tracing[dependencies]
role-system = { version = "0.1", features = ["persistence", "audit"] }
The role system supports multiple storage backends:
use role_system::{RoleSystem, storage::MemoryStorage};
let role_system = RoleSystem::<MemoryStorage>::new();
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);
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
}
Permissions follow the format action:resource_type:
read:documents - Read access to documentswrite:users - Write access to user recordsadmin:* - Admin access to all resource types*:documents - All actions on documentsRoles 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")?;
The system supports different types of subjects:
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)))?;
DashMap for concurrent access without locksContributions 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.
This project is licensed under either of
at your option.
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.