Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tokens

Clients authenticate with access tokens.

Token format

Access tokens are strings like:

AT_<token_id>_<secret>

  • token_id: 16 bytes encoded in hex (32 hex characters)
  • secret: 16 bytes encoded in hex (32 hex characters)

Tokens are created by an admin via the REST API and given to clients.

Token lifetime (expires_at)

Each token has an expiry time:

  • expires_at: ISO 8601 (example: 2026-02-10T12:00:00Z)
  • Maximum TTL: 24 hours. The expires_at field must not exceed 24 hours from the current server time. Requests with a longer TTL are rejected (HTTP 400 / gRPC INVALID_ARGUMENT).
  • After expiry, authentication fails for new connections.
  • To keep a token alive longer than 24 hours, use PUT /v1/refresh-token (or gRPC RefreshToken) to extend it periodically (up to 24 hours each time).

Some deployments support graceful deactivation without forcing disconnects: set expires_at to a past time via refresh. New authentications fail, and the token is removed shortly after. Details depend on deployment and are described in Client configuration.

Permissions

Each token carries a list of tenant_grants that define:

  • allow_channels_pub: which channels the client can publish to (pub-token rules – literals, alternatives, #, >, but no ? or *).
  • allow_channels_sub: which subscription patterns the client is allowed to send (sub-token rules – full syntax with ?, *, alternatives, #, >).

Both use similar dot-separated segment syntax with alternatives and tail wildcards. The key difference: publish rules do not allow ? and *, because publish targets are always concrete channel names. Subscribe rules allow ? and * because subscription patterns can contain wildcards.

Full details, syntax, and examples: Permissions model.

Network restrictions (optional)

Tokens may restrict where they can be used:

  • allow_ip_masks: list of exact IPs or CIDR ranges. If non-empty, only clients with matching IPs can authenticate.
  • allow_regions: list of regions where authentication may be performed (example: ["EU"]).
  • allowed_ws_origin: WebSocket-only. If non-empty, the browser Origin header must match one of the listed values.

These fields are described in detail in Client configuration.

How tokens are passed to the server

The mechanism depends on the protocol:

  • WebSocket (two methods, checked in priority order):

    1. Authorization: Bearer AT_... header – recommended for server-side clients.
    2. Sec-WebSocket-Protocol subprotocol – for browser clients that cannot set custom headers. The token is sent with an at. prefix alongside the real protocol name:
      new WebSocket(url, ["llps.v1", "at.AT_<id>_<secret>"])
      
      The server echoes back only the real protocol (llps.v1), never the token.
  • gRPC: via metadata (for example an authorization metadata entry with value Bearer AT_...).

See:

What not to do

  • Do not put tokens into logs.
  • Do not embed long-lived tokens into client-side code that ships to users (use short-lived tokens, or a backend exchange flow).