- Add complete dark mode system with theme context and toggle - Implement dark mode toggle component in navigation menu - Add client-side routing with SSR-safe signal handling - Fix language selector styling for better dark mode compatibility - Add documentation system with mdBook integration - Improve navigation menu with proper external/internal link handling - Add comprehensive project documentation and configuration - Enhance theme system with localStorage persistence - Fix arena panic issues during server-side rendering - Add proper TypeScript configuration and build optimizations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
23 KiB
RBAC (Role-Based Access Control) System for Rustelo
🔧 Optional Feature - This document provides a comprehensive guide to the optional RBAC system for the Rustelo framework. RBAC is disabled by default and can be enabled via configuration flags to provide fine-grained access control for databases, files, and content based on user roles, categories, and tags.
Table of Contents
- Overview
- Quick Start
- Feature Flags
- Core Concepts
- System Architecture
- Configuration
- Database Schema
- API Usage
- Middleware Integration
- Examples
- Best Practices
- Troubleshooting
Overview
⚡ RBAC is an optional feature that can be enabled when you need advanced access control beyond basic role-based authentication. When disabled (default), Rustelo uses a simple but effective role-based system (Admin, Moderator, User, Guest).
When enabled, the RBAC system provides hierarchical access control that goes beyond simple role-based permissions:
- 🔒 Optional by Design: Enable only what you need
- 📊 Multi-layered Access Control: Users, roles, categories, and tags
- 🎯 Resource-Specific Permissions: Database, file, directory, content, and API access
- ⚙️ Flexible Configuration: TOML files and database storage
- ⚡ Performance Optimization: Built-in caching and audit logging
- 🔧 Middleware Integration: Seamless integration with Axum middleware
- 🔄 Graceful Fallback: Falls back to basic auth when disabled
Quick Start
Option 1: Use Basic Authentication (Default)
# No configuration needed - works out of the box
ENABLE_RBAC=false # This is the default
Option 2: Enable Basic RBAC
# Enable RBAC with categories
ENABLE_RBAC=true
ENABLE_RBAC_CATEGORIES=true
ENABLE_RBAC_CACHING=true
Option 3: Enable Full RBAC
# Enable all RBAC features
ENABLE_RBAC=true
ENABLE_RBAC_DATABASE=true
ENABLE_RBAC_FILES=true
ENABLE_RBAC_CONTENT=true
ENABLE_RBAC_CATEGORIES=true
ENABLE_RBAC_TAGS=true
ENABLE_RBAC_CACHING=true
ENABLE_RBAC_AUDIT=true
Feature Flags
RBAC is controlled by environment variables. All features are disabled by default:
Core RBAC
ENABLE_RBAC=false- Master switch for RBAC system
Access Control Features
ENABLE_RBAC_DATABASE=false- Database access controlENABLE_RBAC_FILES=false- File system access controlENABLE_RBAC_CONTENT=false- Content management access controlENABLE_RBAC_API=false- API endpoint access control
User Organization Features
ENABLE_RBAC_CATEGORIES=false- User categories (departments, teams)ENABLE_RBAC_TAGS=false- User tags (attributes, clearance levels)
Advanced Features
ENABLE_RBAC_CACHING=false- Permission result cachingENABLE_RBAC_AUDIT=false- Access attempt loggingENABLE_RBAC_TOML_CONFIG=false- TOML configuration file supportENABLE_RBAC_HIERARCHICAL=false- Hierarchical permissionsENABLE_RBAC_DYNAMIC_RULES=false- Dynamic rule evaluation
Migration Path
- Start Simple: Use default authentication (no RBAC)
- Add Categories: Enable
ENABLE_RBAC=trueandENABLE_RBAC_CATEGORIES=true - Add Resources: Enable specific resource types as needed
- Add Advanced: Enable caching, audit logging, etc. for production
Core Concepts
Users
Users are the primary entities in the system. Each user has:
- Basic profile information
- Assigned roles
- Categories (organizational units)
- Tags (attributes/characteristics)
Roles
Predefined permission sets:
- Admin: Full system access
- Moderator: Content management access
- User: Basic application access
- Guest: Limited read-only access
- Custom: User-defined roles
Categories
Organizational units that group users by function:
admin- Administrative accesseditor- Content editing accessviewer- Read-only accessfinance- Financial data accesshr- Human resources accessit- Information technology access
Tags
Attributes that define user characteristics:
sensitive- Access to sensitive datapublic- Public data accessinternal- Internal data accessconfidential- Confidential data accessrestricted- Restricted accesstemporary- Temporary access
Resource Types
- Database: Database access control
- File: File system access control
- Directory: Directory-level access control
- Content: CMS content access control
- API: API endpoint access control
System Architecture
┌─────────────────────────────────────────────────────────────────┐
│ RBAC System Architecture │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ TOML Config │ │ Web Interface │ │ Database │ │
│ │ Loader │ │ │ │ Configuration │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │ │ │ │
│ └───────────────────────┼───────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────┼─────────────────────────────┐│
│ │ RBAC Service Layer │ ││
│ │ ┌─────────────────┐ ┌─────────▼─────────┐ ┌─────────────┐ ││
│ │ │ Permission │ │ Configuration │ │ Access │ ││
│ │ │ Cache │ │ Manager │ │ Evaluator │ ││
│ │ └─────────────────┘ └───────────────────┘ └─────────────┘ ││
│ └─────────────────────────────────────────────────────────────┘│
│ │ │
│ ┌─────────────────────────────────┼─────────────────────────────┐│
│ │ RBAC Repository │ ││
│ │ ┌─────────────────┐ ┌─────────▼─────────┐ ┌─────────────┐ ││
│ │ │ User Categories │ │ Access Rules │ │ Audit Log │ ││
│ │ │ & Tags │ │ Management │ │ Manager │ ││
│ │ └─────────────────┘ └───────────────────┘ └─────────────┘ ││
│ └─────────────────────────────────────────────────────────────┘│
│ │ │
│ ┌─────────────────────────────────┼─────────────────────────────┐│
│ │ Middleware Layer │ ││
│ │ ┌─────────────────┐ ┌─────────▼─────────┐ ┌─────────────┐ ││
│ │ │ Authentication │ │ Authorization │ │ Request │ ││
│ │ │ Middleware │ │ Middleware │ │ Context │ ││
│ │ └─────────────────┘ └───────────────────┘ └─────────────┘ ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘
Configuration
TOML Configuration
The RBAC system uses TOML files for configuration. Here's the structure:
[rbac]
cache_ttl_seconds = 300
[rbac.default_permissions]
Database = ["read_content"]
File = ["read_file:public/*"]
Content = ["read_content"]
[rbac.category_hierarchies]
admin = ["editor", "viewer"]
editor = ["viewer"]
[rbac.tag_hierarchies]
public = ["internal"]
internal = ["confidential"]
[[rbac.rules]]
id = "admin_full_access"
resource_type = "database"
resource_name = "*"
allowed_roles = ["admin"]
required_categories = ["admin"]
is_active = true
priority = 1000
Environment Variables
# Database configuration
DATABASE_URL=postgres://user:password@localhost:5432/database
# RBAC configuration
RBAC_CONFIG_PATH=config/rbac.toml
# JWT configuration
JWT_SECRET=your-super-secret-jwt-key
# Server configuration
SERVER_HOST=127.0.0.1
SERVER_PORT=3030
Database Schema
Core Tables
Users Table
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
User Categories
CREATE TABLE user_categories (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
parent_id UUID REFERENCES user_categories(id),
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
User Tags
CREATE TABLE user_tags (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
color VARCHAR(7),
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Access Rules
CREATE TABLE access_rules (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
resource_type VARCHAR(50) NOT NULL,
resource_name VARCHAR(500) NOT NULL,
action VARCHAR(50) NOT NULL,
priority INTEGER NOT NULL DEFAULT 0,
is_active BOOLEAN NOT NULL DEFAULT true,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Assignment Tables
User Category Assignments
CREATE TABLE user_category_assignments (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id),
category_id UUID NOT NULL REFERENCES user_categories(id),
assigned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ,
UNIQUE(user_id, category_id)
);
User Tag Assignments
CREATE TABLE user_tag_assignments (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id),
tag_id UUID NOT NULL REFERENCES user_tags(id),
assigned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ,
UNIQUE(user_id, tag_id)
);
API Usage
Authentication Endpoints
Login
POST /api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "password",
"remember_me": true
}
Register
POST /api/auth/register
Content-Type: application/json
{
"email": "user@example.com",
"username": "username",
"password": "password",
"display_name": "User Name"
}
RBAC Management Endpoints
Get RBAC Configuration
GET /api/rbac/config
Authorization: Bearer <token>
Update RBAC Configuration
POST /api/rbac/config
Authorization: Bearer <token>
Content-Type: application/json
{
"rules": [...],
"default_permissions": {...},
"cache_ttl_seconds": 300
}
Assign Category to User
POST /api/rbac/users/{user_id}/categories
Authorization: Bearer <token>
Content-Type: application/json
{
"category": "editor",
"expires_at": "2024-12-31T23:59:59Z"
}
Assign Tag to User
POST /api/rbac/users/{user_id}/tags
Authorization: Bearer <token>
Content-Type: application/json
{
"tag": "internal",
"expires_at": "2024-12-31T23:59:59Z"
}
Protected Resource Endpoints
Database Access
GET /api/database/analytics
Authorization: Bearer <token>
POST /api/database/analytics/query
Authorization: Bearer <token>
Content-Type: application/json
{
"query": "SELECT * FROM users WHERE active = true",
"parameters": []
}
File Access
GET /api/files/reports/financial/2024-q1.pdf
Authorization: Bearer <token>
POST /api/files/uploads/documents/report.pdf
Authorization: Bearer <token>
Content-Type: application/json
{
"operation": "write",
"content": "base64-encoded-content"
}
Content Access
GET /api/content/blog-posts/123
Authorization: Bearer <token>
POST /api/content/blog-posts/123
Authorization: Bearer <token>
Content-Type: application/json
{
"title": "Updated Title",
"content": "Updated content..."
}
Middleware Integration
Basic RBAC Middleware
use crate::auth::rbac_middleware::rbac_middleware;
let app = Router::new()
.route("/api/protected", get(protected_handler))
.layer(middleware::from_fn(rbac_middleware));
Database-Specific Middleware
use crate::auth::rbac_middleware::require_database_access;
let app = Router::new()
.route("/api/database/:db_name", get(database_handler))
.layer(middleware::from_fn(require_database_access(
"analytics".to_string(),
"read".to_string()
)));
Category-Based Middleware
use crate::auth::rbac_middleware::require_category_access;
let app = Router::new()
.route("/api/admin/users", get(admin_handler))
.layer(middleware::from_fn(require_category_access(
vec!["admin".to_string()]
)));
Tag-Based Middleware
use crate::auth::rbac_middleware::require_tag_access;
let app = Router::new()
.route("/api/sensitive/data", get(sensitive_handler))
.layer(middleware::from_fn(require_tag_access(
vec!["sensitive".to_string()]
)));
Examples
Example 1: Database Access Control
use crate::auth::{RBACService, rbac_middleware::*};
async fn database_handler(
Path(db_name): Path<String>,
State(rbac_service): State<Arc<RBACService>>,
) -> Result<Response, StatusCode> {
// The middleware has already checked access
// Your database logic here
Ok(Json(json!({
"database": db_name,
"status": "accessible"
})).into_response())
}
// Apply middleware
let app = Router::new()
.route("/api/database/:db_name", get(database_handler))
.layer(middleware::from_fn(rbac_middleware));
Example 2: File Access Control
async fn file_handler(
Path(file_path): Path<String>,
State(rbac_service): State<Arc<RBACService>>,
) -> Result<Response, StatusCode> {
// File access logic
let content = std::fs::read_to_string(&file_path)?;
Ok(Json(json!({
"file": file_path,
"content": content
})).into_response())
}
// Apply file-specific middleware
let app = Router::new()
.route("/api/files/*path", get(file_handler))
.layer(middleware::from_fn(require_file_access(
"reports/*".to_string(),
"read".to_string()
)));
Example 3: User Category Management
async fn assign_category(
Path(user_id): Path<Uuid>,
State(rbac_service): State<Arc<RBACService>>,
Json(request): Json<CategoryRequest>,
) -> Result<Response, StatusCode> {
rbac_service.assign_category_to_user(
user_id,
&request.category,
None,
request.expires_at
).await?;
Ok(Json(json!({
"success": true,
"message": "Category assigned successfully"
})).into_response())
}
Example 4: Custom Access Rules
async fn check_custom_access(
user: &User,
resource: &str,
action: &str,
rbac_service: &RBACService,
) -> Result<AccessResult> {
let context = AccessContext {
user: Some(user.clone()),
resource_type: ResourceType::Custom("api".to_string()),
resource_name: resource.to_string(),
action: action.to_string(),
additional_context: HashMap::new(),
};
rbac_service.check_access(&context).await
}
Best Practices
1. Principle of Least Privilege
- Grant minimum necessary permissions
- Use specific resource names instead of wildcards when possible
- Regularly review and audit user permissions
2. Hierarchical Categories
[rbac.category_hierarchies]
admin = ["editor", "viewer", "finance", "hr"]
editor = ["viewer"]
finance = ["viewer"]
3. Tag-Based Attributes
[rbac.tag_hierarchies]
public = ["internal"]
internal = ["confidential"]
confidential = ["restricted"]
4. Caching Strategy
- Use appropriate cache TTL (default: 5 minutes)
- Implement cache invalidation on permission changes
- Monitor cache hit rates
5. Audit Logging
- Log all access attempts
- Include sufficient context for security analysis
- Regular audit log review
6. Configuration Management
- Use version control for RBAC configuration files
- Implement configuration validation
- Test permission changes in staging environment
7. Error Handling
match rbac_service.check_access(&context).await {
Ok(AccessResult::Allow) => {
// Process request
}
Ok(AccessResult::Deny) => {
return Err(StatusCode::FORBIDDEN);
}
Ok(AccessResult::RequireAdditionalAuth) => {
return Err(StatusCode::UNAUTHORIZED);
}
Err(_) => {
return Err(StatusCode::INTERNAL_SERVER_ERROR);
}
}
Troubleshooting
Common Issues
1. Permission Denied Errors
Symptoms: Users getting 403 Forbidden errors Solutions:
- Check user's assigned categories and tags
- Verify access rules are active
- Check rule priority order
- Review cache expiration
2. Performance Issues
Symptoms: Slow response times Solutions:
- Optimize database queries
- Adjust cache TTL settings
- Review access rule complexity
- Use database indexes
3. Configuration Errors
Symptoms: RBAC rules not taking effect Solutions:
- Validate TOML syntax
- Check database synchronization
- Verify rule priorities
- Review resource name patterns
4. Cache Inconsistencies
Symptoms: Inconsistent access results Solutions:
- Clear permission cache
- Check cache expiration settings
- Verify cache invalidation logic
- Review concurrent access patterns
Debugging Commands
Check User Permissions
curl -X GET "http://localhost:3030/api/rbac/users/{user_id}/categories" \
-H "Authorization: Bearer <token>"
View Access Audit Log
curl -X GET "http://localhost:3030/api/rbac/audit/{user_id}" \
-H "Authorization: Bearer <token>"
Test Access Rules
curl -X POST "http://localhost:3030/api/users/{user_id}/access-check" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"database": "analytics", "action": "read"}'
Database Queries for Debugging
Check User Categories
SELECT u.username, uc.name as category_name
FROM users u
JOIN user_category_assignments uca ON u.id = uca.user_id
JOIN user_categories uc ON uca.category_id = uc.id
WHERE u.id = $1;
Check User Tags
SELECT u.username, ut.name as tag_name
FROM users u
JOIN user_tag_assignments uta ON u.id = uta.user_id
JOIN user_tags ut ON uta.tag_id = ut.id
WHERE u.id = $1;
Check Access Rules
SELECT ar.name, ar.resource_type, ar.resource_name, ar.priority
FROM access_rules ar
WHERE ar.resource_type = $1 AND ar.is_active = true
ORDER BY ar.priority DESC;
Migration Guide
From Simple Role-Based System
- Backup existing data
- Run RBAC migrations
- Convert existing roles to categories
- Create default access rules
- Test permission assignments
Configuration Migration
# Backup current configuration
cp config/auth.toml config/auth.toml.backup
# Create RBAC configuration
cp config/rbac.toml.example config/rbac.toml
# Edit configuration
nano config/rbac.toml
Performance Considerations
Database Optimization
- Indexes: Ensure proper indexing on frequently queried columns
- Connection Pooling: Use appropriate connection pool sizes
- Query Optimization: Optimize access rule queries
Caching Strategy
- Cache TTL: Balance between performance and consistency
- Cache Size: Monitor memory usage
- Cache Invalidation: Implement selective invalidation
Monitoring
- Access Patterns: Monitor frequent access patterns
- Performance Metrics: Track response times
- Error Rates: Monitor permission denial rates
Security Considerations
Data Protection
- Encryption: Encrypt sensitive data at rest
- Transport Security: Use HTTPS for all communications
- Token Management: Implement secure token handling
Access Control
- Regular Audits: Conduct regular permission audits
- Privilege Escalation: Monitor for privilege escalation attempts
- Anomaly Detection: Implement anomaly detection for access patterns
Compliance
- Audit Trails: Maintain comprehensive audit logs
- Data Retention: Implement appropriate data retention policies
- Privacy Controls: Respect user privacy requirements
Contributing
When contributing to the RBAC system:
- Follow Rust best practices
- Add comprehensive tests
- Update documentation
- Consider security implications
- Test with real-world scenarios
License
This RBAC system is part of the Rustelo framework and is licensed under the MIT License.