Skip to content

Authentication and Realms

eric edited this page Jul 18, 2026 · 2 revisions

Authentication and Realms

Authentication is disabled by default (fully backwards compatible). Enable it with:

new Server({ auth: { enabled: true } })

or "auth": { "enabled": true } in the settings file, or TYO_MQ_AUTH_ENABLED=true with the stock entry point.

The handshake

Once auth is on, a socket must authenticate before any protocol event:

client → server: AUTHENTICATION { token | realm + role [+ key] }
server → client: AUTH_OK   { realm, role }
               | AUTH_FAIL { code: 401|403, message }

The client libraries do this automatically from the Factory's auth option:

// token-based
new Factory({ host, port, protocol, auth: { token: 'secret-acme-prod' } });

// role-declared (token-less) — see [[Roles and Connection Authorization]]
new Factory({ host, port, protocol, auth: { realm: 'acme', role: 'consumer', key: 'acme-psk' } });

After connecting, client.authInfo holds { realm, role }.

Token formats

Validation modes, checked in this order (local credentials first, so enabling an external validator can never break configured tokens):

  1. Custom validatorauth.validator: (token) => ({realm, role}) | null (replaces all other modes when set)

  2. Per-realm HS256 JWT — verified against the realm's own manager_key, looked up from the token's realm claim; realms stay isolated because one realm's key can't verify another's tokens.

  3. Global HS256 JWTauth.jwt_secret; exp/nbf are honored.

  4. Opaque token listauth.tokens: [{token, realm, role}, ...] (also where runtime-approved tokens land).

  5. External endpoint (fallback, since 0.14.2 scopable) — the server POSTs {token, realm} with an X-MQ-Auth-Secret header and expects {realm, role} back. The validator is picked by scope, most specific first:

    • auth.realms[r].auth_url (+ auth_secret) — that realm only
    • auth.external_validators: [{realm_prefix, auth_url, auth_secret}] — realms under the prefix, longest match wins
    • auth.auth_url — global fallback (original behavior)

    Scoped validators are an isolation boundary: one bound to a realm or prefix can only authorize tokens into its own realm(s) — responses naming any other realm are discarded. The scope is chosen from the realm the client declared, falling back to the token's JWT realm claim.

The admin token

When auth is enabled and no realm: "*", role: "admin" token exists, the server generates one and appends it to .env as TYO_MQ_ADMIN_TOKEN (disable with auth.auto_admin_token: false). The admin token signs management commands — it is never sent over the wire. Verify it works:

npm run auth:admin

Realms

A realm is a named isolation boundary — tyo-mq's multi-tenancy unit.

  • Every authenticated socket is tagged with its realm; all routing and subscription lookups are realm-scoped.
  • The same producer/consumer names can exist independently in different realms; messages never cross realms.
  • realm: "*" is the admin realm: its subscribers observe messages across all realms — for monitoring and management only.

Per-realm settings live under auth.realms:

"realms": {
  "acme":   { "required": true,
              "manager_key": "realm-operator-secret",
              "key": "consumer-pre-shared-key",
              "require_acceptance": true },
  "public": { "required": false }
}
Field Meaning
required: false the realm is fully open — no token or key needed
key / require_key consumer pre-shared key — Roles and Connection Authorization
require_acceptance producer admission — Roles and Connection Authorization
manager_key lets a realm operator approve requests scoped to this realm — Authorization Requests
auth_url / auth_secret realm-scoped external validator (see Token formats above)
ephemeral / expires_at disposable realm form — Ephemeral Realms

Realms are created implicitly on first use, or explicitly via the add_realm management command — in permanent or ephemeral (disposable) form; see Ephemeral Realms. All of this hot-reloads via the settings file and is manageable at runtime — see [[Management Commands]]. Once realm/token data grows, move it to the crash-safe SQLite auth store (Server Configuration).

Clone this wiki locally