Authentication

AI Transport authenticates at three layers: an Ably token for the channel, HTTP credentials for the agent endpoint, and a server-side hook that authorises cancel signals.

Authentication in AI Transport operates at three levels: Ably token authentication for channel access, HTTP credentials for agent endpoint authorisation, and cancel authorisation for controlling who can stop a Run. Each layer is independent and addresses a different trust boundary.

For the practical setup (signing tokens, wiring authCallback, securing the agent POST), see Set up authentication.

The three layers

LayerWhat it protectsHow it works
Ably tokenChannel publish, subscribe, history, presence.Your server signs a short-lived JWT that names the user's clientId and capabilities. The client SDK fetches it via authCallback and refreshes before expiry.
Agent endpointThe HTTP POST that wakes the agent.Your application's normal endpoint auth: cookies, bearer tokens, signed headers. Carries no AI-Transport-specific semantics.
Cancel authorisationWho can stop a Run.An onCancel hook on the agent's RunRuntime. The agent inspects the cancel sender and accepts or rejects.

The Ably token controls what can land on the channel. The agent endpoint auth controls who can trigger a Run. Cancel authorisation controls who can stop one that's already running. Different concerns, separately enforced.

Authentication flow

  1. Your auth server authenticates the user.
  2. Your auth server issues an Ably-compatible token (JWT format is recommended for most apps).
  3. The client SDK fetches tokens through authCallback and refreshes them automatically before expiry.
  4. The authenticated Ably Realtime client provides channels to AI Transport via the session providers.

AI Transport capabilities

Capabilities are permissions on the Ably channel. When you issue a token for an AI Transport user, the capability claim names which operations they can perform on which channels.

FeatureRequired capabilities
Send user messages to channelpublish
Receive streamed tokenssubscribe
Replay history on reconnectsubscribe, history
Cancel a Runpublish
Read and write shared objectsobject-subscribe, object-publish
All AI Transport featurespublish, subscribe, history

A token that's missing a capability fails silently at the operation site, not at construction. Capability mismatches are one of the most common setup mistakes; see troubleshooting: capability or token scope mismatch.

Channel-scoped capabilities

Capabilities are keyed by channel name pattern. The same token can grant different operations on different channels:

  • my-conversation: a specific conversation channel.
  • conversations:*: all channels in the conversations: namespace.
  • *: all channels.

Scope tokens to the smallest channel set the user needs. A user's token granting access to one conversation should name that conversation, not the whole namespace.

Token lifecycle and permission updates

  • With authCallback or authUrl, token refresh is automatic. The SDK fetches a new token before the current one expires.
  • To change a user's capabilities mid-session, issue a new token from your auth server and re-authenticate the client:
JavaScript

1

await realtimeClient.auth.authorize();
  • To immediately remove access, revoke issued tokens.
  • If your capability JSON is too large for a JWT claim, or must remain confidential, use native Ably Tokens instead.

Agent endpoint authentication

The HTTP POST that wakes the agent is a separate request from anything on the Ably channel. It carries application credentials (a session cookie, a bearer token, or whatever your endpoint normally expects). The Ably token does not authenticate this POST; the agent endpoint authenticates it through your own application auth.

On the core flow, the application owns the POST and sets credentials in its fetch call. On the Vercel flow, ChatTransportProvider accepts a credentials prop and a chatOptions.prepareSendMessagesRequest hook that returns { body?, headers? } per request, which the transport merges into every invocation POST.

Cancel authorisation

When a client publishes a cancel signal, the agent decides whether to honour it. The onCancel hook on RunRuntime receives a CancelRequest carrying the raw Ably cancel message and the runId it targets. Compare the cancel sender's clientId against whichever identity your application considers authorised; here, the user identity resolved from the inbound HTTP request:

JavaScript

1

2

3

4

5

6

7

8

const userId = await authenticateUser(req);

const run = session.createRun(invocation, {
  signal: req.signal,
  onCancel: async (request) => {
    return request.message.clientId === userId;
  },
});

Return true to allow the cancel (the abortSignal fires, the stream closes). Return false to reject it (the Run continues). If onCancel is not provided, every cancel is accepted.

The Ably token's clientId is verified by the Ably service before the cancel reaches the agent, so the clientId on the cancel message is trustworthy; the agent can authorise off it without independent verification.