Authentication
How browsers connect, how private channels are authorized, and how servers sign publish requests.
Two credential domains
EmitWave keeps browser credentials and server credentials strictly separate. A public application key identifies an app but grants no private channel access; a connection token permits a socket but grants no private channel access by itself.
| Credential | Held by | Grants |
|---|---|---|
| ew_pk_… | Browser | Identifies the application; safe to expose |
| End-user Bearer token | Browser | Authenticates the user to EmitWave |
| Connection token | SDK (auto) | Permission to open the socket |
| Subscription token | SDK (auto) | Access to one private or presence channel |
| Server key + secret | Trusted server | Permission to publish (HMAC-signed) |
Browser connection flow
Pass an authHeaders callback; the SDK invokes it before every token request so a renewed session is picked up without recreating the client.
const emitwave = new Emitwave('ew_pk_live_your_public_key', { // Runs before every connect-token and channel-auth request, // so a refreshed token is used without recreating the client. authHeaders: async () => ({ Authorization: `Bearer ${await getEndUserToken()}`, }), }) await emitwave.connect()
- Your app authenticates the end user and gets a Bearer token EmitWave recognizes.
connect()POSTs the public key to/connect-tokenwith that token. Required for every connection, even public-only ones.- Public and public-cache channels subscribe immediately.
- Private, presence, cache, and encrypted channels first call
/channel-auth.
Channel authorization
Authenticated channel types deny access unless a registered callback matches. Private callbacks return a truthy value; presence callbacks must return the member identity.
// Private: return a truthy value to allow Emitwave::channel('private-account.{account}', fn ($user, $account) => (string) $user->account_id === $account ); // Presence: return the member identity Emitwave::channel('presence-room.{room}', fn ($user, $room) => [ 'id' => (string) $user->id, 'info' => ['name' => $user->name], ]);
true is insufficient for a presence channel — EmitWave needs an id to populate the member set. Member identity always comes from the server callback, never the client.Server publish signing
For every publish, a server SDK hashes the exact JSON body and HMAC-signs the HTTP method, path, canonical query, and body hash with HMAC-SHA256. The gateway rejects unknown keys, revoked credentials, stale timestamps, and invalid signatures. See Publishing and the error codes.
Management API tokens
The management API under /api/platform/* uses bearer tokens with organization RBAC (owner > admin > developer > viewer). Mint one from an account's credentials:
TOKEN=$(curl -fsS -X POST https://api.emitwave.com/api/platform/auth/token \ -H 'Content-Type: application/json' \ -d '{"email":"[email protected]","password":"…","device_name":"cli"}' \ | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')
See the API reference for the management endpoints this token unlocks.