#312 Platform admin management: Create /api/v1/platform/admins endpoints

closed high Created 2025-12-07 06:16 · Updated 2025-12-16 19:42

Description

Edit
## Problem Platform admins with `_platform` tenant JWT cannot manage other platform admins via existing `/api/v1/users` endpoint. ### Root Cause Analysis 1. `/api/v1/users` requires `manage_users` permission 2. `_platform` tenant has platform-specific roles (`platform_owner`, `platform_admin`, `platform_support`) with platform-specific permissions: - `manage_tenants` - `view_all_tenants` - `manage_platform_admins` - `view_platform_metrics` - `impersonate_tenant` 3. These roles do NOT include `manage_users` (which is a tenant-level permission in `tenant_admin` role) 4. When platform admin calls `/api/v1/users`, permission check fails 5. **Bug**: Returns 500 instead of 403 because exception during error message building is caught by broad exception handler at `api/middleware/rbac.py:706-713` ### Current Code Flow ``` require_permission('manage_users') decorator → check_user_permission(conn, '_platform', user_email, 'manage_users') → get_auth_for_tenant(conn, '_platform') # succeeds → auth_client.user_has_permission(user_email, 'manage_users') # returns False → Permission denied, tries to build error message → get_user_roles(conn, '_platform', user_email) # may throw exception → Exception caught → returns 500 instead of 403 ``` ### Relevant Files - `api/middleware/rbac.py:496-717` - `require_permission` decorator - `engine/security/platform.py` - Platform tenant management, roles defined at lines 99-129 - `engine/security/rbac_roles.py:382-408` - `check_user_permission()` function - `engine/security/auth_wrapper.py:153-199` - `get_auth_for_tenant()` function ### Platform Roles (from platform.py) ```python PLATFORM_ROLES = [ PlatformRoleDefinition( name='platform_owner', permissions=['manage_tenants', 'view_all_tenants', 'manage_platform_admins', 'view_platform_metrics', 'impersonate_tenant'], ), PlatformRoleDefinition( name='platform_admin', permissions=['manage_tenants', 'view_all_tenants', 'view_platform_metrics', 'impersonate_tenant'], ), PlatformRoleDefinition( name='platform_support', permissions=['view_all_tenants', 'view_platform_metrics'], ), ] ``` ## Solution: Create Dedicated Platform Admin Endpoints ### New Endpoints | Method | Endpoint | Permission | Description | |--------|----------|------------|-------------| | GET | `/api/v1/platform/admins` | `view_all_tenants` OR `manage_platform_admins` | List all platform admins with roles | | POST | `/api/v1/platform/admins` | `manage_platform_admins` | Add platform admin | | DELETE | `/api/v1/platform/admins/{email}` | `manage_platform_admins` | Remove platform admin | ### Security Requirements 1. **Protect platform_owner**: The original `platform_owner` cannot be removed by anyone (including themselves) 2. **Role hierarchy**: Only `platform_owner` has `manage_platform_admins` permission 3. **Audit logging**: All platform admin changes must be logged to `platform_audit_log` table ### Implementation Notes 1. Create new blueprint: `api/blueprints/v1/platform.py` 2. Use existing functions from `engine/security/platform.py`: - `list_platform_admins(conn)` - already exists - `add_platform_admin(conn, email, role)` - already exists - `remove_platform_admin(conn, email, role)` - already exists 3. Add protection logic to prevent removing the first platform_owner 4. Register blueprint in `api/__init__.py` ### Also Fix (Related Bug) The 500-instead-of-403 bug in `require_permission` decorator: - Wrap `_get_user_context()` call in its own try/except - If building error message fails, still return 403 with generic message ## Why This Approach 1. **Clean separation**: Platform operations vs tenant operations 2. **Scalable**: Doesn't conflate platform and tenant permissions 3. **Secure**: Built-in protection for super admin 4. **Existing code**: Most logic already exists in `platform.py`

Comments

Loading comments...

Context

Loading context...

Audit History

View All
Loading audit history...