Channels & authorization

A channel is a name that clients subscribe to and events are delivered to. The prefix on that name decides who is allowed in.

Why the prefix is part of the name

Access rules live in the string itself rather than in a dashboard setting, so a developer reading private-invoice-2481 in a code review can tell it is protected without looking anything up. It also means the client library knows to fetch a signature before subscribing, with no configuration.

public-

Anyone holding your public key can subscribe. Since the public key ships in your browser bundle, treat a public channel as world-readable: use it for things like a live status page or a global announcement feed, never for anything scoped to a user.

private-

Subscription requires a signature issued by your backend. When the client subscribes, it POSTs the socket id and channel name to your authEndpoint. Your code decides whether that user may join, and if so returns a signature.

presence-

Everything private- does, plus a live roster. The signature covers achannel_data payload carrying the member's identity:

{
  "user_id": "user_8f2a",
  "user_info": { "name": "Ada", "avatar": "https://…" }
}

Because the identity is inside the signed payload, a client cannot claim to be someone else — it can only present what your backend signed for it.

How the signature works

HMAC-SHA256(secretKey, socketId + ":" + channel)                    // private-
HMAC-SHA256(secretKey, socketId + ":" + channel + ":" + channelData) // presence-

// returned to the client as:
{ "auth": "<appId>:<hexDigest>", "channel_data": "<the signed JSON>" }

The socket id is part of the signed payload, so a signature obtained for one connection cannot be reused on another. The SDK re-authorizes automatically after every reconnect, since the socket id changes.

We never see your user model. Your backend answers one question — may this connection join this channel — and we only verify that the answer was signed by someone holding your secret key.

Client events

By default, clients cannot publish; events come from your server. When you enable client events for an app, a client may publish only:

  • to a private- or presence- channel — never public-, which would be an open relay
  • to a channel it is currently subscribed to
  • with an event name starting client-, so it can never impersonate one of your server events

Client events are metered exactly like server events. Typing indicators and cursor positions are the usual good uses; anything you would not let a user forge should go through your backend.

Naming rules

  • Must start with one of the three prefixes
  • Up to 164 characters
  • Letters, numbers, and _ - = @ , . ;