Chat authentication is handled by the underlying Pub/Sub SDK. You authenticate an Ably Realtime client, then pass that authenticated client into ChatClient.
Authentication flow
- Your auth server authenticates the user.
- Your auth server issues an Ably-compatible token (JWT format is recommended for most apps).
- The client SDK fetches tokens with
authCallbackand refreshes them automatically before expiry. - The authenticated Pub/Sub client is passed into
ChatClient.
Server setup
Create an endpoint that validates user-provided credentials and returns JWTs with the appropriate Chat capabilities:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Server-side JWT with Chat capabilities
import jwt from 'jsonwebtoken';
const [keyName, keySecret] = process.env.ABLY_API_KEY.split(':');
const ablyJwt = jwt.sign(
{
'x-ably-capability': JSON.stringify({
// Only allow access to a specific room
'your-room': ['publish', 'subscribe', 'presence', 'history'],
}),
'x-ably-clientId': userId,
},
keySecret,
{ algorithm: 'HS256', keyid: keyName, expiresIn: '1h' }
);Client setup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import * as Ably from 'ably';
import { ChatClient } from '@ably/chat';
const realtimeClient = new Ably.Realtime({
authCallback: async (tokenParams, callback) => {
try {
const response = await fetch('/api/ably-token', { credentials: 'include' });
if (!response.ok) throw new Error('Auth failed');
const jwt = await response.text();
callback(null, jwt);
} catch (error) {
callback(error, null);
}
},
});
const chatClient = new ChatClient(realtimeClient);In each example, the authenticated Pub/Sub client is passed into ChatClient and Chat uses that connection for authentication and token renewal.
Chat capabilities
Capabilities are permissions that control what operations a client can perform. When you create a token for a Chat user, you specify which capabilities they have. Each Chat feature requires specific capabilities:
| Feature | Required Capabilities |
|---|---|
| Send messages | publish |
| Receive messages | subscribe |
| Update messages | message-update-any or message-update-own |
| Delete messages | message-delete-any or message-delete-own |
| Message history | subscribe, history |
| Message reactions | annotation-publish, optionally annotation-subscribe |
| Presence | subscribe, presence |
| Typing indicators | publish, subscribe |
| Room reactions | publish, subscribe |
| Occupancy | subscribe, channel-metadata |
| All Chat features | publish, subscribe, presence, history, channel-metadata, annotation-publish, annotation-subscribe, message-update-own, message-delete-own |
Room-scoped capabilities
You can scope capabilities to specific rooms, a namespace of rooms, or all rooms:
my-chat-room- a specific roomdms:*- all rooms in thedms:namespace*- all chat rooms
Token lifecycle and permission updates
- With
authCallbackorauthUrl, token refresh is automatic and handled by the SDK. - To change a user's capabilities during an active session, issue a new token from your auth server and re-authenticate:
1
2
// Re-authenticate to pick up updated capabilities
await realtimeClient.auth.authorize();- To immediately remove access, revoke issued tokens.
- If your capability JSON is too large for JWT or must remain confidential, use native Ably Tokens.