#312 Platform admin management: Create /api/v1/platform/admins endpoints
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 AllLoading audit history...