RBAC & impersonation
Active Reach uses role-based access control (RBAC) to manage who can do what within an organization, a workspace, and (since the 2026-05 location-scoped permissions phase) a specific outlet.
Role hierarchy
| Role | Scope | Capabilities |
|---|---|---|
| Owner | Organization | Full access — billing, team, settings, all workspaces |
| Admin | Organization or workspace | Everything except billing and deletion |
| Member | Workspace | Create/edit campaigns, segments, journeys. Cannot manage team or settings. |
| Viewer | Workspace | Read-only access to analytics and campaign results |
| Custom | Workspace or org unit | Granular permissions defined by the admin |
Permission categories
| Category | Permissions |
|---|---|
| campaigns | create, edit, send, approve, delete |
| journeys | create, edit, publish, pause, delete |
| contacts | read, create, edit, delete, export |
| segments | create, edit, delete |
| analytics | read, export |
| settings | view, edit, manage_channels, manage_billing |
| team | invite, remove, assign_roles |
| ads | create, manage_budgets, approve_spend |
Custom roles
Create custom roles at Settings → Team → Roles → Create Role:
- Name the role
- Toggle individual permissions on/off
- Scope to a specific org unit (optional — for multi-workspace orgs)
- Save and assign to team members
Permission checks
The platform enforces RBAC at:
- UI level — buttons and pages are hidden/disabled based on the user’s permissions
- API level — every API endpoint checks the requesting user’s permissions; unauthorized requests return
403 - Server Action level — Next.js server actions verify permissions before executing
Location-scoped permissions
A user can be granted access at three scopes — org, workspace, or a specific location (outlet). The resolver UNIONs across all three. The relevant substrate (control-plane):
| Table | What it stores |
|---|---|
user_org_access | Org-tier role binding (cascades to all workspaces / locations) |
user_location_access | Direct location-tier role binding (one row per user × location) |
location_group_role_bindings | Role binding for a named group of locations |
user_location_access is backfilled from user_org_access on first use so existing org-tier grants keep working under the new model.
The location middleware reads the user’s bindings and stamps a resolved (workspace_id, location_id) pair onto every request. Outlet-scoped endpoints then validate against the resolved pair. Final permissions are the union of: org-tier cascade + direct location bindings + location-group bindings.
For developers shipping new endpoints: outlet-scoped writes must validate the resolved location_id against the user’s binding set before mutating data.
Impersonation
Admin and agency impersonation uses a separate auth layer:
- A short-lived
aegis_sim_tokencookie is set when impersonation starts - All actions during impersonation are logged with the impersonator’s identity
- Sessions expire automatically (configurable timeout)
- Full details in Impersonation
API access
RBAC for API consumers:
- SDK write keys — scoped to a workspace, can only send events (no admin access)
- Clerk JWT — carries the user’s org ID and role claims; validated by the gateway
- Internal API secret — service-to-service only, not exposed to tenants
What’s next
- Team & permissions — UI guide for managing roles
- Data governance — access controls in context