All systems operational

Authorization & Organization Isolation

Access is controlled by a fixed set of roles, enforced in API routes and, crucially, by PostgreSQL row-level security that isolates each organization's data.

#Purpose

Describe the role model, permission checks, and how tenants are kept separate.

#Architecture

Roles are a fixed enum (for example platform_admin, ceo, admin, manager, and department/viewer/operator/client roles). There are no custom roles.

Permission helpers gate actions in API routes — for example, organization management requires CEO/admin, and timesheet decisions require CEO/admin/manager. Beneath that, RLS policies scope every query to the caller's organization using a current-user-role helper.

Role permission matrix
CapabilityCEOAdminManagerSalesSEOOperatorClientViewer
Manage organization & settings
Manage users & roles
Configure AI agents
Manage API keys & webhooks
Access all departments' data
Approve timesheets & deliverables
Work on assigned records~
Client portal access only
✓ allowed · ~ limited/own records · – not allowed. Access is also constrained by per-organization data isolation.

#How it works

1

Resolve role

The caller's role and organization come from their session/profile.
2

Application check

Route-level helpers permit or deny the action based on role.
3

Database check

RLS independently filters rows to the caller's organization.
4

Defense in depth

Both layers must allow an action for it to succeed.

#Reference

#Access helpers (conceptual)

HelperGrants
Manage-organizationCEO / admin (settings, users, agents, API keys)
Full-accessCEO / admin / manager (e.g., decide timesheets)
Row-level securityEvery tenant row, scoped to the caller's organization

#Implementation notes

  • The role set is fixed; assign the closest-fitting role rather than creating custom ones.
  • Self-approval is blocked where it matters (for example, a user cannot approve their own timesheet).
  • AI acts within the permissions of the user it assists.

#Limitations

Known limitations

  • No custom roles or a per-permission matrix editor.
  • Role changes take effect on the user's next session refresh.

#Security considerations

Security

  • Never rely on the application check alone — RLS is the backstop.
  • Keep the number of CEO/admin accounts small (least privilege).
  • The service-role key bypasses RLS; restrict it to trusted server code.

#Best practices

  • Apply least privilege when assigning roles.
  • Add RLS to every tenant table.
  • Re-audit access after role changes and departures.

Still need help?

Can’t find what you’re looking for? The DevSphere OS team is happy to help.