Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Patterns & matching

You can subscribe to one channel (exact name) or to many channels with a pattern. Channel names use dot-separated tokens (e.g. a.b.c).

Token permissions vs subscription patterns

There are two matchers you should keep separate:

  • Token rules (permissions): a restricted subset used in access tokens.
  • Runtime subscription patterns: richer wildcards accepted when subscribing.

Token rules are intentionally limited to keep authorization non-ambiguous. In tokens, channel rules support:

  • exact channel: "a.b.c"
  • prefix tree: "a.b.c.#" (base channel and any deeper channel under it)
  • literal alternatives in one segment: "orders.(eu|us|asia).#"
  • for subscriptions also ? and * as policy tokens

Runtime subscriptions support: exact tokens, *, >, #, {a,b} and [a,b].

Important rule: your runtime subscription must be a subset of what your token allows. If in doubt, keep token rules broad (roots like orders.#) and narrow down with runtime patterns.

Breaking change: prefix*, prefix# and prefix> are no longer supported in runtime patterns or in token alternatives. Old rules with b* / user# / user> must be rewritten.

See also:

Tenant

  • Length: 1..128 bytes
  • Allowed characters: a-z, A-Z, 0-9, _, -, ~, @, .
    • If the tenant is sent empty, it is set by default to ~, because the tenant cannot be absent.

Channel

  • Length: 1..256 bytes
  • Allowed characters: a-z, A-Z, 0-9, _, -, ~, @, ., and for subscription patterns also >, #, *, {, }, [, ], , (see Wildcard patterns).

Channel names usually use dot-separated tokens (example: a.b.c).

Wildcard patterns

Channel names are dot-separated tokens (e.g. a.b.c → tokens a, b, c). Subscription patterns use the same format with wildcards. Only the last token of a pattern may use tail wildcards (> or #). In the middle of a pattern, only exact tokens, *, {…} or […] are allowed.

Limits:

  • one list {…} / […] contains at most 16 literal values
  • one pattern expands to at most 64 trie paths
  • each literal token is at most 16 bytes
  • whole pattern is at most 256 bytes

Single-token matching

  • Exact: abc — matches only the token abc.
  • Any one token: * — matches exactly one token (any value).
  • Alternatives: {eu,us,asia} — matches exactly one token if it is one of the listed literals.
  • Optional alternatives: [v1,v2] — matches zero tokens or exactly one listed literal.

Tail wildcards (last token only)

  • > (1+ levels, NATS-style): “one or more tokens after this”.
    Example: a.b.> matches a.b.x, a.b.x.y, but not a.b (at least one token after b is required).
  • # (0+ levels, MQTT/RabbitMQ-style): “zero or more tokens after this”.
    Example: a.b.# matches a.b, a.b.x, a.b.x.y.

Choice examples

  • orders.{eu,us,asia}.created matches orders.eu.created, orders.us.created, orders.asia.created.
  • orders.[v2].created matches orders.created and orders.v2.created.
  • orders.[v1,v2].# matches orders, orders.v1, orders.v1.x, orders.v2.y.

Invalid patterns

  • > or # in the middle: e.g. a.>.b, a.#.b — invalid.
  • Tail in the middle: e.g. a.b.>.x — invalid (tail must be the last token).
  • Prefix forms: news*, user>, user# — invalid.
  • Empty or duplicate lists: {}, [], {a,a} — invalid.
  • Nested or mixed wildcards inside a list: {a,*}, [b#] — invalid.