Skip to content

Endpoints a tenant can reach

Every broker route, classified into the seven classes the gateway enforces: produce, consume, queue admin, read, gated, operator, blocked.

Updated View as Markdown

The gateway does not forward a request it cannot name. Every broker-bound path is matched against one classifier, which returns exactly one class, and the class decides three things at once: which credential may use the route, which limits apply to it, and which usage class it meters as.

The classifier is the enforcement spec. It runs on the URL path only, never the query string, and it is written to fail closed.

How a path is classified

  1. The operator subset is checked first, because the prefix blocks below would otherwise swallow two of its entries. It is a closed list of seven paths. Matching it opens nothing on its own: reaching one still needs a live operator principal, and on a cell with QUEEN_PROXY_OPERATOR_ENABLED off the route answers 404 before authentication runs at all.

  2. Hard blocks. Everything under /api/v1/migration, /api/v1/system, and /internal, plus /api/v1/stats/refresh, bare /metrics, the broker’s own /status, and the queue-less discovery pop GET /api/v1/pop. Blocked for every principal on every cell.

  3. Data plane, then queue admin, then gated features, then reads, by exact path or prefix, and for some routes by method: a DELETE under /api/v1/resources/queues/ is queue admin, while a GET on the same prefix is a read.

  4. Anything else under /api/ is blocked. An unrecognised API-shaped path is never forwarded, so a broker route added upstream does not become reachable by accident. It has to be classified here first.

  5. Everything else is a read. That is the dashboard and static-asset fallback.

A blocked or unauthorized-operator route answers 404 {"code":"route_blocked"}, not 403. A tenant learns that a path does not exist for them rather than that it exists and is forbidden.

Two classes with extra behaviour

produce is the only class whose request body is parsed. The body is buffered so items can be counted, per-item payload sizes checked, each (queue, partition) admitted against the plan caps, and message tokens taken. It is forwarded byte for byte: the proxy never rewrites a body.

consume with wait=true holds a parked-consumer slot for the duration of the upstream call, and the long-poll timeout is recomputed as the client’s requested wait, clamped to QUEEN_PROXY_LONGPOLL_MAX_MS, plus QUEEN_PROXY_LONGPOLL_MARGIN_MS.

The table

The proxy classifies every broker-bound request into exactly one class, and anything API-shaped that matches no rule is blocked. The table below applies that classifier to the broker’s own route list.

Class What it means
produce Counted against the message quota. May create queues and partitions implicitly.
consume Pop, ack and lease extension. A wait=true pop also holds a parked-consumer slot.
queue admin Configuration, deletions, seeks and subscription changes.
read Listings, status, analytics, DLQ and message reads, all tenant-scoped.
gated (streams) Available when the plan enables the streams feature.
gated (traces) Writing a trace is available when the plan enables the traces feature.
operator Cell-wide surfaces. Not tenant-scopable, so a tenant credential gets the same 404 a blocked route returns.
blocked Never exposed to a tenant, whatever the credential. Returns 404.

produce

Method Path
POST /api/v1/push
POST /api/v1/transaction

consume

Method Path
POST /api/v1/ack
POST /api/v1/ack/batch
POST /api/v1/lease/:leaseId/extend
GET /api/v1/pop/queue/:queue
GET /api/v1/pop/queue/:queue/partition/:partition

queue admin

Method Path
POST /api/v1/configure
DELETE /api/v1/consumer-groups/:group
DELETE /api/v1/consumer-groups/:group/queues/:queue
POST /api/v1/consumer-groups/:group/queues/:queue/partitions/:partition/seek
POST /api/v1/consumer-groups/:group/queues/:queue/seek
POST /api/v1/consumer-groups/:group/subscription
DELETE /api/v1/messages/:partitionId/:transactionId
DELETE /api/v1/resources/queues/:queue

read

Method Path
GET /api/v1/analytics/queue-lag
GET /api/v1/analytics/queue-ops
GET /api/v1/analytics/queue-parked-replicas
GET /api/v1/analytics/retention
GET /api/v1/consumer-groups
GET /api/v1/consumer-groups/:group
GET /api/v1/consumer-groups/lagging
GET /api/v1/dlq
GET /api/v1/messages
GET /api/v1/messages/:partitionId/:transactionId
POST /api/v1/messages/:partitionId/:transactionId/retry
GET /api/v1/resources/namespaces
GET /api/v1/resources/overview
GET /api/v1/resources/queues
GET /api/v1/resources/queues/:queue
GET /api/v1/resources/tasks
GET /api/v1/status/analytics
GET /api/v1/status/queues
GET /api/v1/status/queues/:queue
GET /api/v1/traces/:partitionId/:transactionId
GET /api/v1/traces/by-name/:traceName
GET /api/v1/traces/names
GET /auth/login
POST /auth/logout
GET /auth/me
GET /health

gated (streams)

Method Path
POST /streams/v1/cycle
POST /streams/v1/queries
POST /streams/v1/state/get

gated (traces)

Method Path
POST /api/v1/traces

operator

Method Path
GET /api/v1/analytics/postgres-stats
GET /api/v1/analytics/system-metrics
GET /api/v1/analytics/worker-metrics
GET /api/v1/status
GET /api/v1/status/buffers
GET /api/v1/system/maintenance
POST /api/v1/system/maintenance
GET /api/v1/system/maintenance/pop
POST /api/v1/system/maintenance/pop
GET /metrics/prometheus

blocked

Method Path
GET /api/v1/pop
POST /api/v1/stats/refresh
GET /api/v1/system/shared-state
GET /internal/api/inter-instance/stats
POST /internal/api/notify
GET /internal/api/shared-state/stats
GET /metrics
GET /status

45 of the broker’s 63 method + path pairs are reachable with a tenant credential; the rest are operator or blocked surfaces.

Reading it in practice

  • A tenant’s normal working set is produce, consume, queue admin and read. Those four cover the whole documented HTTP API for building on Queen.
  • gated routes exist on the broker for every tenant and are opened by the plan’s features object, not by the credential’s scopes.
  • operator and blocked are the two classes a tenant can never reach. They are cell-wide surfaces that the broker does not tenant-scope, which is precisely why the proxy exists. Isolation explains what each of them would leak.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close