Claims and Identity
This page explains each claim that your server signs, how the reference identifies connections, and why a connection can fail to open.
Before you start: Read Authentication. For segment access, read Permissions.
Your server signs claims for each connection. The claims tell Celeris which channels the connection can use, what it can do in each segment, and which identity its peers see.
1. Know the claims
| Claim | Default | What it controls |
|---|---|---|
channels | None. It is necessary. | The channel references that the connection can open |
permissions | None. It is necessary. | Read and write access for each segment. See Permissions. |
reference | A new random value | The identity label that peers see in messages and presence |
replay | false | Recent history at each segment join. See Replay. |
allowEcho | false | Whether the publishing connection gets its own messages |
| timestamp | Added by the signer | The time of signing. The server uses it to refuse old credentials. |
const credentials = signer.sign({
channels: { kind: "restricted", references: ["room-42"] },
permissions: {
kind: "restricted",
segments: [{ segmentId: "chat", read: true, write: true }],
},
reference: user.realtimeReference,
replay: false,
allowEcho: false,
});
The other SDKs use the same claims. Go uses Reference and AllowEcho. Python uses reference and allow_echo. Java uses .reference() and .allowEcho(). See the server page of your SDK.
2. Choose the channels
Sign one of two forms:
{ kind: "all" }lets the connection open any channel of your application.{ kind: "restricted", references: [...] }lets it open only the listed channels.
The client gives the channel reference when it connects. If that reference is not in the signed list, the server refuses the connection. Use the restricted form by default.
3. Set the reference
The reference is a label that your server chooses. Celeris does not check that it belongs to a user. Peers see it:
- As
tokenReferencein the metadata of each message. - As
tokenReferencein presence events and presence lists.
Use a stable, opaque identifier that is safe to show to other users. Do not use an email address or private account data. The reference must not be empty. It must not contain a colon, CR, or LF.
If you do not sign a reference, the server makes a new random reference for each connection. A reconnect opens a new connection, so the reference also changes after each reconnect. Peers then cannot tell that the two connections belong to the same user. Sign a reference when peers must recognize a user.
4. Know how connections share a reference
Each WebSocket connection gets its own connection ID. Many connections can use the same reference, for example two browser tabs, a phone and a laptop, or a connection after a reconnect.
| Where peers see it | Reference | Connection ID |
|---|---|---|
| Message metadata | Yes | No |
| Presence events | Yes | Yes |
| Presence lists | Yes | Yes |
The message ID is not related to the reference or the connection ID. The server does not tell a connection its own connection ID.
Presence describes connections, not users:
- A second tab with the same reference causes a second join event and a second entry in the presence list.
- When one tab closes, watchers get one leave event, for that connection only. The other tab stays present.
- A connection that watches presence gets the join and leave events of the other connections with its reference.
To show each user one time, group presence entries by tokenReference. A user is offline when no entry for that reference remains.
Limits apply to the account and to each connection, not to the reference. Each connection counts toward the concurrent connection limit of your plan. Each connection has its own message rate limit.
5. Decide about echo
With allowEcho: false, the server does not send a message back to the connection that published it. Other connections with the same reference get the message. Thus, a second tab of the same user gets the message from the first tab.
With allowEcho: true, the publishing connection also gets its own message. It gets it only while it holds a subscription to that segment.
After a reconnect, the replay can include your own earlier messages, also when allowEcho is false. See Replay.
6. Sign fresh credentials
The signer adds the time of signing to the credentials. The server refuses credentials that are more than 60 seconds old. It also refuses credentials with a time that is later than its own clock. Keep the clock of your server synchronized, for example with NTP.
Credentials are not for one use only. Anyone who holds them can open connections until they become too old. Sign new credentials for each connection attempt, and do not keep them. The SDK calls your credential provider for each attempt, also for each automatic reconnect.
7. Find why a connection does not open
The server refuses a connection when:
- The signature does not match, or the client ID is not correct.
- The payload is not valid, or the reference is empty.
- The credentials are too old, or their time is in the future.
- The channel reference is not in the signed
channelslist. - Your account reached a connection limit or a rate limit.
The browser gets no reason for a refused connection. All SDKs report it as a Transport error. Examine the signing secret, the client ID, the claims, and the clock of your server.
Next: Read Binary Messaging.