Roles & Permissions: Two Layers, Seven Org Roles
Platform roles, tenant roles, and why module access is not decided by whoever last edited their profile name.
Permissions in a multi-tenant ITAD platform have to be precisely right or visibly wrong. There is very little useful middle ground. ReVend OS uses two layers: platform-level roles for the ReVend operator, and organization roles for tenant users.
Platform-level roles
platform_owner can manage the platform end to end. platform_staff can support customers and work across tenants where the support/admin flow allows it. platform_viewer is read-only for oversight. Platform pages check platform scope before they show platform-only tools such as health, package plans or trust-scoring settings.
Org-level roles
Seven tenant roles are used today: org_admin, org_manager, org_warehouse, org_commercial, org_finance, org_operator and org_viewer. They describe the user's job inside the tenant. Fine-grained role gating is intentionally limited in v1: most module access is controlled by package entitlements, while admin/settings and risky actions use explicit role checks.
Where enforcement happens
UI navigation is helpful, but the server and database are the adults in the room. Server guards read roles from membership records, not from editable user metadata. RLS keeps tenant data tenant-scoped. Service-role admin code has to add tenant scope explicitly because service role bypasses RLS; that is power with paperwork, not a shortcut.
Admin boundaries
Admin pages are platform-only: platform roles see cross-tenant platform tools, and non-platform users are redirected away from Admin. Tenant profile and team administration live in Settings at /settings/organization-profile and /settings/users. A missing route is annoying; a leaked cross-tenant tool is a fire drill.
Changes and audit
Role and permission changes are audit-sensitive. The platform records who changed access, what changed and why. If a user suddenly sees fewer buttons, support should be able to explain it without reading tea leaves from the browser cache.