How to Create a Custom Role
5 min read
Overview
Custom roles allow administrators to tailor access control to their organization's specific needs without modifying the built-in system roles. Custom roles are created through the Access Management UI or via the GraphQL API.
This page covers:
Creating a custom role via the UI (with inheritance)
Adding granular policies via the API (for advanced use cases)
Two worked examples
Creating a Custom Role via the UI
The Access Management UI (behind feature flag FEATURE_FLAG_NEW_ACCESS_CONTROL_UI_UN_11268) provides a straightforward way to create custom roles.
Steps
Navigate to Access Management > Roles tab.
Click the Create Role button in the top-right corner.
Fill in the form:
Name - a human-readable name (max 100 characters). Must be unique within your company and cannot conflict with system role names.
Description (optional) - a short explanation of the role's purpose (max 500 characters).
Inherits From - select one or more existing roles (system or custom) that this role should inherit permissions from. The new role will automatically receive all permissions of the selected parent roles.
Click Create to create the role.
After creation, use Manage Users from the role's action menu to assign users.
What You Can Do in the UI
Create a custom role with a name, description, and inheritance
Edit name, description, and inherited roles of an existing custom role
Assign/remove users to/from a custom role
Delete a custom role (with impact summary)
What You Cannot Do in the UI
Important: The UI does not support defining granular permission policies (i.e., specifying which resources and actions a custom role can access beyond what it inherits). Inheritance is the only way to grant permissions through the UI.
If you need a custom role with specific resource/action permissions that no existing role provides, you must use the GraphQL API to add policies directly. See the section below.
Adding Policies via the GraphQL API
The Gatekeeper service exposes GraphQL mutations for managing policies directly. This is required when you need a custom role to have permissions that go beyond what it inherits from parent roles.
API Endpoint
The Gatekeeper GraphQL API is available at:
POST {GATEKEEPER_API_URL}/graphqlAdding a Policy to a Custom Role
Use the adminAddPolicy mutation to grant a specific resource/action permission to a custom role:
mutation AddPolicyToCustomRole {
adminAddPolicy(input: {
subject: "custom__my-role__a1b2c3d4"
subjectCompany: "own"
resource: "analytics"
objectCompany: "own"
objectOwner: "*"
action: "read"
effect: ALLOW
})
}Field reference:
Field | Description | Example values |
|---|---|---|
| The role ID to grant the permission to |
|
| Company scope for the subject |
|
| The resource to grant access to (from |
|
| Company scope for the resource |
|
| Ownership restriction |
|
| The action being granted (from |
|
| Allow or deny |
|
Adding Multiple Policies at Once
Use adminAddPolicies to add several permissions in a single call:
mutation AddMultiplePolicies {
adminAddPolicies(input: {
policies: [
{
subject: "custom__my-role__a1b2c3d4"
subjectCompany: "own"
resource: "analytics"
objectCompany: "own"
objectOwner: "*"
action: "read"
effect: ALLOW
},
{
subject: "custom__my-role__a1b2c3d4"
subjectCompany: "own"
resource: "analytics:chat-interactions"
objectCompany: "own"
objectOwner: "*"
action: "read"
effect: ALLOW
}
]
})
}Removing a Policy
Use adminRemovePolicy with the exact same fields to revoke a permission:
mutation RemovePolicy {
adminRemovePolicy(input: {
subject: "custom__my-role__a1b2c3d4"
subjectCompany: "own"
resource: "analytics"
objectCompany: "own"
objectOwner: "*"
action: "read"
effect: ALLOW
})
}Example 1: Custom Role Using Inheritance (UI Only)
Scenario: You want a "Senior Analyst" role that combines the permissions of Analytics Admin and Benchmarking Viewer - so users can view analytics dashboards and download benchmarking results, all in a single role assignment.
Steps
Go to Access Management > Roles.
Click Create Role.
Fill in:
Name:
Senior AnalystDescription:
Combines analytics and benchmarking read access for senior data team membersInherits From: Select
Analytics AdminandBenchmarking Viewer
Click Create.
Go to the new role's action menu > Manage Users > assign the relevant team members.
Result: Users assigned to "Senior Analyst" automatically inherit all permissions from both Analytics Admin (full analytics access) and Benchmarking Viewer (read-only benchmarking access). No API calls needed.
What the role looks like in Casbin
Behind the scenes, Gatekeeper creates:
A metadata record storing the role name and description
Two grouping policies (
grules):custom__senior-analyst__<id>inherits fromAnalytics_AdminandBenchmarking_ViewerUsers assigned to the role get a grouping policy linking them to
custom__senior-analyst__<id>
Example 2: Custom Role Using Policies (API Required)
Scenario: You want a "Feedback Reviewer" role that can read feedback data and read chat interactions analytics - but nothing else. No existing system role provides exactly this combination, so inheritance alone is not enough.
Step 1: Create the Role via UI
Go to Access Management > Roles.
Click Create Role.
Fill in:
Name:
Feedback ReviewerDescription:
Can read feedback and chat interaction analytics for quality review purposesInherits From: Leave empty (we will add specific policies instead)
Click Create.
Note the generated role ID (visible in the roles table, e.g.
custom__feedback-reviewer__f8e2a1c0).
Step 2: Add Policies via API
Call the Gatekeeper GraphQL API to grant the specific permissions:
mutation SetupFeedbackReviewerPolicies {
adminAddPolicies(input: {
policies: [
{
subject: "custom__feedback-reviewer__f8e2a1c0"
subjectCompany: "own"
resource: "feedback"
objectCompany: "own"
objectOwner: "*"
action: "read"
effect: ALLOW
},
{
subject: "custom__feedback-reviewer__f8e2a1c0"
subjectCompany: "own"
resource: "analytics:chat-interactions"
objectCompany: "own"
objectOwner: "*"
action: "read"
effect: ALLOW
}
]
})
}Step 3: Assign Users via UI
Back in the Access Management UI, go to the "Feedback Reviewer" role > Manage Users > assign the relevant team members.
Result: Users assigned to "Feedback Reviewer" can:
Read feedback data (but not write or delete)
Read chat interaction analytics (but not other analytics resources)
Nothing else - no chat access, no KB access, no space management, etc.
This provides much tighter access control than assigning a broad system role.
Combining Both Approaches
You can also create a role that uses both inheritance and custom policies. For example:
Create a role that inherits from
Chat_User(so users can chat)Add a custom policy granting
analytics:chat-interactionsREAD (so they can also view their team's chat usage stats)
This gives you the flexibility to start with a well-known base (system role) and layer on targeted additional permissions via the API.
Available Resources and Actions
When defining policies via the API, use these values:
Actions: read, write, delete, manage, create, list
Common resources:
Resource | Description |
|---|---|
| Chat conversations |
| Chat messages |
| Knowledge base content |
| Knowledge base folders |
| Spaces / assistants |
| Scope configuration |
| Scope access permissions |
| Feedback data |
| Benchmarking data |
| General analytics |
| Chat interaction analytics |
| Active users analytics |
| User chat export |
| Magic table feature |
| Due diligence feature |
| App repository |
| MCP connectors |
| User management |
| Group management |
| Group/role memberships |
For a complete list, refer to the GatekeeperResources enum in next/packages/backend/gatekeeper-utils/src/types/resources.ts.
Important Notes
Custom role IDs are auto-generated with the format
custom__<slugified-name>__<random-hex>. You cannot choose the ID.Role names must be unique within your company (case-insensitive) and cannot conflict with system role names.
Deleting a custom role removes all user assignments and inheritance links. Policies added via the API are also removed.
Policies added via the API are not visible in the UI - the UI only shows the role name, description, inheritance, and assigned users. Use the
adminPaginatedPoliciesquery to inspect policies.Inheritance is transitive - if Role A inherits from Role B, and Role B inherits from Role C, then users with Role A also get all permissions from Role C.