Token authentication uses a trusted device with an API key to issue time-limited tokens to untrusted clients. Tokens have a limited set of access rights, known as capabilities, and can have a specific identity using a clientId.
Token authentication is the recommended authentication method to use client-side for the following reasons:
- Tokens ensure that an Ably API key isn't exposed in client applications.
- Tokens are short-lived so there is only a short period of time during which a compromised token can be used.
- Tokens provide more fine-grained access control, which also limits the area of exposure a compromised token can access.
- Tokens support functionality not available with Basic auth, such as user claims.
Choosing a token mechanism
Ably supports two token formats: JWT, the primary and recommended format, and Ably tokens, a legacy format. Each format is associated with a different flow for issuing tokens to clients.
JWT format (recommended)
JWTs are the recommended approach for most applications:
- No Ably SDK required on your server. Any JWT library works.
- Supports channel-scoped claims for trusted metadata
- Supports per-connection rate limits
- Stateless and ideal for serverless environments
Use JWTs unless your capability list is very large (JWTs must fit within HTTP header limits, typically around 8 KB) or you need to keep capabilities confidential (clients can decode JWTs).
Native Ably Token formats
Ably tokens are an alternative mechanism that predates Ably's JWT support. Unlike JWTs, Ably tokens are not generated by a client but are issued by the Ably service via a /requestToken endpoint. Integrating Ably tokens is more involved, and they do not support all functionality available with JWTs. Use native Ably Tokens when JWTs are not suitable:
- TokenRequest: Server creates a signed request locally, client exchanges it with Ably
- Ably Token (direct): Server requests token from Ably, passes it to client
- Embedded Token JWT: If you need a single app token format, you can wrap Ably credentials in an outer JWT used by your existing auth system
How token authentication works
- Your client calls
authUrlorauthCallbackto request a token from your server. - Your server validates the client and returns a token (JWT, TokenRequest, or Ably Token).
- The client uses this token to authenticate with Ably.
- Tokens are short-lived and expire after a set period.
- The client SDK automatically requests a new token before expiry, ensuring uninterrupted connectivity.
Token refresh
One of the important benefits of using an Ably SDK is that automatic token refresh is handled for you.
When you provide either an authUrl or an authCallback, the SDK automatically:
- Calls your auth endpoint when connecting
- Requests a new token before the current token expires
- Maintains the connection seamlessly during refresh
Token TTL limits
Ably enforces maximum TTL (time-to-live) limits:
- Access tokens: Maximum TTL of 24 hours.
- Device tokens (for push notifications): Maximum TTL of 5 years.
- Revocable tokens: Maximum TTL of 1 hour. A token is revocable if token revocation has been enabled for the API key used to issue it.
Dynamic channel access control
Token authentication allows you to dynamically change a client's channel access permissions without disconnecting. Use the authorize() method to re-authenticate with updated capabilities.
When you call client.auth.authorize():
- The client obtains a new token with different capabilities from your authentication server.
- The new token is sent to Ably using the existing realtime connection.
- The updated permissions are automatically applied without disconnecting.
Use cases
You can trigger re-authentication in response to:
- Detect error code 40160 when a client attempts to attach to a channel.
- Instruct clients to re-authenticate via Ably channels or other communication methods.
The following example shows how to re-authenticate with updated capabilities:
1
2
3
4
5
6
7
8
9
10
// Re-authenticate to get new capabilities
try {
const newTokenDetails = await client.auth.authorize({
clientId: 'user123',
// Your auth server will return a token with updated capabilities
});
console.log('Successfully updated permissions');
} catch (error) {
console.error('Failed to re-authenticate:', error);
}For security purposes, handle non-compliant clients by:
- Set shorter token TTL expiry times to force frequent re-authentication (minimum 10 minutes recommended).
- Use the token revocation API to immediately invalidate tokens.
Server clock requirements
The machine that is used to sign JWTs (or sign TokenRequests, in the case of using Ably tokens) should have an accurate clock, as tokens and TokenRequest contain a timestamp. You can use an NTP daemon, or if you are not able to control your server's clock, you can use the queryTime auth option.
Access restrictions
Token-based client validation
Token authentication enables you to validate client characteristics (such as origin, IP address, cookies, or any other client features) in your authentication server before issuing tokens. This provides flexible access control as you can implement any validation logic in your auth server as part of the token issuance process.
API key restrictions
For cases where token authentication is impractical, Ably can add origin or IP address restrictions directly to API keys. However, this approach has significant limitations:
- Available to enterprise support packages only.
- Changes require contacting Ably support; restrictions cannot be updated programmatically or self-served.
- Not a security boundary: origin headers can be easily spoofed, especially outside browser contexts.
- Permissive fallback: requests with no origin header are allowed when origin restrictions are set.
Token authentication with server-side validation is recommended over API key restrictions wherever possible.
Embedded Token JWT
If you have an existing JWT authentication system, you can embed an Ably Token as a claim within your JWT. This allows you to use your existing auth infrastructure while providing Ably authentication.
Requirements
- The embedded token must be an Ably Token (not a JWT).
- The embedded token is included under the
x-ably-tokenkey in the JOSE Header, or if using JWS, in the payload claims. - The expiry time of the embedded token must not be earlier than the outer JWT's expiry time (
expclaim). Ably will reject any JWT if it is unencrypted and itsexpclaim is later than the expiry of the enclosed token.
When to use
- You already have a JWT-based authentication system
- You want to avoid changing your client authentication flow
- You need the capability hiding features of Ably Tokens but want to use your existing JWT infrastructure
Server examples
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const ably = new Ably.Rest({ key: 'demokey:*****' });
const tokenDetails = await ably.auth.requestToken({ clientId: '[email protected]' });
const header = {
"typ":"JWT",
"alg":"HS256",
"x-ably-token": tokenDetails.token
}
const claims = {
"exp": currentTime + 3600
}
const base64Header = btoa(header);
const base64Claims = btoa(claims);
/* Apply the hash specified in the header */
const signature = hash((base64Header + "." + base64Claims), SECRET);
const jwt = base64Header + "." + base64Claims + "." + signature;
/* Send jwt to client */What triggers token authentication
Any of the following cause an SDK to use token authentication:
- An
authUrlorauthCallbackis provided. useTokenAuthis true.- A
tokenortokenDetailsproperty is provided.
Providing a literal token or tokenDetails is typically used for testing: since tokens are short-lived, in production you typically want to use an authentication method that allows the client library to renew the token automatically as the current token expires.
Next steps
- JWTs - Recommended approach for most applications
- Ably Tokens - Alternative when JWTs aren't suitable
- Capabilities - Control what operations clients can perform
- Identified clients - Assign trusted identities to clients
- Token revocation - Immediately invalidate tokens