Rustelo/info/rbac_readme.md
Jesús Pérex 2f0f807331 feat: add dark mode functionality and improve navigation system
- 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>
2025-07-11 20:53:20 +01:00

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

  1. Overview
  2. Quick Start
  3. Feature Flags
  4. Core Concepts
  5. System Architecture
  6. Configuration
  7. Database Schema
  8. API Usage
  9. Middleware Integration
  10. Examples
  11. Best Practices
  12. 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 control
  • ENABLE_RBAC_FILES=false - File system access control
  • ENABLE_RBAC_CONTENT=false - Content management access control
  • ENABLE_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 caching
  • ENABLE_RBAC_AUDIT=false - Access attempt logging
  • ENABLE_RBAC_TOML_CONFIG=false - TOML configuration file support
  • ENABLE_RBAC_HIERARCHICAL=false - Hierarchical permissions
  • ENABLE_RBAC_DYNAMIC_RULES=false - Dynamic rule evaluation

Migration Path

  1. Start Simple: Use default authentication (no RBAC)
  2. Add Categories: Enable ENABLE_RBAC=true and ENABLE_RBAC_CATEGORIES=true
  3. Add Resources: Enable specific resource types as needed
  4. 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 access
  • editor - Content editing access
  • viewer - Read-only access
  • finance - Financial data access
  • hr - Human resources access
  • it - Information technology access

Tags

Attributes that define user characteristics:

  • sensitive - Access to sensitive data
  • public - Public data access
  • internal - Internal data access
  • confidential - Confidential data access
  • restricted - Restricted access
  • temporary - 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

  1. Backup existing data
  2. Run RBAC migrations
  3. Convert existing roles to categories
  4. Create default access rules
  5. 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

  1. Indexes: Ensure proper indexing on frequently queried columns
  2. Connection Pooling: Use appropriate connection pool sizes
  3. Query Optimization: Optimize access rule queries

Caching Strategy

  1. Cache TTL: Balance between performance and consistency
  2. Cache Size: Monitor memory usage
  3. Cache Invalidation: Implement selective invalidation

Monitoring

  1. Access Patterns: Monitor frequent access patterns
  2. Performance Metrics: Track response times
  3. Error Rates: Monitor permission denial rates

Security Considerations

Data Protection

  1. Encryption: Encrypt sensitive data at rest
  2. Transport Security: Use HTTPS for all communications
  3. Token Management: Implement secure token handling

Access Control

  1. Regular Audits: Conduct regular permission audits
  2. Privilege Escalation: Monitor for privilege escalation attempts
  3. Anomaly Detection: Implement anomaly detection for access patterns

Compliance

  1. Audit Trails: Maintain comprehensive audit logs
  2. Data Retention: Implement appropriate data retention policies
  3. Privacy Controls: Respect user privacy requirements

Contributing

When contributing to the RBAC system:

  1. Follow Rust best practices
  2. Add comprehensive tests
  3. Update documentation
  4. Consider security implications
  5. Test with real-world scenarios

License

This RBAC system is part of the Rustelo framework and is licensed under the MIT License.