← Back to Table of Contents

User Roles

Comprehensive user roles and permissions system for the Open Source Site Tracking platform, including role definitions, permission management, and access control.

Overview Role Architecture Permission Management Predefined Roles Role Management API Endpoints Best Practices

Overview

The user roles system provides comprehensive access control for the Open Source Site Tracking platform. It implements role-based access control (RBAC) with granular permissions, role hierarchy, and flexible role assignment.

Role Architecture

Role Model

Core Components

# Role model definition
class Role:
    id: str
    name: str
    description: str
    permissions: List[str]
    level: str
    is_system_role: bool
    is_default: bool
    created_at: datetime
    updated_at: datetime
class UserRole:
    id: str
    user_id: str
    role_id: str
    resource_id: str
    resource_type: str
    granted_by: str
    granted_at: datetime
    expires_at: Optional[datetime]
    is_active: bool
class Permission:
    id: str
    name: str
    description: str
    resource_type: str
    action: str
    level: str
    created_at: datetime
class RoleLevel:
    SYSTEM = "system"
    ORGANIZATION = "organization"
    PROJECT = "project"
    TEAM = "team"
class RoleType:
    SYSTEM_ROLE = "system_role"
    ORGANIZATION_ROLE = "organization_role"
    PROJECT_ROLE = "project_role"
    TEAM_ROLE = "team_role"

Role Hierarchy

System Level

Organization Level

Project Level

Team Level

Permission Management

Permission Model

Permission Structure

# Permission management implementation
class PermissionManager:
    def __init__(self):
        self.permissions_cache = {}
        self.roles_cache = {}
    
    async def check_permission(self, user_id, permission, resource_id=None):
        """Check if user has permission"""
        # Get user roles
        user_roles = await self.get_user_roles(user_id)
        
        # Check each role for permission
        for role in user_roles:
            if await self.role_has_permission(role, permission, resource_id):
                return True
        
        return False
    
    async def role_has_permission(self, role, permission, resource_id=None):
        """Check if role has permission"""
        # Get role details
        role_details = await self.get_role_details(role.role_id)
        
        # Check direct permissions
        if permission in role_details.permissions:
            return True
        
        # Check inherited permissions
        inherited_permissions = await self.get_inherited_permissions(role_details)
        if permission in inherited_permissions:
            return True
        
        # Check resource-specific permissions
        if resource_id:
            resource_permissions = await self.get_resource_permissions(role, resource_id)
            if permission in resource_permissions:
                return True
        
        return False
    
    async def grant_permission(self, user_id, role_id, resource_id=None, expires_at=None):
        """Grant role to user"""
        user_role = UserRole(
            user_id=user_id,
            role_id=role_id,
            resource_id=resource_id,
            resource_type=self.get_resource_type(resource_id),
            granted_by=self.get_current_user_id(),
            granted_at=datetime.utcnow(),
            expires_at=expires_at,
            is_active=True
        )
        
        await self.save_user_role(user_role)
        
        # Clear cache
        self.clear_user_cache(user_id)
        
        return user_role

Permission Categories

Analytics Permissions

Project Permissions

User Permissions

Predefined Roles

System Roles

Super Admin

Permissions

  • Full system access
  • User management
  • Organization management
  • System configuration
  • Security administration

Use Cases

  • System administration
  • Emergency access
  • System maintenance
  • Security oversight

System Admin

Organization Roles

Organization Owner

Organization Admin

Project Roles

Project Owner

Project Member

Role Management

Role Assignment

Role Assignment Process

# Role assignment implementation
class RoleAssignmentService:
    def __init__(self):
        self.permission_manager = PermissionManager()
    
    async def assign_role(self, user_id, role_id, resource_id=None, context=None):
        """Assign role to user"""
        # Validate role exists
        role = await self.get_role(role_id)
        if not role:
            raise ValueError(f"Role {role_id} not found")
        
        # Validate user exists
        user = await self.get_user(user_id)
        if not user:
            raise ValueError(f"User {user_id} not found")
        
        # Validate resource access
        if resource_id:
            if not await self.can_assign_role(user_id, role_id, resource_id):
                raise PermissionError("Insufficient permissions to assign role")
        
        # Create user role assignment
        user_role = await self.permission_manager.grant_permission(
            user_id=user_id,
            role_id=role_id,
            resource_id=resource_id,
            expires_at=context.get('expires_at') if context else None
        )
        
        # Send notification
        await self.send_role_assignment_notification(user_role, context)
        
        # Log assignment
        await self.log_role_assignment(user_role, context)
        
        return user_role
    
    async def revoke_role(self, user_id, role_id, resource_id=None, context=None):
        """Revoke role from user"""
        # Find user role assignment
        user_role = await self.find_user_role(user_id, role_id, resource_id)
        if not user_role:
            raise ValueError("Role assignment not found")
        
        # Validate revocation permissions
        if not await self.can_revoke_role(user_id, role_id, resource_id):
            raise PermissionError("Insufficient permissions to revoke role")
        
        # Deactivate role assignment
        user_role.is_active = False
        user_role.revoked_at = datetime.utcnow()
        user_role.revoked_by = self.get_current_user_id()
        
        await self.save_user_role(user_role)
        
        # Send notification
        await self.send_role_revocation_notification(user_role, context)
        
        # Log revocation
        await self.log_role_revocation(user_role, context)
        
        return user_role

Role Lifecycle

Role Creation

Role Updates

API Endpoints

Role Management API

Create Role

# Create custom role
POST /api/v1/roles
{
  "name": "Custom Analytics Manager",
  "description": "Custom role for analytics management",
  "permissions": [
    "analytics.read",
    "analytics.write",
    "analytics.export",
    "project.read"
  ],
  "level": "project",
  "is_default": false
}
Response:
{
  "id": "role-123",
  "name": "Custom Analytics Manager",
  "description": "Custom role for analytics management",
  "permissions": [
    "analytics.read",
    "analytics.write",
    "analytics.export",
    "project.read"
  ],
  "level": "project",
  "is_system_role": false,
  "created_at": "2024-01-15T10:30:00Z"
}

Assign Role

# Assign role to user
POST /api/v1/users/{user_id}/roles
{
  "role_id": "role-123",
  "resource_id": "project-456",
  "resource_type": "project",
  "expires_at": "2024-12-31T23:59:59Z"
}
Response:
{
  "id": "user-role-789",
  "user_id": "user-123",
  "role_id": "role-123",
  "resource_id": "project-456",
  "resource_type": "project",
  "granted_at": "2024-01-15T10:30:00Z",
  "expires_at": "2024-12-31T23:59:59Z",
  "is_active": true
}

Check Permission

# Check user permission
GET /api/v1/users/{user_id}/permissions/check?permission=analytics.read&resource_id=project-456
Response:
{
  "has_permission": true,
  "permission": "analytics.read",
  "resource_id": "project-456",
  "granted_by": [
    {
      "role_id": "role-123",
      "role_name": "Analytics Manager",
      "granted_at": "2024-01-15T10:30:00Z"
    }
  ]
}

User Role API

Get User Roles

# Get user roles
GET /api/v1/users/{user_id}/roles
Response:
{
  "roles": [
    {
      "id": "user-role-789",
      "role_id": "role-123",
      "role_name": "Analytics Manager",
      "resource_id": "project-456",
      "resource_type": "project",
      "granted_at": "2024-01-15T10:30:00Z",
      "expires_at": "2024-12-31T23:59:59Z",
      "is_active": true
    }
  ],
  "summary": {
    "total_roles": 1,
    "active_roles": 1,
    "expired_roles": 0
  }
}

Best Practices

Role Design

Principle of Least Privilege

  • Minimal Access: Grant only necessary permissions
  • Role-based: Use roles for permission management
  • Time-limited: Use temporary roles when possible
  • Regular Review: Review role assignments regularly

Role Granularity

  • Fine-grained: Use specific permissions
  • Resource-specific: Apply permissions to specific resources
  • Action-based: Define permissions by actions
  • Context-aware: Consider context in permission checks

Security Implementation

Security Best Practices

  • Input Validation: Validate all role inputs
  • Output Encoding: Encode permission outputs
  • SQL Injection Prevention: Use parameterized queries
  • XSS Prevention: Sanitize permission data
  • CSRF Protection: Use CSRF tokens

Monitoring and Alerting

  • Real-time Monitoring: Monitor role changes
  • Anomaly Detection: Detect unusual role assignments
  • Alert System: Alert on security events
  • Regular Audits: Conduct regular security audits

Implementation Checklist

  • ✅ Implement role-based access control
  • ✅ Define comprehensive permission set
  • ✅ Create predefined roles
  • ✅ Implement role assignment system
  • ✅ Add permission checking middleware
  • ✅ Implement role lifecycle management
  • ✅ Add audit logging
  • ✅ Set up security monitoring
  • ✅ Test role system thoroughly
  • ✅ Document role system