Chat permissions
A Chat permission, called a capability in the API, answers one question: may this user perform this kind of operation? It never answers which users they may do it with. A tenant gives permissions to roles, separately for each application.
The permissions
Section titled “The permissions”Chat enforces 18 permissions. The reference lists each with the routes it unlocks: Capabilities.
| Area | Permissions |
|---|---|
| Conversations | conversations.create, conversations.read, conversations.update, conversations.delete |
| Groups | groups.create (create groups, and add members to a group you own), groups.manage (manage any group) |
| Channels | channels.create, channels.manage (manage any channel) |
| Messages | messages.send, messages.read (also needed for reactions, read state and typing), messages.update (your own messages), messages.delete (moderation: delete and edit other members’ messages) |
| Users | users.lookup (members Chat already knows), users.lookup.directory (the whole tenant directory at the Identity Server) |
| Attachments | attachments.upload, attachments.download |
| Administration | administration.read, administration.manage |
Direct conversations need only conversations.create. Groups and channels also need groups.create or channels.create.
Roles belong to the Identity Server
Section titled “Roles belong to the Identity Server”Chat defines no roles. System roles such as tenant_owner and tenant_admin, and your own such as coach and client, live in the Identity Server. Chat receives a user’s roles and maps them to permissions.
- The tenant owner or an admin holding
administration.managemaps roles to permissions in Chat Administration, under Roles and permissions. The mapping is stored at the Identity Server. - The mapping is per context. The tenant-wide mapping holds tenant-level permissions such as
administration.*. Each tenant application has its own mapping, and nothing is inherited between them. - Inside an application you can map the tenant’s roles and that application’s own roles, such as
coach. - <code dir="auto">tenant_owner</code> always holds every permission, in every context. It is shown locked and cannot be edited.
- Every other role starts with none,
tenant_adminincluded. The owner first grantstenant_adminwhat it should be able to do. - Platform roles never carry Chat permissions.
Being a member of a tenant does not imply Chat permissions either. A user whose roles have no grants cannot look up users, start conversations or create groups and channels.
A permission is not a relationship
Section titled “A permission is not a relationship”Take a Fitness app. Coach Ana may message her clients John and Sarah, but not a random member. That is a business rule. Chat has no idea what a coach is, so it cannot enforce it.
What Chat does enforce is the kind of operation:
| Rule | Who enforces it |
|---|---|
| “Ana may send messages” | Chat, with messages.send |
| “Ana may start a conversation” | Chat, with conversations.create |
| “Ana’s clients are John and Sarah” | Your backend, in your database |
Granting a permission applies to every holder of the role. If you gave the coach role conversations.create, any coach could open a chat with any tenant member who can use the application. That is exactly what your backend’s rules exist to prevent.
A user can take part without creating
Section titled “A user can take part without creating”Users do not need conversations.create or users.lookup to take part in a conversation someone else created. For a backend-driven integration, grant your roles only what they need inside existing conversations:
| Role | Chat permissions inside the Fitness application |
|---|---|
coach |
conversations.read, messages.read, messages.send, messages.update |
client |
conversations.read, messages.read, messages.send, messages.update |
Leave out conversations.create, groups.create and users.lookup. Your backend creates the conversations with a machine token instead; see Machine scopes.
How it shows up in the API
Section titled “How it shows up in the API”Each operation lists what it needs, for example sending a message:
messages.sendUser scope: chat:accessMachine scope (any of): chat:messages.sendA caller without the permission gets 403 missing_capability, and message names the permission. The permission is checked together with membership: holding messages.send does not let a user post to a conversation they are not in, which answers 403 not_conversation_member.
To show or hide controls, an app asks Chat what the signed-in user holds:
GET /api/v1/tenants/{tenant_id}/applications/{application_id}/me/capabilitiesThe response lists capabilities and the user’s roles for display. Chat enforces every permission on every call regardless of what the UI shows.
Related guides
Section titled “Related guides”- Grant permissions to roles
- Permission sets for standalone use
- Roles and permissions in Chat Administration