Role-Based Permissions
Configure and manage user roles and granular permissions via the role management APIs.
This guide shows you how to manage user permissions in your organization using Concurrence's role management APIs.
What You'll Learn
How to create and manage roles for different user types
How to control what actions users can perform
How to assign roles to users
Common permission patterns and best practices
Getting Started
Every user in your organization has exactly one role. Roles define what actions users can perform, such as creating conversations, viewing data, or managing other users.
Basic concepts
Role: a set of permissions you assign to users (for example "Admin", "Moderator", "Viewer").
Permission: a specific action like "create conversation" or "view user data".
Conditions: rules that limit when permissions apply (for example "only in your organization").
Working with Role APIs
Return a list of roles in this organization.
Permissions
This endpoint may be impacted by the following permissions:
- Only roles that the authenticated user has the
Role:GetRolepermission on will be returned.
The username should be set to {org_id}_{user_id}, and the password should be the Amigo issued JWT token that identifies the user.
Amigo issued JWT token that identifies an user. It's issued either after logging in through the frontend, or manually through the SignInWithAPIKey endpoint.
An optional organization identifier that indicates from which organization the token is issued. This is used in rare cases where the user to authenticate is making a request for resources in another organization.
Whether to return permission grants.
falseThe IDs of the roles to retrieve.
[]The names of the roles to retrieve.
[]The Mongo cluster name to perform this request in. This is usually not needed unless the organization does not exist yet in the Amigo organization infra config database.
[]Succeeded
Invalid authorization credentials.
Missing required permissions.
Specified organization is not found.
Invalid request path parameter or request query parameter failed validation.
The user has exceeded the rate limit of 20 requests per minute for this endpoint.
The service is going through temporary maintenance.
GET /v1/{organization}/role/ HTTP/1.1
Host: api.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
X-ORG-ID: YOUR_API_KEY
Accept: */*
{
"roles": [
{
"id": "text",
"name": "text",
"description": "text",
"frontend_view": "client",
"permission_grants": [
{
"permission_name": "text",
"conditions": {
"ANY_ADDITIONAL_PROPERTY": {
"type": "Equals",
"value": null
}
}
}
]
}
]
}Create a new role.
Permissions
This endpoint requires the following permissions:
Role:CreateRolefor the role.
The username should be set to {org_id}_{user_id}, and the password should be the Amigo issued JWT token that identifies the user.
Amigo issued JWT token that identifies an user. It's issued either after logging in through the frontend, or manually through the SignInWithAPIKey endpoint.
An optional organization identifier that indicates from which organization the token is issued. This is used in rare cases where the user to authenticate is making a request for resources in another organization.
The Mongo cluster name to perform this request in. This is usually not needed unless the organization does not exist yet in the Amigo organization infra config database.
[]The name of the role to create. The role must have a max length of 256 characters.
A description about the role.
The frontend view for users of this role.
Succeeded
The ID of the newly created role.
Invalid authorization credentials.
Missing required permissions.
Specified organization or inherited role is not found.
Role with the same name already exists in this organization.
Invalid request path parameter or request body failed validation.
The user has exceeded the rate limit of 20 requests per minute for this endpoint.
The service is going through temporary maintenance.
POST /v1/{organization}/role/ HTTP/1.1
Host: api.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
X-ORG-ID: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 187
{
"role_name": "text",
"description": "text",
"permission_grants": [
{
"permission_name": "text",
"conditions": {
"ANY_ADDITIONAL_PROPERTY": {
"type": "Equals",
"value": null
}
}
}
],
"frontend_view": "client"
}{
"role_id": "text"
}Modify an existing role. The roles are modified in-place unless immutable fields are modified, in which case a new role with the same name is created, and all users/API keys assigned to the previous role are switched to the new role. The old role document will expire after 1 day.
Permissions
This endpoint requires the following permissions:
Role:ModifyRolefor the role.
This endpoint may require the authenticated user to have great privileges than the new role if a new role document is created as a result of immutable field changes.
The username should be set to {org_id}_{user_id}, and the password should be the Amigo issued JWT token that identifies the user.
Amigo issued JWT token that identifies an user. It's issued either after logging in through the frontend, or manually through the SignInWithAPIKey endpoint.
An optional organization identifier that indicates from which organization the token is issued. This is used in rare cases where the user to authenticate is making a request for resources in another organization.
The name of the role.
The Mongo cluster name to perform this request in. This is usually not needed unless the organization does not exist yet in the Amigo organization infra config database.
[]A description about the role. Only updated if specified. This field is a mutable field.
The frontend view for the user of this role. Only updated if specified. This field is an immutable field.
Succeeded
The identifier of the updated role.
Base roles cannot inherit from other roles.
Invalid authorization credentials.
Missing required permissions.
Specified organization, role, or inherited role is not found.
Invalid request path parameter or request body failed validation.
The user has exceeded the rate limit of 10 requests per minute for this endpoint.
The service is going through temporary maintenance.
POST /v1/{organization}/role/{role_name} HTTP/1.1
Host: api.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
X-ORG-ID: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 168
{
"description": "text",
"permission_grants": [
{
"permission_name": "text",
"conditions": {
"ANY_ADDITIONAL_PROPERTY": {
"type": "Equals",
"value": null
}
}
}
],
"frontend_view": "client"
}{
"role_id": "text"
}Assign a role to a user.
Permissions
This endpoint requires the following permissions:
- The authenticated user to have greater privileges than the role being assigned.
The username should be set to {org_id}_{user_id}, and the password should be the Amigo issued JWT token that identifies the user.
Amigo issued JWT token that identifies an user. It's issued either after logging in through the frontend, or manually through the SignInWithAPIKey endpoint.
An optional organization identifier that indicates from which organization the token is issued. This is used in rare cases where the user to authenticate is making a request for resources in another organization.
The name of the role to assign.
The Mongo cluster name to perform this request in. This is usually not needed unless the organization does not exist yet in the Amigo organization infra config database.
[]The identifier of the user to assign the role to.
Succeeded
The identifier of the role assigned to the user.
Invalid authorization credentials.
Missing required permissions.
Specified organization, role, or user is not found.
Invalid request path parameter or request body failed validation.
The user has exceeded the rate limit of 1000 requests per minute for this endpoint.
The service is going through temporary maintenance.
POST /v1/{organization}/role/{role_name}/assign HTTP/1.1
Host: api.amigo.ai
Authorization: Bearer YOUR_SECRET_TOKEN
X-ORG-ID: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 18
{
"user_id": "text"
}{
"role_id": "text"
}Creating Permission Rules
When creating roles, you define permission grants that specify what users can do. Each grant has two parts: the permission it grants and the conditions under which it applies.
Permission names
Permissions use a simple Category:Action format.
Conversation:CreateConversation: create new conversations.Conversation:GetConversation: view existing conversations.User:GetUserInfo: view user information.
Adding conditions
Conditions let you limit when permissions apply. For example, you might want users to only access data in their own organization:
The {self_org_id} placeholder automatically becomes the user's organization when the permission is checked.
Condition types
You can use these condition types to control when permissions apply.
Equals
Grant permission for a specific value
{"type": "Equals", "value": "premium_service"}
NotEquals
Grant permission for any value except one
{"type": "NotEquals", "value": "restricted_service"}
In
Grant permission for any of several values
{"type": "In", "values": ["basic", "premium", "enterprise"]}
Understanding Permission Behavior
How permissions are checked
When a user tries to perform an action, the system:
Looks at all permission grants in the user's role.
Finds grants for the permission being attempted.
Checks whether each grant's conditions are met.
If any grant for the permission matches with its conditions satisfied, the action is permitted.
If no grant matches, the action is denied.
What happens when permissions are missing
Different API endpoints handle missing permissions in different ways.
Some endpoints return errors:
Others filter results silently:
GetConversationsonly returns conversations you can access.GetUsersonly shows users you have permission to view.
Some hide specific fields:
If you do not have message-level access,
final_messagemay be empty inGetConversations.If you lack service-version access,
version_set_infomay be omitted inGetConversations.This prevents errors while protecting sensitive information.
Role hierarchy requirements
When managing other users' roles, you need sufficient privileges.
Inviting users: you can only assign roles with equal or fewer privileges than your own.
Creating API keys: API keys can only have roles with equal or fewer privileges than yours.
Modifying roles: you can only create or edit roles that have equal or fewer privileges than yours.
Common Role Examples
Content moderator
A role that can review admin-visible conversations and messages but cannot interact in them:
Because the role never grants Conversation:InteractWithConversation, moderators cannot send messages in the conversations they review - no explicit deny is needed.
Read-only user
A role that can only view their own conversations, never create or interact:
The role includes no grants for Conversation:CreateConversation or Conversation:InteractWithConversation, so viewers cannot create conversations or send messages - permissions that are not granted are denied by default.
Best Practices
Start simple
Begin with basic roles like "Admin", "User", and "Viewer" before creating more intricate permission structures.
Use organization scoping
Almost all permissions should include "org_id": {"type": "Equals", "value": "{self_org_id}"} to keep users within their organization.
Grant only what each role needs
The permission model is allow-only: anything not explicitly granted is denied. Design roles by granting the specific permissions they need, and rely on omission - not deny rules - to block everything else.
Test permission changes
Always test role modifications in a development environment before applying them to production users.
Document your roles
Use clear role names and descriptions so other developers understand their purpose.
Last updated
Was this helpful?

