> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ably/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Token Authentication

Token authentication uses a trusted device with an [API key](/docs/pubsub/auth/overview#api-keys) to issue time-limited tokens to untrusted clients. Tokens have a limited set of access rights, known as [capabilities](/docs/auth/capabilities), and can have a specific [identity](/docs/auth/identified-clients) 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.

## How token authentication works

1. Your client calls `authUrl` or `authCallback` to request a token from your server.
2. Your server validates the client and returns a token (JWT, TokenRequest, or Ably Token).
3. The client uses this token to authenticate with Ably.
4. Tokens are short-lived and expire after a set period.
5. The client SDK automatically requests a new token before expiry, ensuring uninterrupted connectivity.

## Using authCallback

The `authCallback` is a function that the SDK calls when it needs a token. Your callback should request a token from your server and return it:

<Code>
  ```javascript theme={null}
  const realtime = new Ably.Realtime({
    authCallback: async (tokenParams, callback) => {
      try {
        const response = await fetch('https://your-server.com/auth', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(tokenParams)
        });
        const tokenRequest = await response.json();
        callback(null, tokenRequest);
      } catch (error) {
        callback(error, null);
      }
    }
  });
  ```

  ```python theme={null}
  async def auth_callback(token_params):
      response = await fetch('https://your-server.com/auth',
          method='POST',
          json=token_params)
      return await response.json()

  realtime = AblyRealtime(auth_callback=auth_callback)
  ```

  ```java theme={null}
  ClientOptions options = new ClientOptions();
  options.authCallback = new Auth.TokenCallback() {
      @Override
      public Object getTokenRequest(Auth.TokenParams params) {
          // Request token from your server
          return requestTokenFromServer(params);
      }
  };
  AblyRealtime realtime = new AblyRealtime(options);
  ```

  ```swift theme={null}
  let options = ARTClientOptions()
  options.authCallback = { tokenParams, callback in
      // Request token from your server
      requestTokenFromServer(tokenParams) { tokenRequest, error in
          callback(tokenRequest, error)
      }
  }
  let realtime = ARTRealtime(options: options)
  ```
</Code>

## Using authUrl

The `authUrl` is a URL that the SDK calls to obtain a token. The SDK will make an HTTP request to this URL and expect a token in the response:

<Code>
  ```javascript theme={null}
  const realtime = new Ably.Realtime({
    authUrl: 'https://your-server.com/auth'
  });
  ```

  ```python theme={null}
  realtime = AblyRealtime(auth_url='https://your-server.com/auth')
  ```

  ```java theme={null}
  ClientOptions options = new ClientOptions();
  options.authUrl = "https://your-server.com/auth";
  AblyRealtime realtime = new AblyRealtime(options);
  ```

  ```swift theme={null}
  let options = ARTClientOptions()
  options.authUrl = URL(string: "https://your-server.com/auth")
  let realtime = ARTRealtime(options: options)
  ```
</Code>

## Token types

Ably supports two token formats:

### JWT (recommended)

[JWTs](/docs/auth/token/jwt) 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

### Ably Tokens

[Ably tokens](/docs/auth/token/ably-tokens) are an alternative mechanism:

* TokenRequest: Server creates a signed request locally, client exchanges it with Ably
* Ably Token (direct): Server requests token from Ably, passes it to client

Use Ably Tokens when:

* Your capability list is very large (JWTs must fit within HTTP header limits)
* You need to keep capabilities confidential (clients can decode JWTs)

## 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:

1. Calls your auth endpoint when connecting
2. Requests a new token before the current token expires
3. 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](/docs/auth/revocation) has been enabled for the API key used to issue it.

<Aside data-type="important">
  Attempting to create a token with a TTL that exceeds these limits will result in an error.
</Aside>

## Server-side token generation

Your server should generate tokens using the Ably SDK. Here's an example:

<Code>
  ```javascript theme={null}
  const Ably = require('ably');
  const rest = new Ably.Rest({ key: 'YOUR_API_KEY' });

  app.post('/auth', async (req, res) => {
    const tokenParams = {
      clientId: 'user-123',
      capability: {
        'chat-room': ['publish', 'subscribe', 'presence']
      }
    };
    
    const tokenRequest = await rest.auth.createTokenRequest(tokenParams);
    res.json(tokenRequest);
  });
  ```

  ```python theme={null}
  from ably import AblyRest

  rest = AblyRest(key='YOUR_API_KEY')

  @app.post('/auth')
  async def auth():
      token_params = {
          'client_id': 'user-123',
          'capability': {
              'chat-room': ['publish', 'subscribe', 'presence']
          }
      }
      
      token_request = await rest.auth.create_token_request(token_params=token_params)
      return token_request
  ```

  ```java theme={null}
  import io.ably.lib.rest.AblyRest;

  AblyRest rest = new AblyRest("YOUR_API_KEY");

  Auth.TokenParams tokenParams = new Auth.TokenParams();
  tokenParams.clientId = "user-123";
  tokenParams.capability = "{\"chat-room\":[\"publish\",\"subscribe\",\"presence\"]}";

  Auth.TokenRequest tokenRequest = rest.auth.createTokenRequest(tokenParams, null);
  ```
</Code>

## Next steps

* Learn about [JWT authentication](/docs/auth/token/jwt)
* Learn about [Ably Tokens](/docs/auth/token/ably-tokens)
* Understand [capabilities](/docs/auth/capabilities) for access control
* Explore [identified clients](/docs/auth/identified-clients)
* Learn about [token revocation](/docs/auth/revocation)
