Authentication overview

Ably provides authentication mechanisms to ensure that only authorized clients can connect to its real-time infrastructure and access specific resources, such as channels or queues. This is crucial for maintaining data privacy and integrity in applications that rely on live data streams. The core principle involves verifying the identity of a client and then granting it permissions based on that identity. Ably distinguishes between authentication for server-side components, which typically handle sensitive API keys, and client-side components, which utilize more constrained, temporary tokens.

Effective authentication in real-time systems like Ably's involves managing access to various features, including publishing messages, subscribing to channels, presence tracking, and push notifications. Ably's approach prioritizes security while offering flexibility for different application architectures, from web browsers and mobile apps to backend services and IoT devices. All connections to Ably are secured using TLS/SSL, encrypting data in transit and protecting against eavesdropping and tampering, a standard practice for secure internet communication as described by the W3C Security FAQ.

Supported authentication methods

Ably primarily supports two authentication methods: API Keys and Token Authentication. Each method is designed for specific use cases and offers different levels of security and control.

API Keys

API keys are long-lived credentials generated from the Ably Dashboard. They provide full access to your Ably application, including the ability to create channels, publish messages, and manage other application settings. Due to their broad permissions, API keys are intended for use in trusted environments, such as your backend servers or during development. They should never be exposed in client-side code (e.g., web browsers, mobile apps) where they could be easily extracted and misused.

Token Authentication

Token authentication is the recommended method for client-side applications. It involves a two-step process:

  1. Your backend server generates an Ably Token Request, which specifies the client ID, capabilities (permissions), and an optional expiry time for the token.
  2. The server then signs this request using your Ably API key and sends it to the client.
  3. The client uses this signed token request to obtain a temporary token from Ably's servers. This token is then used to authenticate subsequent connections and operations.

Tokens offer granular control over permissions (e.g., a client can only subscribe to specific channels but not publish) and have a limited lifespan, enhancing security by reducing the window of opportunity for misuse if a token is compromised. This approach aligns with the principle of least privilege access, where users or systems are granted only the permissions necessary to perform their tasks.

Ably Authentication Methods Comparison
Method When to Use Security Level Credential Lifespan
API Key Backend servers, trusted environments, internal tools, development High (if kept secret) Permanent until revoked
Token Authentication Client-side applications (web, mobile), IoT devices, untrusted environments High (due to temporary, scoped access) Temporary (configurable expiry)

Getting your credentials

To use Ably, you'll need to obtain credentials from your Ably account dashboard. This process primarily involves generating API keys.

Generating API Keys

  1. Log in to your Ably Dashboard.
  2. Navigate to your application settings.
  3. Go to the 'API Keys' section.
  4. You will see a list of existing API keys. You can create a new API key by clicking 'Generate New API Key'.
  5. When generating a new key, you can configure its capabilities (permissions) to restrict what it can do. For example, you might create an API key that can only publish to a specific channel.
  6. Once generated, copy the API key. It will typically consist of an application ID and a secret key, separated by a colon (e.g., APP_ID.API_KEY_SECRET).

Remember to store your API keys securely and never hardcode them directly into client-side code or publicly accessible repositories. If an API key is compromised, you should revoke it immediately from the Ably Dashboard and generate a new one.

Configuring Token Authentication

For token authentication, you don't directly obtain a token from the dashboard. Instead, your backend server uses an API key to generate a 'token request' which is then used by the client to obtain a token from Ably. The Ably SDKs provide helper functions to simplify the generation of these token requests.

Authenticated request example

Here's an example of how to initialize the Ably client using an API key (for server-side code) and how a client might use a token generated by a backend (for client-side code).

Server-side authentication with an API Key (Node.js)


const Ably = require('ably');

// Replace with your actual Ably API Key
const ABLY_API_KEY = 'YOUR_ABLY_API_KEY'; 

const ably = new Ably.Realtime(ABLY_API_KEY);

ably.connection.on('connected', () => {
  console.log('Ably server-side client connected with API Key!');
  const channel = ably.channels.get('my-secure-channel');
  channel.publish('greeting', 'Hello from server!');
});

ably.connection.on('failed', (error) => {
  console.error('Ably server-side connection failed:', error);
});

Client-side authentication with a Token (JavaScript in a browser)

First, your backend would have an endpoint to generate the token request:


// Backend (Node.js example for generating a token request)
const Ably = require('ably');
const ABLY_API_KEY = 'YOUR_ABLY_API_KEY';

// This function would be exposed via an API endpoint
async function createTokenRequest(clientId) {
  const client = new Ably.Rest(ABLY_API_KEY);
  const tokenParams = {
    clientId: clientId,
    capability: {
      'my-secure-channel': ['subscribe', 'presence'] // Define client capabilities
    },
    ttl: 3600 * 1000 // Token valid for 1 hour
  };
  try {
    const tokenRequest = await client.auth.createTokenRequest(tokenParams);
    return tokenRequest;
  } catch (error) {
    console.error('Error creating token request:', error);
    throw error;
  }
}

// Example usage for an Express.js endpoint:
// app.get('/auth', async (req, res) => {
//   const clientId = req.query.clientId || 'anonymous';
//   try {
//     const tokenRequest = await createTokenRequest(clientId);
//     res.json(tokenRequest);
//   } catch (error) {
//     res.status(500).send('Failed to generate token');
//   }
// });

Then, the client-side code would fetch this token request and use it to authenticate:


// Frontend (browser-side JavaScript example)
async function connectAblyClient() {
  // Fetch token request from your backend server
  const response = await fetch('/auth?clientId=user123'); // Assuming your backend has an /auth endpoint
  const tokenRequest = await response.json();

  const ably = new Ably.Realtime({
    authUrl: '/auth?clientId=user123', // Ably will fetch the token from this URL
    authMethod: 'GET', // Or 'POST' depending on your backend
    authHeaders: { 'X-My-Custom-Header': 'value' }, // Optional custom headers for authUrl request
    // Alternatively, you can directly pass the tokenRequest object:
    // authCallback: async (tokenParams, callback) => {
    //   const response = await fetch('/auth?clientId=user123');
    //   const tokenRequest = await response.json();
    //   callback(null, tokenRequest);
    // }
  });

  ably.connection.on('connected', () => {
    console.log('Ably client connected with Token!');
    const channel = ably.channels.get('my-secure-channel');
    channel.subscribe('greeting', (message) => {
      console.log('Received:', message.data);
    });
  });

  ably.connection.on('failed', (error) => {
    console.error('Ably client connection failed:', error);
  });
}

connectAblyClient();

Security best practices

Implementing strong authentication is critical for securing your real-time applications. Adhere to these best practices when working with Ably:

  • Never expose API Keys in client-side code: API keys grant extensive permissions. Always use them exclusively on your trusted backend servers. For client-side applications, use token authentication.
  • Use Token Authentication for client-side access: Tokens provide temporary, revocable, and granularly scoped access. Generate them on your backend and serve them to clients. This limits the blast radius if a client-side token is compromised.
  • Implement strict token capabilities: When generating tokens, define the minimum necessary capabilities for each client. For example, if a client only needs to subscribe to a channel, do not grant it publish permissions. This adheres to the principle of least privilege.
  • Set appropriate token expiry times: Configure tokens to expire after a reasonable period, balancing security and user experience. Shorter expiry times reduce the risk of compromised tokens being used for extended periods. Ably tokens can be refreshed automatically by the client SDKs if an authUrl or authCallback is provided.
  • Secure your token generation endpoint: The backend endpoint responsible for generating Ably tokens must be secured. Implement appropriate authentication and authorization for this endpoint to ensure that only legitimate users can request tokens.
  • Rotate API Keys regularly: Periodically rotate your Ably API keys, especially if there's any suspicion of compromise. The Ably Dashboard allows you to revoke old keys and generate new ones.
  • Monitor access and usage: Utilize Ably's logging and monitoring features to detect unusual activity or unauthorized access attempts.
  • Use secure connection protocols: All Ably connections are automatically secured with TLS/SSL, ensuring encrypted communication between clients and Ably servers. Verify that your client environments are correctly configured to establish these secure connections.
  • Implement client ID management: Assign unique and meaningful client IDs to users or devices. This helps with auditing, debugging, and applying specific permissions based on identity.