Roles and permissions
Control who can do what in your Gateway organization with built-in and custom roles.
Every member of a Gateway organization holds exactly one role. Each role is a named bundle of permissions, and every privileged API endpoint requires one or more permissions to succeed. Use the built-in roles for the common case, or define custom roles to match how your team is organized.
Built-in roles
Three system roles ship with every organization. They cannot be edited or deleted.
System roles are immutable. To grant a slightly different permission set, create a custom role instead.
Permissions catalog
Permissions are grouped into 13 resources. Most resources have a manage_* permission for create / update / delete and a view_* permission for read access. Logs is the one resource without a manage_* permission - visibility is the only operation.
The control-plane API exposes the canonical list at GET /organizations/{org_id}/permissions, which returns both the machine codename and the human-readable display name for each.
Custom roles
Custom roles let you slice the permission set however your team needs - for example, a “Routing Editor” role that grants manage_routing + view_projects + view_api_keys and nothing else, or a “Billing Manager” role that only includes billing permissions.
All four operations require the manage_roles permission.
Deleting a role is blocked if members are assigned to it. Reassign members to a different role first, then retry the delete.
Permission Matrix UI
Open Settings → Roles in the Merge Gateway dashboard to see the permission matrix:
- Each row is a permission, labeled with its human-readable name.
- Each column is a role. System roles render as read-only badges (their checkboxes are non-interactive). Custom roles render as editable columns with a checkbox grid.
- The “Create custom role” panel opens from the right of the page and shares the same matrix layout.
Behind the matrix is a feature flag named rbac. While that flag is on (the default for production orgs), permission checks are enforced server-side. When the flag is off - for example, in early-pilot organizations - the frontend bypasses all checks and returns true for every permission.
Assigning roles to users
Invitations
Org admins invite new members from Settings → Members. Each invitation:
- Requires the inviter to hold
manage_users. - Carries a role selection - the invitee will hold that role immediately on acceptance.
- Expires after 7 days.
- Writes a
MEMBER_INVITEDaudit event on send and aMEMBER_JOINEDevent when accepted.
You can resend (MEMBER_INVITATION_RESENT) or revoke (MEMBER_INVITATION_REVOKED) a pending invitation from the same page. Both actions emit their own audit entries.
Role changes
To change an existing member’s role, use the role selector in the members table. The underlying call is:
This also requires manage_users and emits a MEMBER_ROLE_CHANGED audit event with a diff between the old and new role names.
A member always holds exactly one role at a time. There is no concept of multi-role assignment; if you need a custom permission combination for a user, create a role that has that exact combination and assign them to it.
Permission checks at the API layer
Every mutating control-plane endpoint is gated by require_permission(...). The dependency accepts one or more permission codenames; the caller’s role must hold at least one of them for the request to proceed.
For example, the blocklist endpoints declare:
GET /organizations/{org_id}/blocklist-rules→ requiresview_org_settingsormanage_org_settingsPOST /organizations/{org_id}/blocklist-rules→ requiresmanage_org_settings
If the caller’s role doesn’t satisfy the requirement, the request fails with 403. To find the permission required for any given endpoint, check the OpenAPI reference or the endpoint’s require_permission(...) declaration in the control-plane source.
Audit trail integration
Every RBAC operation writes an entry to the audit trail:
Use the audit trail to answer “who granted this user admin?” or “when did this role lose a permission?” - the diff is captured on every UPDATE event.
FAQ
Can a user have multiple roles?
No. Each member holds exactly one role per organization. If a user belongs to multiple orgs, they have one role in each.
Can I edit the Admin / Developer / Read Only roles?
No. System roles are immutable so the baseline permission sets stay predictable across orgs. To customize, create a new role with the permission set you need.
What happens if I delete a role that has members assigned?
The delete is rejected with 409 Conflict. Reassign affected members to a different role, then retry the delete.
Are there role hierarchies - does Admin inherit Developer?
No. Roles are flat permission sets. The Admin role explicitly enumerates every permission; it does not derive from any other role.
How long do pending invitations stay valid?
7 days. After expiry, the invitee gets a “this invitation has expired” message. The inviter can resend a fresh invitation from the same page.