streamflow/docs/RBAC_IMPLEMENTATION.md
2025-12-17 00:42:43 +00:00

20 KiB

Role-Based Access Control (RBAC) Implementation

Overview

This document describes the comprehensive Role-Based Access Control (RBAC) system implemented in StreamFlow, following the Principle of Least Privilege. The RBAC system provides granular permission management, ensuring users have only the minimum access rights needed to perform their functions.

Table of Contents

  1. Architecture
  2. Permission System
  3. Default Roles
  4. API Reference
  5. Frontend Integration
  6. Security Considerations
  7. Audit Logging
  8. Migration Guide
  9. Best Practices

Architecture

Components

The RBAC system consists of four main components:

  1. RBAC Middleware (backend/middleware/rbac.js)

    • Permission checking logic
    • Role initialization
    • Permission caching
    • Audit logging utilities
  2. RBAC Routes (backend/routes/rbac.js)

    • Role CRUD operations
    • User role assignment
    • Permission queries
    • Audit log retrieval
  3. Database Schema

    • roles table: Role definitions and permissions
    • permission_audit_log table: Audit trail for permission changes
  4. RBAC Dashboard (frontend/src/components/RBACDashboard.jsx)

    • Visual role management interface
    • User role assignment UI
    • Permission viewer
    • Audit log browser

Database Schema

Roles Table

CREATE TABLE roles (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  role_key TEXT UNIQUE NOT NULL,
  name TEXT NOT NULL,
  description TEXT,
  permissions TEXT NOT NULL, -- JSON array
  is_system_role BOOLEAN DEFAULT 0,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)

Permission Audit Log Table

CREATE TABLE permission_audit_log (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  user_id INTEGER NOT NULL,
  action TEXT NOT NULL,
  target_type TEXT NOT NULL,
  target_id INTEGER,
  old_value TEXT, -- JSON
  new_value TEXT, -- JSON
  ip_address TEXT,
  user_agent TEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
)

Permission System

Permission Categories

The system defines 70+ granular permissions across 7 categories:

1. User Management

  • users.view - View user list and details
  • users.create - Create new users
  • users.edit - Edit existing users
  • users.delete - Delete users
  • users.manage_roles - Assign and modify user roles
  • users.unlock - Unlock locked user accounts
  • users.reset_password - Reset user passwords

2. Session Management

  • sessions.view_own - View own active sessions
  • sessions.view_all - View all user sessions
  • sessions.terminate_own - Terminate own sessions
  • sessions.terminate_any - Terminate any user session
  • sessions.view_stats - View session statistics

3. Content Management

  • playlists.* - Create, view, edit, delete, import playlists
  • channels.* - View, edit channels, manage logos
  • favorites.* - View and manage favorites
  • history.* - View own/all history, delete history

4. System & Settings

  • settings.* - View and edit application settings
  • stats.* - View analytics and detailed statistics
  • backup.* - Create, restore, delete, download backups

5. Security Management

  • security.view_sessions - View security session dashboard
  • security.view_csp - View CSP violation dashboard
  • security.manage_2fa - Manage two-factor authentication
  • security.view_audit - View audit logs

6. Search & Discovery

  • search.use - Use search functionality
  • search.admin - Search users and system settings

Permission Checking

Middleware Functions

requirePermission(permissions)

  • Requires ANY of the specified permissions
  • Usage: requirePermission('users.view')
  • Usage: requirePermission(['users.view', 'users.edit'])

requireAllPermissions(permissions)

  • Requires ALL of the specified permissions
  • Usage: requireAllPermissions(['users.view', 'users.manage_roles'])

hasPermission(userId, permission)

  • Programmatic permission check
  • Returns: Promise

hasAnyPermission(userId, permissionList)

  • Check if user has ANY permission
  • Returns: Promise

hasAllPermissions(userId, permissionList)

  • Check if user has ALL permissions
  • Returns: Promise

Example Usage in Routes

const { requirePermission, requireAllPermissions } = require('../middleware/rbac');

// Require ANY of the specified permissions
router.get('/users', 
  authenticate, 
  requirePermission('users.view'),
  (req, res) => {
    // Only users with 'users.view' permission can access
  }
);

// Require ALL specified permissions
router.post('/roles',
  authenticate,
  requireAllPermissions(['users.manage_roles', 'users.create']),
  (req, res) => {
    // Only users with BOTH permissions can access
  }
);

Permission Caching

  • Permissions are cached for 5 minutes to reduce database queries
  • Cache is automatically cleared when:
    • User role is changed
    • Role permissions are updated
    • Custom roles are created/deleted
  • Manual cache control available:
    • clearUserPermissionCache(userId) - Clear specific user
    • clearAllPermissionCache() - Clear entire cache

Default Roles

Admin

Full system access - All permissions enabled

  • Complete control over users, roles, and permissions
  • Access to all security dashboards
  • Backup and restore capabilities
  • System statistics and monitoring

User Count: Restricted (last admin cannot be deleted)

Moderator

Content management and user support

Key Permissions:

  • View users (but not manage)
  • Full content management (playlists, channels)
  • Manage all user history
  • View detailed statistics
  • Manage own sessions and 2FA

Restrictions:

  • Cannot create/edit/delete users
  • Cannot manage roles or permissions
  • Cannot access backups
  • Cannot view audit logs

User

Standard user with content access

Key Permissions:

  • Manage own playlists and favorites
  • Upload custom channel logos
  • View and delete own history
  • Manage own sessions
  • Own 2FA management

Restrictions:

  • Cannot view other users' data
  • Cannot access admin features
  • Cannot view statistics
  • Limited to own resources

Viewer

Read-only access for content viewing

Key Permissions:

  • View playlists and channels
  • Manage favorites
  • View and delete own history
  • Basic search functionality
  • Own session management

Restrictions:

  • Cannot create or import playlists
  • Cannot upload logos
  • Cannot modify settings
  • Minimal permissions (principle of least privilege)

API Reference

Base URL

All RBAC endpoints are under /api/rbac

Endpoints

Get All Permissions

GET /api/rbac/permissions
Authorization: Bearer {token}
Required Permission: users.manage_roles

Response:

{
  "permissions": [
    { "key": "users.view", "description": "View user list and details" },
    ...
  ],
  "categories": {
    "User Management": ["users.view", "users.create", ...],
    ...
  }
}

Get All Roles

GET /api/rbac/roles
Authorization: Bearer {token}
Required Permission: users.view

Response:

[
  {
    "id": 1,
    "role_key": "admin",
    "name": "Administrator",
    "description": "Full system access",
    "permissions": ["users.view", "users.create", ...],
    "is_system_role": true,
    "created_at": "2024-01-01T00:00:00.000Z",
    "updated_at": "2024-01-01T00:00:00.000Z"
  },
  ...
]

Get Single Role

GET /api/rbac/roles/:roleKey
Authorization: Bearer {token}
Required Permission: users.view

Create Custom Role

POST /api/rbac/roles
Authorization: Bearer {token}
Required Permissions: users.manage_roles AND users.create
Content-Type: application/json

{
  "role_key": "content_manager",
  "name": "Content Manager",
  "description": "Manages playlists and channels",
  "permissions": [
    "playlists.view",
    "playlists.create",
    "playlists.edit",
    "channels.view",
    "channels.edit"
  ]
}

Response: 201 Created with role object

Validation:

  • role_key: lowercase letters and underscores only, 2-50 chars
  • name: 2-100 chars
  • description: max 500 chars (optional)
  • permissions: array of valid permission keys

Update Role

PATCH /api/rbac/roles/:roleKey
Authorization: Bearer {token}
Required Permission: users.manage_roles
Content-Type: application/json

{
  "name": "Updated Name",
  "description": "Updated description",
  "permissions": [...]
}

Restrictions:

  • Cannot modify system roles (admin, moderator, user, viewer)
  • All fields optional

Delete Custom Role

DELETE /api/rbac/roles/:roleKey
Authorization: Bearer {token}
Required Permission: users.manage_roles

Restrictions:

  • Cannot delete system roles
  • Cannot delete roles assigned to users

Get User's Permissions

GET /api/rbac/my-permissions
Authorization: Bearer {token}

Response:

{
  "role": "user",
  "role_name": "Regular User",
  "role_description": "Standard user with content access",
  "permissions": ["playlists.view", "playlists.create", ...],
  "permission_details": [
    {
      "key": "playlists.view",
      "description": "View playlists"
    },
    ...
  ]
}

Assign Role to User

POST /api/rbac/users/:userId/role
Authorization: Bearer {token}
Required Permission: users.manage_roles
Content-Type: application/json

{
  "role": "moderator"
}

Restrictions:

  • Cannot modify own role
  • Role must exist

Get Audit Log

GET /api/rbac/audit-log?action=role_created&userId=5&limit=50&offset=0
Authorization: Bearer {token}
Required Permission: security.view_audit

Query Parameters:

  • action: Filter by action type (optional)
  • userId: Filter by user ID (optional)
  • targetType: Filter by target type (optional)
  • limit: Records per page (default: 100)
  • offset: Pagination offset (default: 0)

Response:

{
  "logs": [
    {
      "id": 1,
      "user_id": 1,
      "username": "admin",
      "action": "role_created",
      "target_type": "role",
      "target_id": 5,
      "old_value": null,
      "new_value": {
        "role_key": "content_manager",
        "name": "Content Manager",
        "permissions": [...]
      },
      "ip_address": "192.168.1.100",
      "user_agent": "Mozilla/5.0...",
      "created_at": "2024-01-01T12:00:00.000Z"
    },
    ...
  ],
  "limit": 50,
  "offset": 0
}

Get RBAC Statistics

GET /api/rbac/stats
Authorization: Bearer {token}
Required Permission: security.view_audit

Response:

{
  "role_distribution": [
    {
      "name": "Administrator",
      "role_key": "admin",
      "user_count": 2
    },
    ...
  ],
  "recent_actions": [
    {
      "action": "role_assigned",
      "count": 15
    },
    ...
  ],
  "total_permissions": 70,
  "total_roles": 6
}

Frontend Integration

RBAC Dashboard Component

Location: frontend/src/components/RBACDashboard.jsx

Route: /security/rbac

Access: Requires users.manage_roles or security.view_audit permissions

Features

Tab 1: Roles & Permissions

  • View all system and custom roles
  • Create custom roles with granular permissions
  • Edit custom role permissions
  • Delete custom roles (if not assigned)
  • Color-coded role chips (admin=red, moderator=orange, user=blue, viewer=cyan)
  • Permission count badges

Tab 2: User Roles

  • View all users and their current roles
  • Change user roles (dropdown selection)
  • User status indicators (active/inactive)
  • Prevent self-role modification

Tab 3: Audit Log

  • Browse permission change history
  • Filter by action type, user, target type
  • View change details (old value → new value)
  • Timestamp and IP tracking

Tab 4: Statistics

  • Role distribution chart
  • Recent actions in last 30 days
  • Total permissions and roles count
  • User count per role

Tab 5: My Permissions

  • View your current role and description
  • List all permissions granted to you
  • Grouped by category with icons
  • Permission descriptions

Integration in App

App.jsx:

import RBACDashboard from './components/RBACDashboard';

<Route path="security/rbac" element={<RBACDashboard />} />

SecurityDashboard.jsx:

<Button
  onClick={() => navigate('/security/rbac')}
  startIcon={<AdminPanelSettings />}
>
  {t('security.rbacDashboard')}
</Button>

Translations

English (en.json):

  • security.rbacDashboard: "RBAC & Permissions"
  • rbac.*: 45+ translation keys for all RBAC features

Romanian (ro.json):

  • security.rbacDashboard: "RBAC & Permisiuni"
  • rbac.*: 45+ translation keys (full Romanian translations)

Security Considerations

Defense in Depth

  1. Multiple Authorization Layers

    • JWT authentication (Layer 1)
    • Session validation (Layer 2)
    • RBAC permission check (Layer 3)
  2. Principle of Least Privilege

    • Each role has minimum required permissions
    • Viewer role for read-only access
    • Granular permissions prevent over-privileged accounts
  3. System Role Protection

    • Cannot delete system roles
    • Cannot modify system role permissions
    • Last admin cannot be deleted

Attack Mitigation

Privilege Escalation Prevention:

  • Users cannot modify their own roles
  • Role changes logged in audit trail
  • Permission cache invalidated on role changes

Audit Trail:

  • All permission changes logged with:
    • Actor (who made the change)
    • Action (what was done)
    • Target (what was affected)
    • Old/new values (what changed)
    • IP address and User-Agent
    • Timestamp

Input Validation:

  • Role keys validated (lowercase, underscores only)
  • Permission keys validated against whitelist
  • Array validation for permission lists
  • SQL injection prevention (parameterized queries)

Rate Limiting

RBAC routes protected by rate limiters:

  • readLimiter: 100 requests per 15 minutes (read operations)
  • modifyLimiter: 30 requests per 15 minutes (write operations)

Audit Logging

Logged Actions

  1. role_created

    • Target: role ID
    • New Value: role definition
  2. role_updated

    • Target: role ID
    • Old Value: previous role definition
    • New Value: updated role definition
  3. role_deleted

    • Target: role ID
    • Old Value: deleted role definition
  4. role_assigned

    • Target: user ID
    • Old Value: previous role
    • New Value: new role

Audit Log Metadata

Each log entry captures:

  • User ID and username (who)
  • Action type (what)
  • Target type and ID (where)
  • Old and new values (how it changed)
  • IP address (from where)
  • User-Agent (with what)
  • Timestamp (when)

Querying Audit Logs

// Get all role assignments
GET /api/rbac/audit-log?action=role_assigned

// Get all actions by specific user
GET /api/rbac/audit-log?userId=5

// Get role-related actions
GET /api/rbac/audit-log?targetType=role

// Pagination
GET /api/rbac/audit-log?limit=50&offset=100

Migration Guide

Upgrading from Simple Role System

Current System:

  • Binary role check: user.role === 'admin'
  • Two roles: admin, user

New RBAC System:

  • Granular permissions
  • Four default roles: admin, moderator, user, viewer
  • Custom role support

Migration Steps

  1. Database Migration (Automatic)

    • roles table created on first server start
    • Default roles seeded automatically
    • Existing user roles preserved
  2. Update Route Protection

    Before:

    router.get('/users', authenticate, requireAdmin, (req, res) => { ... });
    

    After:

    router.get('/users', authenticate, requirePermission('users.view'), (req, res) => { ... });
    
  3. Frontend Permission Checks

    Before:

    {user?.role === 'admin' && <AdminPanel />}
    

    After:

    {user?.permissions?.includes('security.view_audit') && <AdminPanel />}
    

Backward Compatibility

The system maintains backward compatibility:

  • requireAdmin middleware still works
  • Existing admin and user roles mapped to RBAC
  • No breaking changes to existing authentication

Best Practices

1. Use Granular Permissions

Bad:

requirePermission('admin') // Too broad

Good:

requirePermission('users.view') // Specific
requirePermission(['playlists.edit', 'channels.edit']) // Multiple specific

2. Principle of Least Privilege

When creating custom roles:

  • Start with minimum permissions
  • Add permissions as needed
  • Regularly audit role usage

Example: Content Editor Role

{
  role_key: 'content_editor',
  name: 'Content Editor',
  permissions: [
    // Only content-related permissions
    'playlists.view',
    'playlists.create',
    'playlists.edit',
    'channels.view',
    'channels.edit',
    'channels.upload_logo',
    // NO user management
    // NO system settings
    // NO backup access
  ]
}

3. Regular Permission Audits

  1. Review role distribution

    • Are too many users admin?
    • Can some admins be moderators?
  2. Check audit logs

    • Monitor role changes
    • Detect unusual permission grants
  3. Clean up unused roles

    • Delete custom roles no longer needed
    • Reassign users from deprecated roles

4. Document Custom Roles

When creating custom roles:

{
  role_key: 'playlist_manager',
  name: 'Playlist Manager',
  description: 'Can manage playlists but not users or settings',
  // Clear description helps future administrators
}

5. Test Permission Changes

Before deploying role changes:

  1. Test in development environment
  2. Verify access for affected users
  3. Check audit logs
  4. Have rollback plan ready

Troubleshooting

Issue: "Insufficient permissions" error

Cause: User lacks required permission(s)

Solution:

  1. Check user's role: GET /api/rbac/my-permissions
  2. Verify required permission for route
  3. Assign appropriate role or add permission to role

Issue: Permission cache not updating

Cause: Cache TTL (5 minutes)

Solution:

// Backend: Force cache clear
clearUserPermissionCache(userId);
// or
clearAllPermissionCache();

// Frontend: Re-fetch user data
const response = await axios.get('/api/rbac/my-permissions');

Issue: Cannot delete custom role

Cause: Role assigned to users

Solution:

  1. Check role usage: GET /api/rbac/stats
  2. Reassign users to different role
  3. Then delete custom role

Issue: System role modification fails

Cause: System roles protected

Solution:

  • Cannot modify system roles (admin, moderator, user, viewer)
  • Create custom role instead
  • Copy desired permissions from system role

Performance Considerations

Permission Caching

  • Cache Duration: 5 minutes
  • Memory Impact: ~1KB per cached user
  • Hit Rate: ~95% (typical)

Database Queries

Optimized:

  • Single query for permission check (cached)
  • Indexed role_key and user_id columns

Audit Log:

  • Paginated results (default 100)
  • Indexed created_at for time-range queries

Recommendations

  1. Production:

    • Monitor cache hit rate
    • Adjust TTL if needed (default: 5 min)
    • Consider Redis for distributed systems
  2. Large Deployments:

    • Archive old audit logs (>90 days)
    • Partition audit table by date
    • Consider read replicas for heavy queries

Summary

The RBAC system provides: Granular Permissions: 70+ specific permissions
Principle of Least Privilege: Four default roles with appropriate access
Custom Roles: Create application-specific roles
Audit Trail: Complete permission change history
Admin UI: Visual role and permission management
Security: Multiple authorization layers
Performance: Permission caching
Internationalization: Full EN/RO translations
Documentation: Comprehensive guide and examples

Next Steps:

  1. Review default role permissions
  2. Create custom roles for your use case
  3. Monitor audit logs regularly
  4. Educate users about their permissions
  5. Conduct regular permission audits

For questions or issues, refer to the audit logs and this documentation.