Warning: You are viewing an old version (0.8) of this documentation. We recommend you view the latest version 1.2.
REST Client Library API

Authentication

Ably clients can authenticate with Ably using Basic Authentication (which uses the customer’s API key), Token Authentication (which relies on a token customers obtain from Ably), or a token request that customers sign and issue to their clients. Token Authentication, in most cases, is the recommended strategy as it provides robust access control and stringent security measures.

Understanding the Ably authentication schemes

This page of documentation is intended to describe the Rest Authentication API and is not intended to explain in depth how Ably’s authentication works. If you are new to Ably and/or the authentication schemes, we strongly recommend that you get acquainted with the following first:

Basic Authentication

Basic Authentication uses one of the api keys configured via the application dashboard as the authentication token. Basic Authentication is the simplest method to use but has some important limitations described in detail in the Basic Authentication documentation.

Here is a straightforward example of using Basic Authentication when instancing a Ably REST client library.

var rest = new Ably.Rest({ key: 'xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U' });
var rest = new Ably.Rest({ key: 'xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U' });
rest = Ably::Rest.new(key: 'xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U')
rest = AblyRest(key='xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U')
$rest = new Ably\AblyRest(array('key' => 'xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U'));
ClientOptions options = new ClientOptions();
options.key = "xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U";
AblyRest rest = new AblyRest(options);
AblyRest rest = new AblyRest("xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U");
let rest = ARTRest(key: "xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U")
ARTRest *rest = [[ARTRest alloc] initWithKey:@"xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U"];

Token Authentication

Token Authentication uses a token obtained via the REST API requestTokenRequestTokenrequest_token endpoint to authenticate with Ably. Tokens are authentication credentials that are short-lived, and therefore they may more readily be distributed to clients where there is a risk of compromise. Tokens may also be issued with a particular scope – such as a limited set of access rights or capabilities or being limited to use by a specific clientIdClientId identity – and therefore token-based authentication provides the flexibility to implement access and identity control policies in the application. See the Token Authentication documentation for more details.

When using Token Authentication, the REST client library will typically be instantiated with a means to obtain a token as opposed to a short-lived token so that when the token expires, the library can assume responsibility to automatically obtain a new token and seamlessly continue operations with Ably. Conversely, if a library is instantiated with a previously obtained Token by setting the :token or :token_detailstoken or token_detailsToken or TokenDetailstoken or tokenDetails attributes of ClientOptions, when the token expires, the client will no longer be able successfully issue REST requests to Ably as the library has no means to obtain a new token. It is therefore recommended that all client libraries that use token authentication have a means to issue new tokens using either the auth_url or auth_callbackAuthUrl or AuthCallbackauthUrl or authCallback attribute of ClientOptions when instancing the library.

Below is a rather contrived yet straightforward example that instances a Rest library using Token Authentication with a means to reissue tokens as required. Typically, in a browser environment, the authUrlAuthUrl provided would be a relative URL to a local endpoint that is used to issue tokens to trusted clients. Client requests can, for example, be trusted based on session cookies. For non-browser clients, an authentication callback is preferred thus relying on your application to communicate securely with your own servers to obtain a token.

var rest = new Ably.Rest({ authUrl: 'https://my.website/auth' });
var rest = new Ably.Rest({ authUrl: 'https://my.website/auth' });
rest = Ably::Rest.new(auth_url: 'https://my.website/auth')
rest = AblyRest(auth_url='https://my.website/auth')
$rest = new Ably\AblyRest(array('authUrl' => 'https://my.website/auth'));
ClientOptions options = new ClientOptions();
options.authUrl = "https://my.website/auth";
AblyRest rest = new AblyRest(options);
AblyRest rest = new AblyRest(new ClientOptions { AuthUrl = new Uri("https://my.website/auth") });
ARTClientOptions *options = [[ARTClientOptions alloc] init];
options.authUrl = [NSURL URLWithString:@"https://my.website/auth"];
ARTRest *rest = [[ARTRest alloc] initWithOptions:options];
let options = ARTClientOptions()
options.authUrl = NSURL(string: "https://my.website/auth")
let rest = ARTRest(options: options)

Auth object

The principal use-case for Auth object is to create signed token request objects or obtain tokens from Ably, and then issue them to other “less trusted” clients. Typically, your servers should be the only devices to have a private API key, and this private API key is used to securely sign token requests or request tokens from Ably. Clients are then issued with short-lived tokens or token requests, and the libraries can then use these to authenticate with Ably. If you adopt this model, your private API key is never shared with clients directly.

A subsidiary use-case for the Auth object is to preemptively trigger renewal of a token or to acquire a new token with a revised set of capabilities by explicitly calling authorizeAuthorize.

Identified clients

When a client has valid credentials to issue requests 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 (i.e. a client_idClientIdclientId), then they are considered to be an identified client and for all operations they perform with the Ably service, their client_idClientIdclientId 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 on a channel via REST. 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 they receive in the channel as being from that client. No other clients are permitted to assume a client_idClientIdclientId that they are not assigned in their token or token request, that is they are unable to masquerade as another client_idClientIdclientId.

In Ably a client can be identified with a client_idClientIdclientId in three ways:

We encourage customers to always issue 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_idClientIdclientId that may be used by any of its clients, all other clients can rely on the validity of the client_idClientIdclientId in published messages.

The following example demonstrates how to issue a token with an explicit client_idClientIdclientId that, when used by a client, will then be considered an identified client.

var rest = new Ably.Rest({ key: 'xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U' });
rest.auth.createTokenRequest({ clientId: 'Bob' }, function(err, tokenRequest) {
  /* ... issue the TokenRequest to a client ... */
})
var rest = new Ably.Rest({ key: 'xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U' });
rest.auth.createTokenRequest({ clientId: 'Bob' }, function(err, tokenRequest) {
  /* ... issue the TokenRequest to a client ... */
})
rest = Ably::Rest.new(key: 'xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U')
token_request = rest.auth.create_token_request(client_id: 'Bob')
# ... issue the TokenRequest to a client ...
rest = AblyRest(key='xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U')
token_request = rest.auth.create_token_request(client_id='Bob')
# ... issue the TokenRequest to a client ...
$rest = new Ably\AblyRest(array('key' => 'xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U'));
$tokenRequest = $rest->auth->createTokenRequest(array('clientId' => 'Bob'));
# ... issue the TokenRequest to a client ...
ClientOptions options = new ClientOptions();
options.key = "xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U";
AblyRest rest = new AblyRest(options);
TokenParams tokenParams = new TokenParams();
tokenParams.clientId = "Bob";
TokenRequest tokenRequest;
tokenRequest = rest.auth.createTokenRequest(tokenParams, null);
/* ... issue the TokenRequest to a client ... */
AblyRest rest = new AblyRest(new ClientOptions {Key = "xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U"});
TokenParams tokenParams = new TokenParams {ClientId = "Bob"};
string tokenRequest = await rest.Auth.CreateTokenRequestAsync(tokenParams);
// ... issue the TokenRequest to a client ...
ARTRest *rest = [[ARTRest alloc] initWithKey:@"xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U"];
ARTTokenParams *tokenParams = [[ARTTokenParams alloc] initWithClientId:@"Bob"];
[rest.auth createTokenRequest:tokenParams options:nil
  callback:^(ARTTokenRequest *tokenRequest, NSError *error) {
    // ... issue the TokenRequest to a client ...
}];
let rest = ARTRest(key: "xVLyHw.8Lf9oQ:7feO8sW-sGTv6eUcuIs4-1O7yohHRZOuIB7fOmo3J4U")
let tokenParams = ARTTokenParams(clientId: "Bob")
rest.auth.createTokenRequest(tokenParams, options: nil) { tokenRequest, error in
  // ... issue the TokenRequest to a client ...
}

API Reference

View the Authentication API Reference.


Need help?

If you need any help with your implementation or if you have encountered any problems, do get in touch. You can also quickly find answers from our knowledge base, and blog.