# RBAC Guide - Updation Role System
## Overview
This document explains how Role-Based Access Control (RBAC) works in the Updation MCP system with your **actual production roles**.
---
## Role Hierarchy
Your roles are organized by **level**, not by number. Here's the complete structure:
### ๐ Global Level
- **`GLOBAL_ADMIN` (1)** - Full system-wide access across all organizations
### ๐ข Organization Level
- **`ORG_ADMIN` (2)** - Full access to everything in their organization
- **`ORG_MANAGER` (7)** - Manage operations within the organization
- **`ORG_USER` (14)** - Standard organization user
- **`ORG_VIEWER` (6)** - Read-only at organization level
- **`ORG_USERS` (5)** - Limited organization role
### ๐๏ธ Platform Level
- **`PLATFORM_ADMIN` (4)** - Full access to their platform + dealerships under it
- **`PLATFORM_MANAGER` (3)** - Manage platform and dealerships
- **`PLATFORM_USER` (8)** - Standard platform user
- **`PLATFORM_VIEWER` (9)** - Read-only platform user
### ๐ช Dealership Level
- **`DEALERSHIP_ADMIN` (10)** - Full access to their dealership
- **`DEALERSHIP_MANAGER` (11)** - Manage dealership operations
- **`DEALERSHIP_USERS` (12)** - Standard dealership user
- **`DEALERSHIP_VIEWER` (13)** - Read-only dealership access
### ๐งช Special
- **`TEST_PLATFORM_ADMIN` (15)** - Testing role (treated as platform-level)
---
## Access Rules
### Data Visibility (What Users Can See)
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ GLOBAL_ADMIN (1) โ
โ โ Sees EVERYTHING across all organizations โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Organization-Level Roles (2, 5, 6, 7, 14) โ
โ โ See all platforms in their org โ
โ โ See all dealerships in their org โ
โ โ See all contracts/vendors in their org โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Platform-Level Roles (3, 4, 8, 9, 15) โ
โ โ See their platform only โ
โ โ See dealerships under their platform โ
โ โ See contracts/vendors for their platform โ
โ โ Cannot see other platforms โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Dealership-Level Roles (10, 11, 12, 13) โ
โ โ See their dealership only โ
โ โ See contracts/vendors for their dealership โ
โ โ Cannot see other dealerships โ
โ โ Cannot see platform-level data โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
### Tool Access (What Users Can Do)
**Public Tools** (anyone can call):
- `get_system_info`
- `health_check`
**Authenticated Tools** (all logged-in users):
- `get_user_profile`
**Dealership Tools** (dealership, platform, org, global):
- `get_dealership_contracts`
- `get_dealership_vendors`
- `upload_contract`
**Platform Tools** (platform, org, global only):
- `get_platform_contracts`
- `get_platform_vendors`
- `get_platform_dealerships`
- `get_dealership_summary`
**Organization Tools** (org, global only):
- `get_organization_contracts`
- `get_organization_vendors`
- `get_all_platforms`
- `get_all_dealerships`
- `get_analytics`
- `manage_users`
**Admin Tools** (global only):
- `manage_organizations`
- `system_configuration`
- `audit_logs`
---
## UserContext Helper Properties
When you have a `UserContext` object, you can check permissions easily:
```python
from src.core import UserContext, Role
user = UserContext(
user_id=123,
role=Role.PLATFORM_ADMIN,
organization_id=1,
platform_id=5,
dealership_id=None
)
# Check level
user.is_global_admin # False
user.is_organization_level # False
user.is_platform_level # True
user.is_dealership_level # False
# Check permissions
user.can_write # True (not a viewer)
user.can_manage # True (admin/manager role)
```
### Viewer vs. Non-Viewer
**Viewer roles** (read-only):
- `ORG_VIEWER` (6)
- `PLATFORM_VIEWER` (9)
- `DEALERSHIP_VIEWER` (13)
These roles:
- โ Can see data at their level
- โ Cannot modify/upload/delete
- `user.can_write` returns `False`
**Manager/Admin roles**:
- All roles with "ADMIN" or "MANAGER" in the name
- `user.can_manage` returns `True`
- Can perform management operations
---
## How to Use in Your Tools
### Example 1: Filter Data by Hierarchy
```python
from src.core import UserContext, RBAC
async def get_contracts(user_context: UserContext):
# Fetch all contracts from your API
all_contracts = await fetch_all_contracts()
# Filter based on user's hierarchy level
visible_contracts = RBAC.filter_data_by_hierarchy(
data=all_contracts,
user_context=user_context,
org_field="organization_id",
platform_field="platform_id",
dealership_field="dealership_id"
)
return visible_contracts
```
**What happens:**
- `GLOBAL_ADMIN` โ sees all contracts
- `ORG_ADMIN` โ sees contracts where `organization_id == user.organization_id`
- `PLATFORM_USER` โ sees contracts where `organization_id == user.organization_id AND platform_id == user.platform_id`
- `DEALERSHIP_USER` โ sees contracts where `organization_id == user.organization_id AND dealership_id == user.dealership_id`
### Example 2: Check Tool Permission
```python
from src.core import UserContext, RBAC, Role
async def upload_contract(user_context: UserContext, ...):
# Check if user can use this tool
if not RBAC.is_tool_allowed(user_context.role, "upload_contract"):
raise AuthorizationError("You don't have permission to upload contracts")
# Check if user can write (not just view)
if not user_context.can_write:
raise AuthorizationError("Viewer roles cannot upload contracts")
# Proceed with upload
...
```
### Example 3: Role-Specific Logic
```python
async def get_analytics(user_context: UserContext):
if user_context.is_global_admin:
# Global admin sees system-wide analytics
return await get_global_analytics()
elif user_context.is_organization_level:
# Org users see org-level analytics
return await get_org_analytics(user_context.organization_id)
elif user_context.is_platform_level:
# Platform users see platform-level analytics
return await get_platform_analytics(
user_context.organization_id,
user_context.platform_id
)
else:
# Dealership users don't have access to analytics
raise AuthorizationError("Analytics not available at dealership level")
```
---
## Testing Different Roles
When testing via `/chat` endpoint:
```bash
# Test as Dealership Viewer (read-only)
curl -X POST http://localhost:8002/chat \
-H "Content-Type: application/json" \
-d '{
"user_id": 1,
"organization_id": 1,
"dealership_id": 10,
"role": 13,
"message": "Show me my contracts"
}'
# Test as Platform Admin
curl -X POST http://localhost:8002/chat \
-H "Content-Type: application/json" \
-d '{
"user_id": 2,
"organization_id": 1,
"platform_id": 5,
"role": 4,
"message": "Show me all dealerships in my platform"
}'
# Test as Org Admin
curl -X POST http://localhost:8002/chat \
-H "Content-Type: application/json" \
-d '{
"user_id": 3,
"organization_id": 1,
"role": 2,
"message": "Show me organization-wide analytics"
}'
# Test as Global Admin
curl -X POST http://localhost:8002/chat \
-H "Content-Type: application/json" \
-d '{
"user_id": 4,
"organization_id": 1,
"role": 1,
"message": "Show me all organizations"
}'
```
---
## Common Patterns
### Pattern 1: Hierarchy-Aware Queries
```python
def build_query_filters(user_context: UserContext) -> dict:
"""Build database query filters based on user's hierarchy."""
filters = {"organization_id": user_context.organization_id}
if user_context.is_platform_level:
filters["platform_id"] = user_context.platform_id
if user_context.is_dealership_level:
filters["dealership_id"] = user_context.dealership_id
return filters
```
### Pattern 2: Write Permission Check
```python
def check_write_permission(user_context: UserContext, action: str):
"""Check if user can perform write operations."""
if not user_context.can_write:
raise AuthorizationError(
f"Viewer roles cannot perform {action}. "
f"Contact your admin for write access."
)
```
### Pattern 3: Management Permission Check
```python
def check_management_permission(user_context: UserContext):
"""Check if user can perform management operations."""
if not user_context.can_manage:
raise AuthorizationError(
"Only admin and manager roles can perform this operation"
)
```
---
## Summary
โ
**Roles are grouped by level** (Global, Org, Platform, Dealership)
โ
**Numbers don't indicate hierarchy** - use the helper properties instead
โ
**Viewers can read but not write** - check `can_write` property
โ
**Managers/Admins can manage** - check `can_manage` property
โ
**Data filtering is automatic** - use `RBAC.filter_data_by_hierarchy()`
โ
**Tool access is automatic** - use `RBAC.is_tool_allowed()`
When building new tools:
1. Add tool name to appropriate tool set in `RBAC` class
2. Use `UserContext` properties to check permissions
3. Use `RBAC.filter_data_by_hierarchy()` to filter results
4. Return data in envelope format with `wrap_response()`