Skip to content

Tenancy & relay_user_id

Both relays rest on one shared multi-tenant model. Learn it here once; it applies identically to the Auth Relay and the Chat Relay.

A tenant is an application or backend that consumes a relay. When you integrate a relay, your service becomes a tenant: you receive an identity and secrets, and every call is attributed to your tenant.

Both relays share one common tenants collection: the same identity fields, the same lifecycle, the same credential conventions. That is what lets you learn the integration once.

Provisioning a tenant returns its secrets once:

CredentialRoleRelay
tenant_idPublic tenant identifier (header on every signed call).Auth + Chat
tenant_secretHMAC signing secret (never expose client-side).Auth + Chat
widget_public_keyPublic web-widget key, safe to expose in the browser.Chat only

A relay does not store your passwords and does not “own” your users. Instead, it links your user identifier (backend_user_id) to a relay-side identity. That link is the relay_user_id: the universal validator that follows the “Stripe Connect” model.

  1. Your backend presents one of its users to the relay (during pairing on the Auth Relay, or operator provisioning on the Chat Relay).
  2. The relay establishes a stable link between your backend_user_id and its internal identity.
  3. Subsequent operations (approval push, sudo step-up, operator token…) target that link, never a shared global account.

A single real user can therefore be linked to multiple tenants and multiple backends at once, with each link kept isolated.

Isolation is a first-class guarantee:

  • Chat Relay — an operator token is issued with a tids: { tenant_id: role } scope limited to the calling tenant. Tenant A cannot forge a token that opens tenant B’s inbox.
  • Auth Relay — pairings and challenges are bound to the tenant that created them; one tenant never sees another’s devices.

Because the caller is already authenticated by HMAC, the relay reliably knows its tenant_id before applying that scope.