-
Notifications
You must be signed in to change notification settings - Fork 0
Auth Permission Model
simitben edited this page Apr 10, 2026
·
1 revision
Define a stable permission model for API V3 that scales without coupling authorization to raw URLs.
- This page is a design specification for upcoming auth hardening.
Use resource-action permission codes and map routes to permission codes.
- Permission code format:
<module>.<resource>.<action> - Examples:
inventory.items.readinventory.items.writebpartner.master.readsales.orders.createaccounting.journal-entries.void
- Path can change (
/api/v3/...) while business permission remains the same. - Multiple endpoints can share one business permission.
- Cleaner policy review for security/audit teams.
- Easier module expansion without rewriting permission logic.
| Table | Role |
|---|---|
system_api3_permission |
Master catalog of permission codes |
system_api3_route_permission |
Route key/method/path -> permission mapping |
system_api3_app_permission |
Granted permissions per app |
Each route registration should include a route key.
Example (target pattern):
$router->add('GET', '/api/v3/business-partners', [$controller, 'index'], true, [
'route_key' => 'bpartner.list',
'permission_code' => 'bpartner.master.read'
]);If Router is not yet extended for metadata, maintain a centralized in-memory map inside Auth module as a transition step and move to route metadata in phase 2.
| Module | Resource | Suggested Actions |
|---|---|---|
| bpartner | master |
read, create, update
|
| inventory | items |
read, create, update
|
| sales | orders / invoices / receipts |
read, create, update, void
|
| purchase | invoices / vouchers |
read, create, update, void
|
| accounting | journal-entries / receipts / reports |
read, create, update, void, report
|
| auth-admin | apps / permissions / org-access |
read, create, update, revoke, rotate-secret
|
- Resolve
route_key+http_method. - Find required
permission_codefrom route mapping. - Verify app has active grant in
system_api3_app_permission. - If missing, return
403 V3_AUTH_PERMISSION_DENIED.
Permission pass is not enough. Organization access must also pass:
- Resolve effective organization from request (
organization_id/org_idororganization_code/org_code). - Validate organization is in
system_api3_app_organizationfor current app. - If missing, return
403 V3_AUTH_ORG_DENIED.
Suggested output from GET /api/v3/auth/me/permissions:
app_idapp_code-
permissions[]:permission_codemodule_coderesource_codeaction_code
-
allowed_organizations[]:organization_idorganization_code
- Do not infer permissions from old module/action names at runtime.
- Build explicit mapping once, store in permission tables, and audit changes through admin endpoints.
- Keep one source of truth in DB; avoid hardcoded permission checks inside controllers.