Overview
The RBAC system operates at two tiers — platform level (superadmin) and organization level (org roles, groups, resource permissions) — and is enforced through shared middleware across all services.Two-Tier Hierarchy
Permission Resolution Order
When checking “Can user X perform action Y on resource Z?”:1
Superadmin Bypass
If
user.platform_role === 'superadmin' -> ALLOW (all actions, all orgs)2
Org Role Check
Load user’s role in target organization:
owner-> ALLOW (all actions within org)admin-> ALLOW (all except: delete org, manage billing, transfer ownership)member/viewer-> proceed to resource check
3
Resource Permission Check (member/viewer)
a. Direct user permission on specific resource? -> use that
b. Any group the user belongs to has permission? -> use highest grant
c. Wildcard permission (resource_id = NULL, meaning “all of type”)? -> use that
d. No match -> DENY
4
Default Viewer Behavior
Can read resources they have explicit access to, nothing else.
Action Types Per Resource
Database Schema
Tables
Helper Function
Middleware Architecture
Every service implements these Fastify hooks:requirePlatformRole(role)
requireOrgRole(minRole)
checkResourceAccess(resourceType, resourceId, requiredAction)
auditLog(action, targetType, targetId, details)
Route Middleware Mapping
New Feature Checklist
When adding any new feature:- Does it introduce a new resource type? -> Add to resource/action table above
- Does it have routes? -> Apply
checkResourceAccessorrequireOrgRolemiddleware - Does it modify state? -> Add
auditLogcall - Does it have a UI? -> Gate render on permission context
- Does it incur cost? -> Also integrate with billing
- Add tests for permission enforcement (403/200 per role)
Relationship to Billing
RBAC and billing are complementary mandatory systems:- RBAC answers: “Is this user allowed to perform this operation?”
- Billing answers: “Should this operation be charged, and to whom?”
organizationId + userId context from JWT auth middleware.
