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:

  1. Creating a custom role via the UI (with inheritance)

  2. Adding granular policies via the API (for advanced use cases)

  3. 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

  1. Navigate to Access Management > Roles tab.

  2. Click the Create Role button in the top-right corner.

  3. 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.

  4. Click Create to create the role.

  5. 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:

graphql
POST {GATEKEEPER_API_URL}/graphql

Adding a Policy to a Custom Role

Use the adminAddPolicy mutation to grant a specific resource/action permission to a custom role:

graphql
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

subject

The role ID to grant the permission to

custom__my-role__a1b2c3d4 or a system role like Chat_User

subjectCompany

Company scope for the subject

own (current company) or * (any)

resource

The resource to grant access to (from GatekeeperResources)

chat, content, analytics, benchmark, feedback, etc.

objectCompany

Company scope for the resource

own (same company) or * (any)

objectOwner

Ownership restriction

own (user's own data), * (any owner)

action

The action being granted (from GatekeeperPermissions)

read, write, delete, manage, create, list

effect

Allow or deny

ALLOW or DENY

Adding Multiple Policies at Once

Use adminAddPolicies to add several permissions in a single call:

graphql
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:

graphql
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

  1. Go to Access Management > Roles.

  2. Click Create Role.

  3. Fill in:

    • Name: Senior Analyst

    • Description: Combines analytics and benchmarking read access for senior data team members

    • Inherits From: Select Analytics Admin and Benchmarking Viewer

  4. Click Create.

  5. 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 (g rules): custom__senior-analyst__<id> inherits from Analytics_Admin and Benchmarking_Viewer

  • Users 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

  1. Go to Access Management > Roles.

  2. Click Create Role.

  3. Fill in:

    • Name: Feedback Reviewer

    • Description: Can read feedback and chat interaction analytics for quality review purposes

    • Inherits From: Leave empty (we will add specific policies instead)

  4. Click Create.

  5. 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:

graphql
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:

  1. Create a role that inherits from Chat_User (so users can chat)

  2. Add a custom policy granting analytics:chat-interactions READ (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

Chat conversations

message

Chat messages

content

Knowledge base content

folder

Knowledge base folders

assistant

Spaces / assistants

scope

Scope configuration

scope-access

Scope access permissions

feedback

Feedback data

benchmark

Benchmarking data

analytics

General analytics

analytics:chat-interactions

Chat interaction analytics

analytics:active-users

Active users analytics

analytics:user-chat-export

User chat export

magic-table

Magic table feature

due-diligence

Due diligence feature

app

App repository

mcp

MCP connectors

user

User management

group

Group management

membership

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 adminPaginatedPolicies query 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.

Last updated