Skip to content

Grant Chat scopes

Decide which Chat Scope your backend client holds, and grant it on the Chat API resource. chat:sync is the simple choice. The granular scopes give an integration only what it needs.

A backend client on your tenant application. Scopes are granted to that client, never to a user.

A machine scope maps to Chat permissions (Capability). A machine client never gets messages.delete, administration or directory search, whatever its scopes. Reactions, read state and typing are user-only.

Scope Lets the client Chat permissions
chat:sync Everything below all of the permissions below
chat:conversations.read Read conversations, members and messages conversations.read, messages.read
chat:conversations.manage Create DIRECT conversations, update and archive conversations conversations.create, conversations.update
chat:groups.manage Create and manage GROUP conversations groups.create, groups.manage
chat:channels.manage Create and manage channels channels.create, channels.manage
chat:messages.send Send messages on behalf of a user, or SYSTEM messages messages.send
chat:users.lookup Search the tenant members Chat already knows users.lookup

Groups and channels also need chat:conversations.manage, because they are created and changed through the same routes as DIRECT conversations.

Your backend does this Grant
Creates and archives DIRECT conversations chat:conversations.manage
Also creates groups add chat:groups.manage
Also creates channels add chat:channels.manage
Sends messages for users, or SYSTEM messages chat:messages.send
Reads conversations and messages chat:conversations.read
Resolves names or emails to user ids chat:users.lookup

chat:access is a different kind of scope. It belongs to user tokens, and you grant it through token exchange, not here.

  1. Open the client. In the Identity Server admin UI, open your backend client on the tenant application.

  2. Open Resource Permissions. Pick the Chat API resource (identifier https://chat.centralcodestation.com/api, audience chat-api).

  3. Tick the scopes. Tick chat:sync, or the granular scopes from the table. Save.

  4. Match your code. ChatClient requests chat:sync by default. If you granted only granular scopes, set CHAT_SCOPE to the same list, space-separated, and pass it as the scope option.

const chat = new ChatClient({
/* ... */
scope: ['chat:conversations.manage', 'chat:messages.send'],
});

Every scope you request must be in the client’s grant, or the token request fails with invalid_scope.

Request a token with exactly the scopes you set.

Terminal window
curl -s -X POST "$CCS_ISSUER_URL/oauth/token" \
-u "$CCS_CHAT_SYNC_CLIENT_ID:$CCS_CHAT_SYNC_CLIENT_SECRET" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "scope=chat:conversations.manage chat:messages.send" \
--data-urlencode "resource=$CHAT_API_RESOURCE"

The response carries an access_token. Its scope claim lists the two scopes.

Symptom Cause and fix
invalid_scope from the token endpoint A requested scope is not in the client’s Resource Permissions for the Chat API. Tick it, or remove it from scope.
Chat answers 403 insufficient_scope or missing_capability The token has no scope that carries the permission the call needs. Check the table above.
invalid_target resource is the audience. Use the identifier.