Auth and Security
Both the REST client library and the Realtime client library use common authentication mechanisms. The two schemes supported by Ably are basic authentication, which uses your Ably API key, and token authentication, which uses short-lived tokens for access. These tokens are periodically renewed, and can be revoked if required.
Important: Token authentication is the recommended authentication mechanism on the client-side, as it provides more fine-grained access control and limits the risk of exposing your Ably API key. In production systems you should never use basic authentication on the client-side as it exposes your Ably API key. API keys don’t have an expiry, so once compromised, they could be used indefinitely by an attacker. Tokens have an expiry, and so there is only a small period of time during which the compromised token can be used. It is also possible to revoke tokens, should that be necessary for security reasons.
Important: You should never use token authentication server-side as this results in unnecessary overhead – the server would periodically require token requests to authenticate. For server-side, basic authentication is the recommended approach.
In summary, on the client-side use token authentication. On the server-side use basic authentication.
Tutorials & Examples
If you would like to just dive in and see an example of Ably authentication in code, then take a look at our client-server authentication tutorials.
Basic authentication
Every application has one or more private API keys that you set up and configure via the dashboard. These keys can be used to authenticate with Ably. It is recommended that private API keys are never shared with untrusted parties, and as such, should only be used by your trusted secure servers when authenticating with Ably.
Basic authentication is the simplest way to authenticate with Ably. It is as simple as:
var ably = new Ably.Realtime({ key: '<loading API key, please wait>' });
Demo OnlyCopyCopied!
Process used by client libraries connecting with basic auth:

While basic authentication is simple, Ably recommends that it is only used server-side because of the following potential issues:
- The secret is passed directly by the client to Ably, so it is not permitted for connections that are not over TLS (HTTPS or non-encrypted realtime connections) to prevent the key secret being intercepted.
- All of the configured capabilities of the key are implicitly possible in any request, and clients that legitimately obtain this key may then abuse the rights for that key.
- A client that authenticates using an API key can claim any client ID it chooses. Therefore this client ID cannot be trusted to represent the genuine identity of the client.
Token authentication
Client-side devices should generally be considered untrusted, and as such, it is important that you minimize the impact of any credentials being compromised on those devices. Token authentication achieves this by having a trusted device, such as one of your own servers, possessing an API key configured via the dashboard. It can then use the API key to distribute time-limited tokens with limited sets of access rights or capabilities, or with specific identities to untrusted clients.
Different token-issuing mechanisms can be used with Ably; the default is to use Ably Tokens which you request from Ably based on an Ably TokenRequest that you sign and issue from your servers to clients; or a JSON Web Token (JWT) which you generate on your servers and sign using your private API key. Token authentication, in most cases, is the recommended strategy on the client-side as it provides more fine-grained access control and limits the risk of exposed credentials being compromised.
Any of the following will cause the library to use token authentication:
- an
authUrl
orauthCallback
is provided that returns an Ably-compatible token or an AblyTokenRequest
; useTokenAuth
is true;- a
clientId
is provided (only for pre-1.1 client libraries); - a
token
ortokenDetails
property is provided
The last of those (providing a literal token
or tokenDetails
) is mostly only used for testing: since tokens are short-lived, in production you almost always want to use an authentication method that allows the client library to renew the token automatically when the previous one expires.
Please note that when setting up a mechanism to automatically renew tokens, an authURL
might be more relevant and recommended to be used with the web based clients as they can easily utilize cookies and other web-only features. However, in case of non-web clients, authCallback
is the recommended strategy.
Token authentication is typically done in one of four ways:
Ably TokenRequest is created by your servers and passed to clients
Token requests include a timestamp. So you should ensure that the machine on which you are running your auth server has an accurate clock, for example, by using an NTP daemon. If you are not able to control your machine’s clock, you may wish to use the queryTime
auth option to avoid ‘Timestamp not current’ errors.
Using an Ably Client Library SDK, a TokenRequest
is generated from your server and returned to the client-side SDK instance. The client-side SDK instance then uses the TokenRequest
to request an Ably Token from Ably, and subsequently authenticates using that Ably Token. This is the recommended approach for authentication as: an Ably TokenRequest
can be generated securely by your servers without communicating with Ably; your secret API key is never shared with Ably or your clients; Ably TokenRequests cannot be tampered with due to being signed, must be used soon after creation and can only be used once.

The following is an example of creating an Ably TokenRequest
:
const ably = new Ably.Rest({ key: '<loading API key, please wait>' });
ably.auth.createTokenRequest({ clientId: '[email protected]' }, null, (err, tokenRequest) => {
/* tokenRequest => {
"capability": "{\"*\":[\"*\"]}",
"clientId": "[email protected]",
"keyName": "{{API_KEY_NAME}}",
"nonce": "5576521221082658",
"timestamp": {{MS_SINCE_EPOCH}},
"mac": "GZRgXssZDCegRV....EXAMPLE"
} */
});
Demo OnlyCopyCopied!
Clients can pass this server-side generated tokenRequest
to Ably to authenticate with Ably automatically.
You can alternatively specify an authentication callback function when you create the Ably client. Inside authCallback
, you can make the network request to your servers to generate the tokenRequest
. For example:
const ablyClient = new Realtime({
authCallback: async (tokenParams, callback) => {
try {
const tokenRequest = await createTokenRequest() // Make a network request to your server
callback(null, tokenRequest)
} catch (error) {
callback(error, null)
}
}
});
CopyCopied!
The tokenParams
argument in authCallback
is available for convenience, allowing you to see the capabilities, clientId
, and other details requested by the client. However, tokenParams
should not be trusted or used to generate the tokenRequest
on the server side. Instead, it is recommended that your createTokenRequest
API authenticates clients separately: for example, based on cookies, headers, or HTTP body.
Ably Token is issued by your servers and passed to clients.
Using an Ably Client Library SDK, an Ably Token is requested by your servers from Ably and then passed to the client-side SDK instance. The client-side SDK instance then uses that Ably Token to authenticate with Ably. This is an alternative approach for authentication that enables you to issue Ably Tokens directly as opposed to providing Ably TokenRequests from your servers. The advantage for clients is it saves one round trip request as they do not need to request an Ably Token themselves. The disadvantage is that your servers must communicate with Ably each time an Ably Token is required.

The following is an example of issuing an Ably Token:
const ably = new Ably.Rest({ key: '<loading API key, please wait>' });
ably.auth.requestToken({ clientId: '[email protected]' }, (err, token) => {
/* token => {
"token": "xVLyHw.Dtxd9tuz....EXAMPLE",
"capability": "{\"*\":[\"*\"]}"
"clientId": "[email protected]",
"expires": 1449745287315,
"keyName": "{{API_KEY_NAME}}",
"issued": 1449741687315,
} */
});
Demo OnlyCopyCopied!
Ably JWT is created by your servers and passed to clients
In most scenarios, we would recommend you use one of the many JWT libraries available when constructing your JWT.
It is possible to use a JWT as a form of token for authentication with Ably, so long as it is structured appropriately, in what will be referred to as an Ably JWT. It is possible for an Ably JWT to contain claims indicating its clientId, capabilities and expiry – in an analogous way to an Ably Token – and it is signed with the applicable Ably API key’s secret part.
This is similar to signing an Ably TokenRequest
, but the client does not need then to request an Ably Token, instead being able to use the Ably JWT as a token in itself. Any compliant third-party JWT library may be used to create the JWT without requiring the token to be issued by Ably. This can be useful for situations where an Ably client library is not available, such as an embedded device connecting to Ably via MQTT.
Similarly to with the TokenRequest flow , you should ensure that your auth server has an accurate clock, as the JWT includes absolute “issued at” and “expires at” timestamps.
An example of creating an Ably JWT manually can be seen below, with SECRET being the secret part of your API key. In most scenarios however, we would recommend you use one of the many JWT libraries available for simplicity

The following is an example of creating an Ably JWT:
var header = {
"typ":"JWT",
"alg":"HS256",
"kid": "{{API_KEY_NAME}}"
}
var currentTime = Math.round(Date.now()/1000);
var claims = {
"iat": currentTime, /* current time in seconds */
"exp": currentTime + 3600, /* time of expiration in seconds */
"x-ably-capability": "{\"*\":[\"*\"]}"
}
var base64Header = btoa(header);
var base64Claims = btoa(claims);
/* Apply the hash specified in the header */
var signature = hash((base64Header + "." + base64Claims), "{{API_KEY_SECRET}}");
var ablyJwt = base64Header + "." + base64Claims + "." + signature;
CopyCopied!
Note: At present Ably does not support asymmetric signatures based on a keypair belonging to a third party. If this is something you’d be interested in, please get in touch.
Ably-compatible token is embedded in a External JWT from your server and passed to clients
If a system has an existing JWT scheme, it can be useful to embed an Ably-compatible token as a claim within it. The External JWT and embedded Ably-compatible token need to meet the following requirements:
- The embedded token is an Ably JWT, or an Ably Token
- The embedded token is included under the
x-ably-token
key in the JOSE Header - OR (if using JWS) the embedded token is included using the
x-ably-token
Claim in the payload - The expiry time of the embedded token must not be earlier than the outer JWT’s expiry time (
exp
Claim). Ably will reject any JWT if it is unencrypted and itsexp
Claim is later than the expiry of the enclosed token. This helps to ensure that tokens are renewed prior to expiry

The following is an example of issuing an Ably-compatible token inside the of header of a JWT:
const ably = new Ably.Rest({ key: '<loading API key, please wait>' });
ably.auth.requestToken({ clientId: '[email protected]' }, (err, tokenDetails) => {
var header = {
"typ":"JWT",
"alg":"HS256",
"x-ably-token": tokenDetails.token
}
var claims = {
"exp": currentTime + 3600
}
var base64Header = btoa(header);
var base64Claims = btoa(claims);
/* Apply the hash specified in the header */
var signature = hash((base64Header + "." + base64Claims), SECRET);
var jwt = base64Header + "." + base64Claims + "." + signature;
/* Send jwt to client */
});
Demo OnlyCopyCopied!
Note: The authenticity of the JWT will not be checked, due to Ably not having access to your SECRET key.
Using JWT for authenticated user claims
It is possible for JWTs to contain authenticated claims for users that can be used to allow or disallow certain interactions in your channels.
Messages can be annotated with trusted metadata copied from the client’s authentication token by Ably servers. Clients are unable to directly publish messages with user claim metadata, and claims contained within the authentication token are signed to prevent tampering. Claims can be scoped to individual channels or to namespaces of channels, see our namespaces documentation for more information. The most specific user claim will be added to the message as part of the extras
object.
Note: This does not apply to presence or metadata messages.
An example use case is when using Message Interactions. You might want to use trusted claims to define ‘moderator’ users in a chat channel who have the ability to delete any sent messages. When the moderator sends an interaction to mark messages in a channel as deleted, your application should check that user’s claims to verify they are a moderator for that channel before actioning their request.
To set the trusted fields you need to include ably.channel.*
in your JWT authentication payload, for example:
const claims = {
"sub": "1234567890",
"name": "John Doe",
"x-ably-capability": <...>,
"x-ably-clientId": <...>,
"ably.channel.chat1": "admin", // the user is an admin for the chat1 channel
"ably.channel.chat:*": "moderator", // the user is a moderator in channels within the chat namespace
"ably.channel.*": "guest", // the user is a guest in all other channels
}
CopyCopied!
The claims from the token are copied into messages, allowing them to be checked for permission:
const fromModerator = (message) => {
const userClaim = message.extras && message.extras.userClaim;
return (userClaim && userClaim == 'moderator');
}
CopyCopied!
Using JWT for per connection publish rate limits
JWTs may specify publish rate limits for a user on particular channels. These limits can be used to prevent any individual user from sending an excessive number of messages in a short period of time.
An example use case is in a large live chat where you may wish to limit users to posting messages no more than once every 10 seconds.
Rate limits can be scoped to individual channels or to channel namespaces. Note that the rate limit with the most specific scope will be applied to the user.
To set rate limits, include ably.limits.*
in your JWT authentication payload, for example:
const claims = {
"sub": "1234567890",
"name": "John Doe",
"x-ably-capability": <...>,
"x-ably-clientId": <...>,
"ably.limits.chat1": 10, // the user can publish 10 messages per second in channel chat1
"ably.limits.chat:*": 0.1 // the user can publish a message every 10 seconds in all channels within the chat namespace
}
CopyCopied!
Selecting an authentication mechanism
When deciding on which authentication method you will be using, it is recommended to bear in mind the principle of least privilege a client should ideally only possess the credentials and rights that it needs to accomplish what it wants; this way, if the credentials are compromised, the rights that can be abused by an attacker are minimized.
The table below should be used as a rough guide as to what you should consider when choosing your authentication method. Many applications will most naturally use a mixed strategy: one or more trusted application servers will use basic authentication to access the service and issue tokens over HTTPS, whereas remote browsers and devices will use individually issued tokens:
Scenario | Basic | Token | Description |
---|---|---|---|
Your scripts may be exposed | No | Yes | If the script, program or system holding the key is exposed, for example on a user’s device, you should not embed an API key and instead use Token Authentication. If the script is on a secure environment such as your own server, an API key with Basic Authentication is fine. |
Your connection may be insecure | No | Yes | If there is a risk of exposure of the client’s credentials, either directly or over an insecure, or insecurely proxied, connection, Token Authentication should be used. If you are sure the connection is secure and unmediated, Basic Authentication is acceptable. |
You have no server to control access | Yes | No | If you do not have your own server to perform authentication and provide tokens to users, you’ll need to use Basic Authentication. |
You require fine-grained access control | No | Yes | If you need to provide privileges on a user-by-user basis, you’d be better using Token Authentication. If you only need a few access control groups, Basic Authentication is reasonable. |
Users need restricted periods of access | No | Yes | If you need users to only have access for a certain period of time, or the ability to revoke access, Token Authentication is needed. If users are able to always have access, Basic Authentication is acceptable. |
Users need to identify themselves | Partial | Yes | If the user can be trusted to identify itself, Basic Authentication is fine. If the user cannot be trusted however, Token Authentication is better as it allows for a trusted token distributor to identify the user instead. |
Capabilities and Token Security explained
API keys, like Ably-compatible tokens, have a set of capabilities assigned to them that specify which operations (such as subscribe or publish) can be performed on which channels. However, unlike tokens, API keys are long-lived, secret and typically not shared with un-trusted clients.
API keys and their capabilities are configured using the dashboard, or using the Control API. Ably-compatible tokens are designed to be shared with un-trusted clients, are short-lived, and can be configured and issued programmatically. See selecting an authentication scheme to understand why token authentication is the preferred authentication scheme in many cases.
Capabilities with API keys
An Ably API key can have single set of permissions, applied to any number of channels or queues. To create a key with certain permissions, simply go to create a new API key and select the desired permissions.
You can also choose whether to restrict the API key to only channels, only queues, or to match a set of channel/queue names. If you’ve chosen to restrict the API key to selected channels and queues, you can use a comma separated list of resources the API key can access, making use of wildcards to provide access to areas of your app. It is worth noting an API key will provide the same permissions to all resources it has access to.
Capabilities with Tokens
Ably Tokens are issued from an existing API key, and their capabilities can, at most, match the capabilities of the issuing API key. Ably JWTs have a similar restriction on capabilities, correlating to the API key they’ve been signed with. If an API key must be shared with a third party, then it is recommended that the principle of least privilege is considered, assigning only the capabilities needed by that third party. Thus, any Ably requests authenticated using that API key or Ably-compatible tokens associated with that API key, will be restricted to the capabilities assigned to the API key.
Capability determination for Ably Tokens
- If no capability is specified in the Ably
TokenRequest
, then the Ably Token will be given the full set of capabilities assigned to the issuing key; see example. - If a set of capabilities are requested, then the Ably Token will be assigned the intersection of the requested capability and the capability of the issuing key, see example.
- If a set of capabilities are requested, and the intersection between those and the API key’s capabilities is empty (ie they are entirely incompatible), then the Ably Token request will result in an error, see example.
Capability determination for Ably JWTs
- The capabilities granted to an Ably JWT will be the intersection of the capabilities within the Ably JWT with the capabilities of the associated API key;
- If the set of capabilities within the Ably JWT have no intersection with the capabilities of the API key, then an error will instead be returned, see example.
See capability operations below for the complete set of supported operations on a channel.
Resource names and wildcards
Capabilities are a map from resources to a list of operations. Each resource can match a single channel e.g. channel
, or multiple channels using wildcards (*
). Wildcards can only replace whole segments (segments are delimited by :
) of the resource name. A wildcard at the end of the name can replace arbitrarily many segments. For example:
- A resource of
*
will match any normal channel (so not queues or metachannels, for which see below) - A resource of
namespace:*
will match any channel in thenamespace
namespace, includingnamespace:channel
, andnamespace:channel:other
- A resource of
foo:*:baz
will matchfoo:bar:baz
, but notfoo:bar:bam:baz
- A resource of
foo:*
will matchfoo:bar
,foo:bar:bam
,foo:bar:bam:baz
etc., as the wildcard as at the end - A resource of
foo*
(without a colon!) will only match the single channel literally calledfoo*
, which probably isn’t what you want
A resource can also be a queue, in which case it will start with [queue]
, e.g. [queue]appid-queuename
. (This is unambiguous as channel names may not begin with a [
). Similar wildcard rules apply, e.g. [queue]*
will match all queues.
A resource can also be a metachannel, in which case it will start with [meta]
, e.g. [meta]metaname
. (This is unambiguous as channel names may not begin with a [
). [meta]*
will match all metachannels. Just *
on its own will not: it will match all possible normal channels, but no metachannels.
You can also have a resource name of [*]*
, which will match all queues, all metachannels, and all channels.
Wildcards are also supported for operations, by requesting an operations list of ['*']
.
Capabilities example for API key
In order to define which capabilities an API key will have, simply select the appropriate capability boxes when setting up your API key. The structure to define channels and namespaces is structurally the same as defined in the above wildcards section.
Ably Token request without capabilities example
Given an API key exists with the following capabilities:
{
"chat": ["publish", "subscribe", "presence"],
"status": ["subscribe"]
}
CopyCopied!
If an Ably Token is requested without requiring any capabilities:
auth.requestToken(tokenCallback)
CopyCopied!
Then the request for an Ably Token is treated as requesting all capabilities, i.e. {"[*]*":["*"]}
), and all capabilities of the API key are assigned to the Ably Token. The capabilities for the issued Ably Token would be as follows:
{
"chat": ["publish", "subscribe", "presence"],
"status": ["subscribe"]
}
CopyCopied!
Ably Token is requested with intersection of capabilities example
Given an API key exists with the following capabilities:
{
"chat:*": ["publish", "subscribe", "presence"],
"status": ["subscribe", "history"],
"alerts": ["subscribe"]
}
CopyCopied!
And an Ably Token is requested with the following explicit capabilities:
auth.requestToken({ capability: {
"chat:bob": ["subscribe"], // only "subscribe" intersects
"status": ["*"], // "*"" intersects with "subscribe"
"secret": ["publish", "subscribe"] // key does not have access to "secret" channel
}}, tokenCallback)
CopyCopied!
Then Ably will intersect the API key’s capabilities and the requested capabilities ie Ably will satisfy the requested Ably Token’s capabilities as far as possible based on the capability of the issuing API key. The capabilities for the issued Ably Token would be as follows:
{
"chat:bob": ["subscribe"],
"status": ["subscribe", "history"]
}
CopyCopied!
Ably Token is requested with incompatible capabilities
Given an API key exists with the following capabilities:
{
"chat": ["*"]
}
CopyCopied!
And an Ably Token is requested with the following explicit capabilities:
auth.requestToken({ capability: {
"status": ["*"]
}}, tokenCallback)
CopyCopied!
Then Ably will be unable to issue an Ably Token because the intersection of the requested capabilities and the API key’s capabilities is empty – they are entirely incompatible. In the example above, requestToken
will call the callback with an error.
Capability operations
The following capability operations are available for API keys and issued tokens.
- subscribe
- can subscribe to messages and presence state change messages on channels, and get the presence set of a channel
- publish
- can publish messages to channels
- presence
- can register presence on a channel (enter, update and leave)
- history
- can retrieve message and presence state history on channels
- stats
- can retrieve current and historical usage statistics for an app
- push-subscribe
- can subscribe devices for push notifications
- push-admin
- can manage device registrations and push subscriptions for all devices in an app
- channel-metadata
- can get metadata for a channel, and enumerate channels
Read understanding capabilities and token security above to get a more thorough overview of how capabilities can be used to secure your application along with working examples.
While most of these capabilities need to be enabled for the resource you’re using them with, as described in resource names and wildcards above, there are exceptions. The stats
permission only does anything when attached to the wildcard resource '*'
(or a resource that contains that as a subset, such as '[*]*'
), since stats are app-wide. The channel-metadata
permission works both ways. When associated with a specific channel or set of channels it allows you to use the Channel Status API to request the status of that channel. When associated with the wildcard resource '*'
it takes on an additional meaning: as well as allowing channel status requests for all channels, it also allows you to enumerate all active channels
Understanding Identified clients
When a client is authenticated and connected to Ably, they are considered to be an authenticated client. However, whilst an authenticated client has a verifiable means to authenticate with Ably, they do not necessarily have an identity. When a client is assigned a trusted identity (ie a client ID
), then they are considered to be an identified client and for all operations they perform with the Ably service, their client ID
field will be automatically populated and can be trusted by other clients.
For example, assuming you were building a chat application and wanted to allow clients to publish messages and be present on a channel. If each client is assigned a trusted identity by your server, such as a unique email address or UUID, then all other subscribed clients can trust any messages or presence events they receive in the channel as being from that client. No other clients are permitted to assume a client ID
that they are not assigned in their Ably-compatible token, that is they are unable to masquerade as another client ID
.
In Ably a client can be identified with a client ID
in two ways:
- if the client is authenticated with an Ably-compatible token that is issued for that
client ID
; - if the client claims that
client ID
(as part ofClientOptions
in the constructor) and is authenticated with an Ably-compatible token that is issued for a wildcardclient ID
(a special token privilege that allows any client identity to be assumed)
We encourage customers to always issue Ably-compatible tokens to clients so that they authenticate using the short-lived token and do not have access to a customer’s private API keys. Since the customer can then control the client ID
that may be used by any of its clients, all other clients can rely on the validity of the client ID
in published messages and of members present in presence channels.
The following JavaScript example demonstrates how to issue an Ably Token with an explicit client ID
that, when used by a client, will then be considered an identified client.
const realtime = new Ably.Rest({ key: '<loading API key, please wait>' });
realtime.auth.createTokenRequest({ clientId: 'Bob' }, (err, tokenRequest) => {
/* ... issue the TokenRequest to a client ... */
})
Demo OnlyCopyCopied!
Token revocation
Token revocation is a mechanism that enables an app to invalidate authentication tokens. This invalidation can be used to force specified clients to re-obtain a token, and subsequently enables the app to modify the rights granted to clients, or to decline to re-issue a token.
The main use case of token revocation is as a method to combat malicious clients. In cases where the client behaves safely, you don’t need token revocation – your code can instruct the connection to Ably to close (or detach from a channel it shouldn’t have access to). But if you want to prevent any chance of a user obtaining the token before it is disconnected, and using it in their own custom client to gain access to Ably, then token revocation can be used.
Without token revocation, in order to restrict potential rogue access, you would make tokens with a short TTL (say 10 minutes) and then simply not issue a new token to a suspect client. Unfortunately, reducing the TTL would increase load on your authentication server, so token revocation can provide a more scalable solution to the issue of rogue clients. There is however a performance cost to using this feature.
Revocable tokens
Tokens are revocable if they are created from an API key that has token revocation enabled. This sets the revocableTokens
attribute to true
for the API key.
To enable token revocation for an API key:
- Sign into your Ably dashboard.
- Select the API Keys tab.
- Open the Settings for an existing API key or Create a new API key.
- Check the Revocable tokens field:

Note: Token revocation can only revoke tokens that were issued by an API key that had revocable tokens enabled before the token was issued.
Tokens created from an API key with revocable tokens enabled are restricted to a maximum TTL of 1 hour; an attempt to create, or present, a token that is revocable, but has a TTL of longer than 1 hr, is rejected with an error.
Initial connections to Ably and REST requests can incur a small latency cost when using revocable tokens.
Revocation keys
Designating a revocation key for a token, or a group of tokens, enables the revocation process to be used at any level of granularity, depending on the needs of the application. This method of revocation only works for JWTs, as traditional tokens do not contain this field.
To designate a revocation key, include the following additional claim in the JWT:
- x-ably-revocation-key
- a string used to identify which token(s) to revoke in the revocation request.
Token revocation API
Ably provides a token revocation API.
Target specifiers
A revocation request must include one or more target specifiers which define the token(s) that are affected by the request. Where multiple target specifiers are included, this is equivalent to making multiple independent revocation requests, each for a single target. The tokens affected by a request are those that match at least one of the target specifiers included in the request.
All target specifiers are formatted as: key:<string>
.
By default, supported target specifiers are:
- clientId
- This target specifier will match tokens that have the specified
clientId
. For example,targets: ["clientId:client1.example.com"]
matches tokens containing theclientId
ofclient1.example.com
. - revocationKey
- This target specifier will match tokens that have the specified
revocationKey
. For example:targets: ["revocationKey:users.group1.example.com"]
matches tokens containing therevocationKey
ofusers.group1.example.com
.
The following target specifier can also be enabled for you by Ably, should your use case require it:
- channel
- This target specifier will match tokens that exactly match one of the resource names present in the token capabilities. Note that this is not the same thing as revoking all tokens that have access to the channel. For example, a token with a capability of
{"foo:*": ["*"]}
will be revoked by a target ofchannel:foo:*
, but a revocation tochannel:*:*
will have no effect (even though that is a superset of the capabilities offoo:*
), and nor willchannel:foo:bar
(even for connections using the token to attach to that particular channel). It must be the exact string used in the token capabilities (which may be inherited from key capabilities).
API endpoint
The Ably REST API contains the following endpoint for token revocation:
POST /keys/{{keyName}}/revokeTokens
CopyCopied!
Where the keyName
is appId.keyId
.
In that request, the request body has the following form:
{
targets: [ "clientId:[email protected]", "clientId:[email protected]" ],
issuedBefore: 1636556083000,
allowReauthMargin: true
}
CopyCopied!
The request body has the following properties:
- targets
- An array of target specifier strings.
- issuedBefore
- Optional number (Unix timestamp in milliseconds); if not specified it is set to the current time. The token revocation only applies to tokens issued before this timestamp. A request with an
issuedBefore
in the future, or more than an hour in the past will be rejected. - allowReauthMargin
- Optional boolean. The
allowReauthMargin
boolean permits a token renewal cycle to take place without needing established connections to be dropped, by postponing enforcement to 30 seconds in the future, and sending any existing connections a hint to obtain (and upgrade the connection to use) a new token. It defaults tofalse
, meaning that the effect is near-immediate.
When invoking the revocation API, a client must prove possession of the key used to issue the tokens to be revoked. You can’t use a key to revoke a token issued from a different key. This can be done by using basic authentication, using the API key itself.
There can be a maximum of 100 target specifiers in a single request.
The token revocation API is rate-limited, so there is a maximum global aggregate rate of revocation requests per app. The rate is configurable by Ably at the application level. As part of the process of enabling revocation on an app Ably will ask you what the maximum rate of token revocations on that app needs to be, and then provision that capacity. The decision is not permanent, it can be changed by Ably on request at any time.
Note that revocation does not permanently forbid a client, connection, clientId
or channel. It invalidates token credentials issued before a certain point in time. Ultimately, the app that issues tokens is responsible for whether or not a client is able to continue to interact with the Ably service.
Examples
A sample request to revoke an Ably token based on clientId
, using the REST client library SDK:
const Ably = require('ably');
const ablyRest = new Ably.Rest({ key: '<loading API key, please wait>' });
const requestBody = { targets: ['clientId:[email protected]'] };
ablyRest.request('post', '/keys/{{API_KEY_NAME}}/revokeTokens', null, requestBody, null,
function (err, response) {
console.log(response);
if (!response.success) {
console.log('An error occurred; err = ' + response.errorMessage);
} else {
console.log('Success! status code was ' + response.statusCode);
}
}
);
Demo OnlyCopyCopied!
In this example, the token with the unique client ID [email protected]
would be revoked.
A sample request to revoke a JWT based on revocationKey
, using the REST client library SDK:
const Ably = require('ably');
const ablyRest = new Ably.Rest({ key: '<loading API key, please wait>' })
const requestBody = { targets: ['revocationKey:[email protected]'] }
ablyRest.request('post', '/keys/{{API_KEY_NAME}}/revokeTokens', null, requestBody, null,
function (err, response) {
console.log(response);
if (!response.success) {
console.log('An error occurred; err = ' + response.errorMessage);
} else {
console.log('Success! status code was ' + response.statusCode);
}
}
);
Demo OnlyCopyCopied!
In this example, all users that have been assigned the revocation key [email protected]
would have their tokens revoked.
Revocation errors
System error responses arising from the use of an invalidated token will include an Ably ErrorInfo
with a code
of 40141 and an informative error message. This includes REST API error responses, and Ably connection disconnected
state changes. Such a token error is non-fatal, which means that client libraries can react to that error by triggering a token renewal where the given library options allow (that is, if an authCallback
or authURL
is specified).
See also
See Revoke tokens in the REST API specification.
Further information
The following overviews are available:
The following API References are available: