227 lines
10 KiB
Markdown
227 lines
10 KiB
Markdown
# P0 DISCOVERY — RBAC Permission Matrix Alignment
|
|
|
|
**Date:** 2026-06-25
|
|
**Scope:** Full Gap Analysis between Code-required vs Database-stored permissions
|
|
**Methodology:** `RequirePermission()` decorator extraction from endpoints → PostgreSQL `system.permissions` table query → Diff Analysis
|
|
|
|
---
|
|
|
|
## 1. Codebase Scan — Permissions REQUIRED by the API
|
|
|
|
Extracted from all `backend/app/api/v1/endpoints/` files using `RequirePermission("...")` decorators.
|
|
|
|
| # | Permission Code | Endpoint File | Line(s) |
|
|
|---|----------------|---------------|---------|
|
|
| 1 | `org:view` | `admin_organizations.py` | 176, 324 |
|
|
| 2 | `org:view` | `admin.py` | 763 |
|
|
| 3 | `org:edit` | `admin_organizations.py` | 517 |
|
|
| 4 | `org:manage-members` | `admin_organizations.py` | 630, 743, 830 |
|
|
| 5 | `system:manage` | `system_parameters.py` | 118 |
|
|
| 6 | `dual-control:request` | `security.py` | 28 |
|
|
| 7 | `dual-control:approve` | `security.py` | 82, 111 |
|
|
| 8 | `dual-control:view` | `security.py` | 142 |
|
|
| 9 | `permissions:view` | `admin_permissions.py` | 137, 271, 317 |
|
|
| 10 | `permissions:edit` | `admin_permissions.py` | 177, 355 |
|
|
| 11 | `fleet:view` | `admin_permissions.py` | 456 |
|
|
| 12 | `finance:view` | `finance_admin.py` | 24 |
|
|
| 13 | `finance:edit` | `finance_admin.py` | 41 |
|
|
| 14 | `services:manage` | `admin_services.py` | 31, 58, 92 |
|
|
| 15 | `services:manage` | `admin.py` | 309, 370 |
|
|
| 16 | `subscription:manage` | `admin_packages.py` | 115, 188, 269, 393 |
|
|
| 17 | `settings:view` | `admin.py` | 37, 68, 92, 134, 163 |
|
|
| 18 | `settings:edit` | `admin.py` | 79, 101, 153 |
|
|
| 19 | `user:manage` | `admin.py` | 179, 664 |
|
|
| 20 | `moderation:manage` | `admin.py` | 240 |
|
|
| 21 | `gamification:manage` | `admin.py` | 418 |
|
|
| 22 | `user:view` | `admin.py` | 502 |
|
|
|
|
### Unique permission codes required by code: **20**
|
|
|
|
```
|
|
org:view, org:edit, org:manage-members,
|
|
system:manage,
|
|
dual-control:request, dual-control:approve, dual-control:view,
|
|
permissions:view, permissions:edit,
|
|
fleet:view,
|
|
finance:view, finance:edit,
|
|
services:manage,
|
|
subscription:manage,
|
|
settings:view, settings:edit,
|
|
user:manage, user:view,
|
|
moderation:manage,
|
|
gamification:manage
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Database Scan — Permissions CURRENTLY in `system.permissions`
|
|
|
|
Queried from `system.permissions` table (PostgreSQL).
|
|
|
|
| ID | Code | Domain | Action | Description |
|
|
|----|------|--------|--------|-------------|
|
|
| 1 | `fleet:view` | fleet | view | View fleet/vehicle data |
|
|
| 2 | `fleet:create` | fleet | create | Create new fleet/vehicle entries |
|
|
| 3 | `fleet:edit` | fleet | edit | Edit existing fleet/vehicle data |
|
|
| 4 | `fleet:delete` | fleet | delete | Delete fleet/vehicle entries |
|
|
| 5 | `fleet:approve` | fleet | approve | Approve fleet/vehicle submissions |
|
|
| 6 | `user:view` | user | view | View user profiles and data |
|
|
| 7 | `user:create` | user | create | Create new user accounts |
|
|
| 8 | `user:edit` | user | edit | Edit user profiles and data |
|
|
| 9 | `user:delete` | user | delete | Delete user accounts |
|
|
| 10 | `user:manage-roles` | user | manage-roles | Manage user role assignments |
|
|
| 11 | `finance:view` | finance | view | View financial data and transactions |
|
|
| 12 | `finance:edit` | finance | edit | Edit financial records |
|
|
| 13 | `finance:approve` | finance | approve | Approve financial transactions |
|
|
| 14 | `finance:refund` | finance | refund | Process refunds |
|
|
| 15 | `system:view` | system | view | View system configuration |
|
|
| 16 | `system:edit` | system | edit | Edit system configuration |
|
|
| 17 | `system:manage` | system | manage | Full system management access |
|
|
| 18 | `org:view` | org | view | View organization data |
|
|
| 19 | `org:edit` | org | edit | Edit organization data |
|
|
| 20 | `org:delete` | org | delete | Delete organizations |
|
|
| 21 | `org:manage-members` | org | manage-members | Manage organization members |
|
|
| 22 | `reports:view` | reports | view | View reports |
|
|
| 23 | `reports:export` | reports | export | Export reports |
|
|
| 24 | `reports:manage` | reports | manage | Manage report configurations |
|
|
| 25 | `audit:view` | audit | view | View audit logs |
|
|
| 26 | `audit:export` | audit | export | Export audit logs |
|
|
| 27 | `settings:view` | settings | view | View system settings |
|
|
| 28 | `settings:edit` | settings | edit | Edit system settings |
|
|
| 29 | `permissions:view` | permissions | view | View permission settings and matrix |
|
|
| 30 | `permissions:edit` | permissions | edit | Edit permission settings and role-permission mappings |
|
|
|
|
### Unique permission codes in database: **30**
|
|
|
|
---
|
|
|
|
## 3. GAP ANALYSIS
|
|
|
|
### 3A. ORPHANED CODES — In Code, MISSING from Database
|
|
|
|
**These 8 permissions are the ROOT CAUSE of the 403 Forbidden errors for non-Superadmin users.**
|
|
The API checks for them via `RequirePermission()` in `deps.py:283`, but `system.permissions` has no such records → `rbac_service.get_role_permissions()` returns empty → `403 Forbidden`.
|
|
|
|
| Permission Code | Endpoint File(s) | Routes Affected |
|
|
|----------------|-----------------|-----------------|
|
|
| **`dual-control:request`** | `security.py:28` | POST `/security/dual-control/request` |
|
|
| **`dual-control:approve`** | `security.py:82,111` | POST `/security/dual-control/approve`, POST `/security/dual-control/reject` |
|
|
| **`dual-control:view`** | `security.py:142` | GET `/security/dual-control/pending` |
|
|
| **`services:manage`** | `admin_services.py:31,58,92`; `admin.py:309,370` | CRUD `/admin/services/*` |
|
|
| **`subscription:manage`** | `admin_packages.py:115,188,269,393` | CRUD `/admin/packages/*` |
|
|
| **`user:manage`** | `admin.py:179,664` | POST `/admin/users`, PUT `/admin/users/{id}` |
|
|
| **`moderation:manage`** | `admin.py:240` | GET `/admin/moderation` |
|
|
| **`gamification:manage`** | `admin.py:418` | GET `/admin/gamification` |
|
|
|
|
---
|
|
|
|
### 3B. UNUSED CODES — In Database, NEVER referenced in any Endpoint
|
|
|
|
**These 18 permissions exist in the database but no `RequirePermission("...")` references them anywhere.**
|
|
|
|
| Permission Code | Domain | Notes |
|
|
|----------------|--------|-------|
|
|
| `fleet:create` | fleet | No endpoint checks this |
|
|
| `fleet:edit` | fleet | No endpoint checks this |
|
|
| `fleet:delete` | fleet | No endpoint checks this |
|
|
| `fleet:approve` | fleet | No endpoint checks this |
|
|
| `user:create` | user | No endpoint checks this |
|
|
| `user:edit` | user | No endpoint checks this |
|
|
| `user:delete` | user | No endpoint checks this |
|
|
| `user:manage-roles` | user | No endpoint checks this |
|
|
| `finance:approve` | finance | No endpoint checks this |
|
|
| `finance:refund` | finance | No endpoint checks this |
|
|
| `system:view` | system | No endpoint checks this |
|
|
| `system:edit` | system | No endpoint checks this |
|
|
| `org:delete` | org | No endpoint checks this |
|
|
| `reports:view` | reports | No endpoint checks this |
|
|
| `reports:export` | reports | No endpoint checks this |
|
|
| `reports:manage` | reports | No endpoint checks this |
|
|
| `audit:view` | audit | No endpoint checks this |
|
|
| `audit:export` | audit | No endpoint checks this |
|
|
|
|
---
|
|
|
|
### 3C. Intersection — Permissions that EXIST in BOTH (Correct)
|
|
|
|
These 12 permissions are properly aligned — they exist in the code and the database.
|
|
|
|
| Permission Code | In Code | In DB |
|
|
|----------------|---------|-------|
|
|
| `org:view` | 3 endpoints | ID 18 |
|
|
| `org:edit` | 1 endpoint | ID 19 |
|
|
| `org:manage-members` | 3 endpoints | ID 21 |
|
|
| `system:manage` | 1 endpoint | ID 17 |
|
|
| `permissions:view` | 3 endpoints | ID 29 |
|
|
| `permissions:edit` | 2 endpoints | ID 30 |
|
|
| `fleet:view` | 1 endpoint | ID 1 |
|
|
| `finance:view` | 1 endpoint | ID 11 |
|
|
| `finance:edit` | 1 endpoint | ID 12 |
|
|
| `settings:view` | 4 endpoints | ID 27 |
|
|
| `settings:edit` | 3 endpoints | ID 28 |
|
|
| `user:view` | 1 endpoint | ID 6 |
|
|
|
|
---
|
|
|
|
## 4. ROOT CAUSE SUMMARY
|
|
|
|
### The 403 Forbidden Problem
|
|
|
|
The `ADMIN` role receives 403 errors because **8 critical permission codes are missing from the database**:
|
|
|
|
| Domain | Missing Codes |
|
|
|--------|--------------|
|
|
| **Dual Control** | `dual-control:request`, `dual-control:approve`, `dual-control:view` |
|
|
| **Services** | `services:manage` |
|
|
| **Subscriptions** | `subscription:manage` |
|
|
| **User Management** | `user:manage` |
|
|
| **Moderation** | `moderation:manage` |
|
|
| **Gamification** | `gamification:manage` |
|
|
|
|
When a non-Superadmin user calls any endpoint protected by these permissions, `RequirePermission()` in `deps.py:333` calls `rbac_service.get_role_permissions()` in `rbac_service.py:263` which queries `system.role_permissions` joined with `system.permissions`. Since the code doesn't exist in `system.permissions`, no `system.role_permissions` record can reference it → the permission check fails → `403 Forbidden`.
|
|
|
|
### How the code resolves this (from `deps.py:311-336`):
|
|
```python
|
|
# SUPERADMIN bypass — rank 100 bypasses all checks
|
|
if current_user.role == UserRole.SUPERADMIN:
|
|
return current_user
|
|
|
|
# Non-Superadmin: query DB
|
|
user_permissions = await rbac_service.get_role_permissions(db, role_id)
|
|
if permission_code not in user_permissions:
|
|
raise HTTPException(403, f"Missing permission: {permission_code}")
|
|
```
|
|
|
|
This is why `SUPERADMIN` works but `ADMIN` (or any other role) gets 403 on all 8 phantom permissions.
|
|
|
|
---
|
|
|
|
## 5. CRITICAL FINDINGS
|
|
|
|
| Metric | Value |
|
|
|--------|-------|
|
|
| Total permissions required by code | **20** |
|
|
| Total permissions in database | **30** |
|
|
| Properly aligned (in both) | **12 (60% of code requirements are satisfied)** |
|
|
| **ORPHANED (code-only, breaking 403s)** | **8 (40% of code requirements)** |
|
|
| **UNUSED (DB-only, no endpoint uses)** | **18 (60% of database entries)** |
|
|
|
|
**The database is 60% polluted with unused permissions, while simultaneously missing 40% of the permissions the code actually needs.**
|
|
|
|
---
|
|
|
|
## 6. RECOMMENDED NEXT STEPS (Not Implemented — report only)
|
|
|
|
1. **INSERT** the 8 orphaned permission codes into `system.permissions`:
|
|
- `dual-control:request`, `dual-control:approve`, `dual-control:view`
|
|
- `services:manage`, `subscription:manage`
|
|
- `user:manage`, `moderation:manage`, `gamification:manage`
|
|
|
|
2. **GRANT** these permissions to the `admin` role in `system.role_permissions`.
|
|
|
|
3. **(Optional) Cleanup:** Review the 18 unused codes — keep those planned for future use, archive the rest.
|
|
|
|
---
|
|
|
|
*Report generated by Service Finder Rendszer-Architect. No code or database changes were made — pure discovery audit.*
|