10 KiB
Roles and Permissions System
Overview
The Bakery IA platform implements a dual role system that provides fine-grained access control across both platform-wide and organization-specific operations.
Architecture
Two Distinct Role Systems
1. Global User Roles (Auth Service)
Purpose: System-wide permissions across the entire platform
Service: Auth Service
Storage: User model
Scope: Cross-tenant, platform-level access control
Roles:
super_admin- Full platform access, can perform any operationadmin- System administrator, platform management capabilitiesmanager- Mid-level management accessuser- Basic authenticated user
Use Cases:
- Platform administration
- Cross-tenant operations
- System-wide features
- User management at platform level
2. Tenant-Specific Roles (Tenant Service)
Purpose: Organization/tenant-level permissions
Service: Tenant Service
Storage: TenantMember model
Scope: Per-tenant access control
Roles:
owner- Full control of the tenant, can transfer ownership, manage all aspectsadmin- Tenant administrator, can manage team members and most operationsmember- Standard team member, regular operational accessviewer- Read-only observer, view-only access to tenant data
Use Cases:
- Team management
- Organization-specific operations
- Resource access within a tenant
- Most application features
Role Mapping
When users are created through tenant management (pilot phase), tenant roles are automatically mapped to appropriate global roles:
Tenant Role → Global Role │ Rationale
─────────────────────────────────────────────────
admin → admin │ Administrative access
member → manager │ Management-level access
viewer → user │ Basic user access
owner → (no mapping) │ Owner is tenant-specific only
Implementation:
- Frontend:
frontend/src/types/roles.ts - Backend:
services/tenant/app/api/tenant_members.py(lines 68-76)
Permission Checking
Unified Permission System
Location: frontend/src/utils/permissions.ts
The unified permission system provides centralized functions for checking permissions:
Functions
-
checkGlobalPermission(user, options)- Check platform-wide permissions
- Used for: System settings, platform admin features
-
checkTenantPermission(tenantAccess, options)- Check tenant-specific permissions
- Used for: Team management, tenant resources
-
checkCombinedPermission(user, tenantAccess, options)- Check either global OR tenant permissions
- Used for: Mixed access scenarios
-
Helper Functions:
canManageTeam()- Check team management permissionisTenantOwner()- Check if user is tenant ownercanPerformAdminActions()- Check admin permissionsgetEffectivePermissions()- Get all permission flags
Usage Examples
// Check if user can manage platform users (global only)
checkGlobalPermission(user, { requiredRole: 'admin' })
// Check if user can manage tenant team (tenant only)
checkTenantPermission(tenantAccess, { requiredRole: 'owner' })
// Check if user can access a feature (either global admin OR tenant owner)
checkCombinedPermission(user, tenantAccess, {
globalRoles: ['admin', 'super_admin'],
tenantRoles: ['owner']
})
Route Protection
Protected Routes
Location: frontend/src/router/ProtectedRoute.tsx
All protected routes now use the unified permission system:
// Admin Route: Global admin OR tenant owner/admin
<AdminRoute>
<Component />
</AdminRoute>
// Manager Route: Global admin/manager OR tenant admin/owner/member
<ManagerRoute>
<Component />
</ManagerRoute>
// Owner Route: Super admin OR tenant owner only
<OwnerRoute>
<Component />
</OwnerRoute>
Team Management
Core Features
1. Add Team Members
- Permission Required: Tenant Owner or Admin
- Options:
- Add existing user to tenant
- Create new user and add to tenant (pilot phase)
- Subscription Limits: Checked before adding members
2. Update Member Roles
- Permission Required: Context-dependent
- Viewer → Member: Any admin
- Member → Admin: Owner only
- Admin → Member: Owner only
- Restrictions: Cannot change Owner role via standard UI
3. Remove Members
- Permission Required: Owner only
- Restrictions: Cannot remove the Owner
4. Transfer Ownership
- Permission Required: Owner only
- Requirements:
- New owner must be an existing Admin
- Two-step confirmation process
- Irreversible operation
- Changes:
- New user becomes Owner
- Previous owner becomes Admin
Team Page
Location: frontend/src/pages/app/settings/team/TeamPage.tsx
Features:
- Team member list with role indicators
- Filter by role
- Search by name/email
- Member details modal
- Activity tracking
- Transfer ownership modal
- Error recovery for missing user data
Security:
- Removed insecure owner_id fallback
- Proper access validation through backend
- Permission-based UI rendering
Backend Implementation
Tenant Member Endpoints
Location: services/tenant/app/api/tenant_members.py
Endpoints:
POST /tenants/{tenant_id}/members/with-user- Add member with optional user creationPOST /tenants/{tenant_id}/members- Add existing userGET /tenants/{tenant_id}/members- List membersPUT /tenants/{tenant_id}/members/{user_id}/role- Update roleDELETE /tenants/{tenant_id}/members/{user_id}- Remove memberPOST /tenants/{tenant_id}/transfer-ownership- Transfer ownershipGET /tenants/{tenant_id}/admins- Get tenant adminsDELETE /tenants/user/{user_id}/memberships- Delete user memberships (internal)
Member Enrichment
The backend enriches tenant members with user data from the Auth service:
- User full name
- Phone
- Last login
- Language/timezone preferences
Error Handling:
- Graceful degradation if Auth service unavailable
- Fallback to user_id if enrichment fails
- Frontend displays warning for incomplete data
Best Practices
When to Use Which Permission Check
-
Global Permission Check:
- Platform administration
- Cross-tenant operations
- System-wide features
- User management at platform level
-
Tenant Permission Check:
- Team management
- Organization-specific resources
- Tenant settings
- Most application features
-
Combined Permission Check:
- Features requiring elevated access
- Admin-only operations that can be done by either global or tenant admins
- Owner-specific operations with super_admin override
Security Considerations
-
Never use client-side owner_id comparison as fallback
- Always validate through backend
- Use proper access endpoints
-
Always validate permissions on the backend
- Frontend checks are for UX only
- Backend is source of truth
-
Use unified permission system
- Consistent permission checking
- Clear documentation
- Type-safe
-
Audit critical operations
- Log role changes
- Track ownership transfers
- Monitor member additions/removals
Future Enhancements
Planned Features
-
Role Change History
- Audit trail for role changes
- Display who changed roles and when
- Integrated into member details modal
-
Fine-grained Permissions
- Custom permission sets
- Permission groups
- Resource-level permissions
-
Invitation Flow
- Replace direct user creation
- Email-based invitations
- Invitation expiration
-
Member Status Management
- Activate/deactivate members
- Suspend access temporarily
- Bulk status updates
-
Advanced Team Features
- Sub-teams/departments
- Role templates
- Bulk role assignments
Troubleshooting
Common Issues
"Permission Denied" Errors
- Cause: User lacks required role or permission
- Solution: Verify user's tenant membership and role
- Check:
currentTenantAccessin tenant store
Missing User Data in Team List
- Cause: Auth service enrichment failed
- Solution: Check Auth service connectivity
- Workaround: Frontend displays warning and fallback data
Cannot Transfer Ownership
- Cause: No eligible admins
- Solution: Promote a member to admin first
- Requirement: New owner must be an existing admin
Access Validation Stuck Loading
- Cause: Tenant access endpoint not responding
- Solution: Reload page or check backend logs
- Prevention: Backend health monitoring
API Reference
Frontend
Permission Functions: frontend/src/utils/permissions.ts
Protected Routes: frontend/src/router/ProtectedRoute.tsx
Role Types: frontend/src/types/roles.ts
Team Management: frontend/src/pages/app/settings/team/TeamPage.tsx
Transfer Modal: frontend/src/components/domain/team/TransferOwnershipModal.tsx
Backend
Tenant Members API: services/tenant/app/api/tenant_members.py
Tenant Models: services/tenant/app/models/tenants.py
Tenant Service: services/tenant/app/services/tenant_service.py
Migration Notes
From Single Role System
If migrating from a single role system:
-
Audit existing roles
- Map old roles to new structure
- Identify tenant vs global roles
-
Update permission checks
- Replace old checks with unified system
- Test all protected routes
-
Migrate user data
- Set appropriate global roles
- Create tenant memberships
- Ensure owners are properly set
-
Update frontend components
- Use new permission functions
- Update route guards
- Test all scenarios
Support
For issues or questions about the roles and permissions system:
- Check this documentation
- Review code comments in permission utilities
- Check backend logs for permission errors
- Verify tenant membership in database
- Test with different user roles to isolate issues
Last Updated: 2025-10-31 Version: 1.0.0 Status: ✅ Production Ready