# Role-Based Access Control (RBAC) Implementation Guide **Last Updated:** November 2025 **Status:** Implementation in Progress **Platform:** Bakery-IA Microservices --- ## Table of Contents 1. [Overview](#overview) 2. [Role System Architecture](#role-system-architecture) 3. [Access Control Implementation](#access-control-implementation) 4. [Service-by-Service RBAC Matrix](#service-by-service-rbac-matrix) 5. [Implementation Guidelines](#implementation-guidelines) 6. [Testing Strategy](#testing-strategy) 7. [Related Documentation](#related-documentation) --- ## Overview This guide provides comprehensive information about implementing Role-Based Access Control (RBAC) across the Bakery-IA platform, consisting of 15 microservices with 250+ API endpoints. ### Key Components - **4 User Roles:** Viewer → Member → Admin → Owner (hierarchical) - **3 Subscription Tiers:** Starter → Professional → Enterprise - **250+ API Endpoints:** Requiring granular access control - **Tenant Isolation:** All services enforce tenant-level data isolation ### Implementation Status **Implemented:** - ✅ JWT authentication across all services - ✅ Tenant isolation via path parameters - ✅ Basic admin role checks in auth service - ✅ Subscription tier checking framework **In Progress:** - 🔧 Role decorators on service endpoints - 🔧 Subscription tier enforcement on premium features - 🔧 Fine-grained resource permissions - 🔧 Audit logging for sensitive operations --- ## Role System Architecture ### User Role Hierarchy Defined in `shared/auth/access_control.py`: ```python class UserRole(Enum): VIEWER = "viewer" # Read-only access MEMBER = "member" # Read + basic write operations ADMIN = "admin" # Full operational access OWNER = "owner" # Full control including tenant settings ROLE_HIERARCHY = { UserRole.VIEWER: 1, UserRole.MEMBER: 2, UserRole.ADMIN: 3, UserRole.OWNER: 4, } ``` ### Permission Matrix by Action | Action Type | Viewer | Member | Admin | Owner | |-------------|--------|--------|-------|-------| | Read data | ✓ | ✓ | ✓ | ✓ | | Create records | ✗ | ✓ | ✓ | ✓ | | Update records | ✗ | ✓ | ✓ | ✓ | | Delete records | ✗ | ✗ | ✓ | ✓ | | Manage users | ✗ | ✗ | ✓ | ✓ | | Configure settings | ✗ | ✗ | ✓ | ✓ | | Billing/subscription | ✗ | ✗ | ✗ | ✓ | | Delete tenant | ✗ | ✗ | ✗ | ✓ | ### Subscription Tier System ```python class SubscriptionTier(Enum): STARTER = "starter" # Basic features PROFESSIONAL = "professional" # Advanced analytics & ML ENTERPRISE = "enterprise" # Full feature set + priority support TIER_HIERARCHY = { SubscriptionTier.STARTER: 1, SubscriptionTier.PROFESSIONAL: 2, SubscriptionTier.ENTERPRISE: 3, } ``` ### Tier Features Matrix | Feature | Starter | Professional | Enterprise | |---------|---------|--------------|------------| | Basic Inventory | ✓ | ✓ | ✓ | | Basic Sales | ✓ | ✓ | ✓ | | Basic Recipes | ✓ | ✓ | ✓ | | ML Forecasting | ✓ (7-day) | ✓ (30+ day) | ✓ (unlimited) | | Model Training | ✓ (1/day, 1k rows) | ✓ (5/day, 10k rows) | ✓ (unlimited) | | Advanced Analytics | ✗ | ✓ | ✓ | | Custom Reports | ✗ | ✓ | ✓ | | Production Optimization | ✓ (basic) | ✓ (advanced) | ✓ (AI-powered) | | Historical Data | 7 days | 90 days | Unlimited | | Multi-location | 1 | 2 | Unlimited | | API Access | ✗ | ✗ | ✓ | | Priority Support | ✗ | ✗ | ✓ | | Max Users | 5 | 20 | Unlimited | | Max Products | 50 | 500 | Unlimited | --- ## Access Control Implementation ### Available Decorators The platform provides these decorators in `shared/auth/access_control.py`: #### Subscription Tier Enforcement ```python # Require specific subscription tier(s) @require_subscription_tier(['professional', 'enterprise']) async def advanced_analytics(...): pass # Convenience decorators @enterprise_tier_required async def enterprise_feature(...): pass @analytics_tier_required # Requires professional or enterprise async def analytics_endpoint(...): pass ``` #### Role-Based Enforcement ```python # Require specific role(s) @require_user_role(['admin', 'owner']) async def delete_resource(...): pass # Convenience decorators @admin_role_required async def admin_only(...): pass @owner_role_required async def owner_only(...): pass ``` #### Combined Enforcement ```python # Require both tier and role @require_tier_and_role(['professional', 'enterprise'], ['admin', 'owner']) async def premium_admin_feature(...): pass ``` ### FastAPI Dependencies Available in `shared/auth/tenant_access.py`: ```python from fastapi import Depends from shared.auth.tenant_access import ( get_current_user_dep, verify_tenant_access_dep, verify_tenant_permission_dep ) # Basic authentication @router.get("/{tenant_id}/resource") async def get_resource( tenant_id: str, current_user: Dict = Depends(get_current_user_dep) ): pass # Tenant access verification @router.get("/{tenant_id}/resource") async def get_resource( tenant_id: str = Depends(verify_tenant_access_dep) ): pass # Resource permission check @router.delete("/{tenant_id}/resource/{id}") async def delete_resource( tenant_id: str = Depends(verify_tenant_permission_dep("resource", "delete")) ): pass ``` --- ## Service-by-Service RBAC Matrix ### Authentication Service **Critical Operations:** - User deletion requires **Admin** role + audit logging - Password changes should enforce strong password policy - Email verification prevents account takeover | Endpoint | Method | Min Role | Min Tier | Notes | |----------|--------|----------|----------|-------| | `/register` | POST | Public | Any | Rate limited | | `/login` | POST | Public | Any | Rate limited (3-5 attempts) | | `/delete/{user_id}` | DELETE | **Admin** | Any | 🔴 CRITICAL - Audit logged | | `/change-password` | POST | Authenticated | Any | Own account only | | `/profile` | GET/PUT | Authenticated | Any | Own account only | **Recommendations:** - ✅ IMPLEMENTED: Admin role check on deletion - 🔧 ADD: Rate limiting on login/register - 🔧 ADD: Audit log for user deletion - 🔧 ADD: MFA for admin accounts - 🔧 ADD: Password strength validation ### Tenant Service **Critical Operations:** - Tenant deletion/deactivation (Owner only) - Subscription changes (Owner only) - Role modifications (Admin+, prevent owner changes) - Member removal (Admin+) | Endpoint | Method | Min Role | Min Tier | Notes | |----------|--------|----------|----------|-------| | `/{tenant_id}` | GET | **Viewer** | Any | Tenant member | | `/{tenant_id}` | PUT | **Admin** | Any | Admin+ only | | `/{tenant_id}/deactivate` | POST | **Owner** | Any | 🔴 CRITICAL - Owner only | | `/{tenant_id}/members` | GET | **Viewer** | Any | View team | | `/{tenant_id}/members` | POST | **Admin** | Any | Invite users | | `/{tenant_id}/members/{user_id}/role` | PUT | **Admin** | Any | Change roles | | `/{tenant_id}/members/{user_id}` | DELETE | **Admin** | Any | 🔴 Remove member | | `/subscriptions/{tenant_id}/upgrade` | POST | **Owner** | Any | 🔴 CRITICAL | | `/subscriptions/{tenant_id}/cancel` | POST | **Owner** | Any | 🔴 CRITICAL | **Recommendations:** - ✅ IMPLEMENTED: Role checks for member management - 🔧 ADD: Prevent removing the last owner - 🔧 ADD: Prevent owner from changing their own role - 🔧 ADD: Subscription change confirmation - 🔧 ADD: Audit log for all tenant modifications ### Sales Service **Critical Operations:** - Sales record deletion (affects financial reports) - Product deletion (affects historical data) - Bulk imports (data integrity) | Endpoint | Method | Min Role | Min Tier | Notes | |----------|--------|----------|----------|-------| | `/{tenant_id}/sales` | GET | **Viewer** | Any | Read sales data | | `/{tenant_id}/sales` | POST | **Member** | Any | Create sales | | `/{tenant_id}/sales/{id}` | DELETE | **Admin** | Any | 🔴 Affects reports | | `/{tenant_id}/products/{id}` | DELETE | **Admin** | Any | 🔴 Affects history | | `/{tenant_id}/analytics/*` | GET | **Viewer** | **Professional** | 💰 Premium | **Recommendations:** - 🔧 ADD: Soft delete for sales records (audit trail) - 🔧 ADD: Subscription tier check on analytics endpoints - 🔧 ADD: Prevent deletion of products with sales history ### Inventory Service **Critical Operations:** - Ingredient deletion (affects recipes) - Manual stock adjustments (inventory manipulation) - Compliance record deletion (regulatory violation) | Endpoint | Method | Min Role | Min Tier | Notes | |----------|--------|----------|----------|-------| | `/{tenant_id}/ingredients` | GET | **Viewer** | Any | List ingredients | | `/{tenant_id}/ingredients/{id}` | DELETE | **Admin** | Any | 🔴 Affects recipes | | `/{tenant_id}/stock/adjustments` | POST | **Admin** | Any | 🔴 Manual adjustment | | `/{tenant_id}/analytics/*` | GET | **Viewer** | **Professional** | 💰 Premium | | `/{tenant_id}/reports/cost-analysis` | GET | **Admin** | **Professional** | 💰 Sensitive | **Recommendations:** - 🔧 ADD: Prevent deletion of ingredients used in recipes - 🔧 ADD: Audit log for all stock adjustments - 🔧 ADD: Compliance records cannot be deleted - 🔧 ADD: Role check: only Admin+ can see cost data ### Production Service **Critical Operations:** - Batch deletion (affects inventory and tracking) - Schedule changes (affects production timeline) - Quality check modifications (compliance) | Endpoint | Method | Min Role | Min Tier | Notes | |----------|--------|----------|----------|-------| | `/{tenant_id}/batches` | GET | **Viewer** | Any | View batches | | `/{tenant_id}/batches/{id}` | DELETE | **Admin** | Any | 🔴 Affects tracking | | `/{tenant_id}/schedules/{id}` | PUT | **Admin** | Any | Schedule changes | | `/{tenant_id}/capacity/optimize` | POST | **Admin** | Any | Basic optimization | | `/{tenant_id}/efficiency-trends` | GET | **Viewer** | **Professional** | 💰 Historical trends | | `/{tenant_id}/capacity-analysis` | GET | **Admin** | **Professional** | 💰 Advanced analysis | **Tier-Based Features:** - **Starter:** Basic capacity, 7-day history, simple optimization - **Professional:** Advanced metrics, 90-day history, advanced algorithms - **Enterprise:** Predictive maintenance, unlimited history, AI-powered **Recommendations:** - 🔧 ADD: Optimization depth limits per tier - 🔧 ADD: Historical data limits (7/90/unlimited days) - 🔧 ADD: Prevent deletion of completed batches ### Forecasting Service **Critical Operations:** - Forecast generation (consumes ML resources) - Bulk operations (resource intensive) - Scenario creation (computational cost) | Endpoint | Method | Min Role | Min Tier | Notes | |----------|--------|----------|----------|-------| | `/{tenant_id}/forecasts` | GET | **Viewer** | Any | View forecasts | | `/{tenant_id}/forecasts/generate` | POST | **Admin** | Any | Trigger ML forecast | | `/{tenant_id}/scenarios` | GET | **Viewer** | **Enterprise** | 💰 Scenario modeling | | `/{tenant_id}/scenarios` | POST | **Admin** | **Enterprise** | 💰 Create scenario | | `/{tenant_id}/analytics/accuracy` | GET | **Viewer** | **Professional** | 💰 Model metrics | **Tier-Based Limits:** - **Starter:** 7-day forecasts, 10/day quota - **Professional:** 30+ day forecasts, 100/day quota, accuracy metrics - **Enterprise:** Unlimited forecasts, scenario modeling, custom parameters **Recommendations:** - 🔧 ADD: Forecast horizon limits per tier - 🔧 ADD: Rate limiting based on tier (ML cost) - 🔧 ADD: Quota limits per subscription tier - 🔧 ADD: Scenario modeling only for Enterprise ### Training Service **Critical Operations:** - Model training (expensive ML operations) - Model deployment (affects production forecasts) - Model retraining (overwrites existing models) | Endpoint | Method | Min Role | Min Tier | Notes | |----------|--------|----------|----------|-------| | `/{tenant_id}/training-jobs` | POST | **Admin** | Any | Start training | | `/{tenant_id}/training-jobs/{id}/cancel` | POST | **Admin** | Any | Cancel training | | `/{tenant_id}/models/{id}/deploy` | POST | **Admin** | Any | 🔴 Deploy model | | `/{tenant_id}/models/{id}/artifacts` | GET | **Admin** | **Enterprise** | 💰 Download artifacts | | `/ws/{tenant_id}/training` | WebSocket | **Admin** | Any | Real-time updates | **Tier-Based Quotas:** - **Starter:** 1 training job/day, 1k rows max, simple Prophet - **Professional:** 5 jobs/day, 10k rows max, model versioning - **Enterprise:** Unlimited jobs, unlimited rows, custom parameters **Recommendations:** - 🔧 ADD: Training quota per subscription tier - 🔧 ADD: Dataset size limits per tier - 🔧 ADD: Queue priority based on subscription - 🔧 ADD: Artifact download only for Enterprise ### Orders Service **Critical Operations:** - Order cancellation (affects production and customer) - Customer deletion (GDPR compliance required) - Procurement scheduling (affects inventory) | Endpoint | Method | Min Role | Min Tier | Notes | |----------|--------|----------|----------|-------| | `/{tenant_id}/orders` | GET | **Viewer** | Any | View orders | | `/{tenant_id}/orders/{id}/cancel` | POST | **Admin** | Any | 🔴 Cancel order | | `/{tenant_id}/customers/{id}` | DELETE | **Admin** | Any | 🔴 GDPR compliance | | `/{tenant_id}/procurement/requirements` | GET | **Admin** | **Professional** | 💰 Planning | | `/{tenant_id}/procurement/schedule` | POST | **Admin** | **Professional** | 💰 Scheduling | **Recommendations:** - 🔧 ADD: Order cancellation requires reason/notes - 🔧 ADD: Customer deletion with GDPR-compliant export - 🔧 ADD: Soft delete for orders (audit trail) --- ## Implementation Guidelines ### Step 1: Add Role Decorators ```python from shared.auth.access_control import require_user_role @router.delete("/{tenant_id}/sales/{sale_id}") @require_user_role(['admin', 'owner']) async def delete_sale( tenant_id: str, sale_id: str, current_user: Dict = Depends(get_current_user_dep) ): # Existing logic... pass ``` ### Step 2: Add Subscription Tier Checks ```python from shared.auth.access_control import require_subscription_tier @router.post("/{tenant_id}/forecasts/generate") @require_user_role(['admin', 'owner']) async def generate_forecast( tenant_id: str, horizon_days: int, current_user: Dict = Depends(get_current_user_dep) ): # Check tier-based limits tier = current_user.get('subscription_tier', 'starter') max_horizon = { 'starter': 7, 'professional': 90, 'enterprise': 365 } if horizon_days > max_horizon.get(tier, 7): raise HTTPException( status_code=402, detail=f"Forecast horizon limited to {max_horizon[tier]} days for {tier} tier" ) # Check daily quota daily_quota = {'starter': 10, 'professional': 100, 'enterprise': None} if not await check_quota(tenant_id, 'forecasts', daily_quota[tier]): raise HTTPException( status_code=429, detail=f"Daily forecast quota exceeded for {tier} tier" ) # Existing logic... ``` ### Step 3: Add Audit Logging ```python from shared.audit import log_audit_event @router.delete("/{tenant_id}/customers/{customer_id}") @require_user_role(['admin', 'owner']) async def delete_customer( tenant_id: str, customer_id: str, current_user: Dict = Depends(get_current_user_dep) ): # Existing deletion logic... # Add audit log await log_audit_event( tenant_id=tenant_id, user_id=current_user["user_id"], action="customer.delete", resource_type="customer", resource_id=customer_id, severity="high" ) ``` ### Step 4: Implement Rate Limiting ```python from shared.rate_limit import check_quota @router.post("/{tenant_id}/training-jobs") @require_user_role(['admin', 'owner']) async def create_training_job( tenant_id: str, dataset_rows: int, current_user: Dict = Depends(get_current_user_dep) ): tier = current_user.get('subscription_tier', 'starter') # Check daily quota daily_limits = {'starter': 1, 'professional': 5, 'enterprise': None} if not await check_quota(tenant_id, 'training_jobs', daily_limits[tier], period=86400): raise HTTPException( status_code=429, detail=f"Daily training job limit reached for {tier} tier ({daily_limits[tier]}/day)" ) # Check dataset size limit dataset_limits = {'starter': 1000, 'professional': 10000, 'enterprise': None} if dataset_limits[tier] and dataset_rows > dataset_limits[tier]: raise HTTPException( status_code=402, detail=f"Dataset size limited to {dataset_limits[tier]} rows for {tier} tier" ) # Existing logic... ``` --- ## Testing Strategy ### Unit Tests ```python # Test role enforcement def test_delete_requires_admin_role(): response = client.delete( "/api/v1/tenant123/sales/sale456", headers={"Authorization": f"Bearer {member_token}"} ) assert response.status_code == 403 assert "insufficient_permissions" in response.json()["detail"]["error"] # Test subscription tier enforcement def test_forecasting_horizon_limit_starter(): response = client.post( "/api/v1/tenant123/forecasts/generate", json={"horizon_days": 30}, # Exceeds 7-day limit headers={"Authorization": f"Bearer {starter_user_token}"} ) assert response.status_code == 402 # Payment Required assert "limited to 7 days" in response.json()["detail"] # Test training job quota def test_training_job_daily_quota_starter(): # First job succeeds response1 = client.post( "/api/v1/tenant123/training-jobs", json={"dataset_rows": 500}, headers={"Authorization": f"Bearer {starter_admin_token}"} ) assert response1.status_code == 200 # Second job on same day fails (1/day limit) response2 = client.post( "/api/v1/tenant123/training-jobs", json={"dataset_rows": 500}, headers={"Authorization": f"Bearer {starter_admin_token}"} ) assert response2.status_code == 429 # Too Many Requests ``` ### Integration Tests ```python # Test tenant isolation def test_user_cannot_access_other_tenant(): response = client.get( "/api/v1/tenant456/sales", # Different tenant headers={"Authorization": f"Bearer {user_token}"} ) assert response.status_code == 403 ``` ### Security Tests ```python # Test rate limiting def test_training_job_rate_limit(): for i in range(6): response = client.post( "/api/v1/tenant123/training-jobs", headers={"Authorization": f"Bearer {admin_token}"} ) assert response.status_code == 429 # Too Many Requests ``` --- ## Related Documentation ### Security Documentation - [Database Security](./database-security.md) - Database security implementation - [TLS Configuration](./tls-configuration.md) - TLS/SSL setup details - [Security Checklist](./security-checklist.md) - Deployment checklist ### Source Reports - [RBAC Analysis Report](../RBAC_ANALYSIS_REPORT.md) - Complete analysis ### Code References - `shared/auth/access_control.py` - Role and tier decorators - `shared/auth/tenant_access.py` - FastAPI dependencies - `services/tenant/app/models/tenants.py` - Tenant member model --- **Document Version:** 1.0 **Last Review:** November 2025 **Next Review:** February 2026 **Owner:** Security & Platform Team