Interfaces (gRPC · REST · API · HTTP)
gRPC, REST/WebSocket, the management API + API auth, and the shared HTTP server with CORS.
KubeMQ fronts its server core with four interfaces: the gRPC transport, the
REST/WebSocket transport, the management/dashboard API (with opt-in API
authentication), and the shared HTTP server that hosts MCP, A2A, and CloudEvents on
the REST port. Each setting is shown for both targets — Docker single-node (config.yaml
key · env var) and Kubernetes/Helm (spec.* path). A dash (—) in the Helm/CRD column
means the setting is not a typed CRD field; on Kubernetes it is reachable only through
spec.configData (raw config) or a directly-set pod env var.
All four interfaces are opt-out (always-on). gRPC, REST, and API are enabled by
default on both targets. On Docker they use the enable: true/false model; on the chart
they use the inverted disabled: true/false framing (spec.grpc.disabled,
spec.rest.disabled, spec.api.disabled) — all shipped as disabled: false. Set
disabled: true to turn one off. The shared HTTP server has no toggle of its own — it
rides the REST port and is emitted only when you set one of its spec.http.* fields.
The shared HTTP listener does not belong to REST. It starts if any of REST, MCP, A2A, or CloudEvents is enabled, and stops only when all four are off. Disabling REST alone retires the REST routes and leaves the other three serving on the same port.
.port on Kubernetes moves everything together. Setting spec.grpc.port /
spec.rest.port / spec.api.port makes the operator emit the matching listener env var
(CONNECTORS_GRPC_PORT / CONNECTORS_REST_PORT / API_PORT) and set the Kubernetes
Service port/targetPort and the container port — the in-pod listener and the
Service port move as one. On Docker the same env var moves the actual listener, which you
then publish with docker run -p.
A default helm install publishes nothing outside the cluster. The shipped
values.yaml sets no expose and no nodePort for any interface, and a KubemqCluster
with expose unset gets a ClusterIP Service. gRPC is not reachable on every node
out of the box — to reach it from outside you set expose yourself (NodePort or
LoadBalancer), and if you need a predictable port you must also set nodePort,
because an unset one is assigned by the kernel and cannot be configured into a client
ahead of the install.
gRPC
The primary client transport. Enabled by default on both targets.
| Setting | Type | Default | Valid values | Docker (config.yaml key · env var) | Helm/CRD path | Notes |
|---|---|---|---|---|---|---|
| Enable / disable | bool | enabled (true) | true / false | connectors.grpc.enable · CONNECTORS_GRPC_ENABLE | spec.grpc.disabled | Inverted boolean: Docker enable: true, Helm disabled: false. When disabled, no listener starts and the rest of the section is skipped. |
| Port | int (string) | 50000 | 1–65535 | connectors.grpc.port · CONNECTORS_GRPC_PORT | spec.grpc.port | Server field is a string port; rejected if non-numeric or out of range. |
| Sub buffer size | int | 100 | ≥ 0 | connectors.grpc.subbuffsize · CONNECTORS_GRPC_SUB_BUFF_SIZE | spec.grpc.bufferSize | Per-subscription channel buffer. Negative rejected. Name divergence: server subBuffSize ↔ CRD bufferSize. |
| Body limit | int (bytes) | 104857600 (100 MB) | ≥ 0 bytes | connectors.grpc.bodylimit · CONNECTORS_GRPC_BODY_LIMIT | spec.grpc.bodyLimit | Server int bytes; CRD int32 bytes, emitted only when non-zero (no CRD type default). Chart example sets 10000000. |
| gRPC reflection | bool | false | true / false | connectors.grpc.enablereflection · CONNECTORS_GRPC_ENABLE_REFLECTION | spec.grpc.enableReflection | Enables server reflection for grpcurl/tooling. |
| Service exposure | enum | ClusterIP | ClusterIP / NodePort / LoadBalancer | (-p host port) | spec.grpc.expose | Kubernetes Service type; empty ⇒ ClusterIP. The chart ships no expose value. On Docker use -p. |
| NodePort | int | 0 (kernel-assigned) | 30000–32767 | (-p) | spec.grpc.nodePort | Applied only when expose: NodePort and the value is > 0. The chart ships no default — leave it unset and the kernel picks a port you cannot configure into a client ahead of the install. |
REST · WebSocket
The HTTP/WebSocket transport, which also hosts the shared HTTP server (MCP, A2A, CloudEvents). Enabled by default on both targets.
| Setting | Type | Default | Valid values | Docker (config.yaml key · env var) | Helm/CRD path | Notes |
|---|---|---|---|---|---|---|
| Enable / disable | bool | enabled (true) | true / false | connectors.rest.enable · CONNECTORS_REST_ENABLE | spec.rest.disabled | Inverted boolean. Disabling REST removes the REST routes (they return 404) but leaves MCP, A2A and CloudEvents serving — the shared HTTP server starts if any of the four is enabled. To take the whole listener down, disable all four. |
| Port | int (string) | 9090 | 1–65535 | connectors.rest.port · CONNECTORS_REST_PORT | spec.rest.port | String port; rejected if non-numeric or out of range. |
| Body limit | string / int | server "100M" | Echo size string or bytes | connectors.rest.bodylimit · CONNECTORS_REST_BODY_LIMIT | spec.rest.bodyLimit | Server size-string ("100M"); CRD int32 bytes, emitted only when non-zero. Chart example sets 1000000. |
| Sub buffer size | int | 100 | ≥ 0 | connectors.rest.subbuffsize · CONNECTORS_REST_SUB_BUFF_SIZE | spec.rest.bufferSize | Negative rejected. Name divergence: subBuffSize ↔ bufferSize. |
| Read timeout | int (s) | 60 | ≥ 0 (CRD ≥ 1) | connectors.rest.readtimeout · CONNECTORS_REST_READ_TIMEOUT | spec.rest.readTimeout | Seconds. Server rejects negative; CRD enforces Minimum=1. |
| Write timeout | int (s) | 60 | ≥ 0 (CRD ≥ 1) | connectors.rest.writetimeout · CONNECTORS_REST_WRITE_TIMEOUT | spec.rest.writeTimeout | Seconds. Server rejects negative; CRD enforces Minimum=1. |
| Service exposure | enum | ClusterIP | ClusterIP / NodePort / LoadBalancer | (-p host port) | spec.rest.expose | Kubernetes Service type; empty ⇒ ClusterIP. The chart ships no expose value. On Docker use -p. |
| NodePort | int | 0 (kernel-assigned) | 30000–32767 | (-p) | spec.rest.nodePort | Applied only when expose: NodePort and the value is > 0. The chart ships no default. |
REST CORS
CORS policy for the REST transport. On the CRD it is a first-class spec.rest.cors.*
sub-object; on Docker/env the keys ride the CONNECTORS_REST_CORS_* prefix.
| Setting | Type | Default | Valid values | Docker (config.yaml key · env var) | Helm/CRD path | Notes |
|---|---|---|---|---|---|---|
| Allow origins | string[] | ["*"] | origin list | connectors.rest.cors.alloworigins · CONNECTORS_REST_CORS_ALLOW_ORIGINS | spec.rest.cors.allowOrigins | Must be non-empty — validation rejects an empty list. |
| Allow methods | string[] | ["GET","POST"] | method list | connectors.rest.cors.allowmethods · CONNECTORS_REST_CORS_ALLOW_METHODS | spec.rest.cors.allowMethods | Must be non-empty. |
| Allow headers | string[] | [] | header list | connectors.rest.cors.allowheaders · CONNECTORS_REST_CORS_ALLOW_HEADERS | spec.rest.cors.allowHeaders | Empty list allowed. |
| Allow credentials | bool | false | true / false | connectors.rest.cors.allowcredentials · CONNECTORS_REST_CORS_ALLOW_CREDENTIALS | spec.rest.cors.allowCredentials | |
| Expose headers | string[] | [] | header list | connectors.rest.cors.exposeheaders · CONNECTORS_REST_CORS_EXPOSE_HEADERS | spec.rest.cors.exposeHeaders | |
| Max age | int (s) | 0 | ≥ 0 | connectors.rest.cors.maxage · CONNECTORS_REST_CORS_MAX_AGE | spec.rest.cors.maxAge | Negative rejected. |
REST → shared-HTTP inheritance. When you explicitly set Rest.ReadTimeout,
Rest.BodyLimit, Rest.Cors.AllowOrigins, or Rest.Cors.AllowMethods (and don't set the
matching Http.* key), the value propagates to the shared HTTP server. Http.Port always
inherits Rest.Port when Http.Port is unset. The shared server's distinct CORS defaults
(the MCP-*/OPTIONS/DELETE headers below) are preserved whenever you did not
override the REST side, so MCP and A2A keep working.
Management API
The management/dashboard API. Enabled by default on both targets.
| Setting | Type | Default | Valid values | Docker (config.yaml key · env var) | Helm/CRD path | Notes |
|---|---|---|---|---|---|---|
| Enable / disable | bool | enabled (true) | true / false | api.enable · API_ENABLE | spec.api.disabled | Inverted boolean. |
| Port | int | 8080 | 1–65535 | api.port · API_PORT | spec.api.port | Validated only when the API is enabled. |
| Bind address | string | 127.0.0.1 (empty → 0.0.0.0) | IP address | api.bindaddress · API_BIND_ADDRESS | — | Config/env only; no typed CRD field. An empty value is normalized to 0.0.0.0. |
| Allow origins (CORS) | string[] | ["*"] | origin list | api.alloworigins · API_ALLOW_ORIGINS | spec.api.allowOrigins | CRD joins the list with commas into the env var. When API auth is enabled, "*" and an empty list are rejected (see below). |
| Service exposure | enum | ClusterIP | ClusterIP / NodePort / LoadBalancer | (-p host port) | spec.api.expose | Kubernetes Service type; empty ⇒ ClusterIP. The chart ships no expose value. On Docker use -p. |
| NodePort | int | 0 (kernel-assigned) | 30000–32767 | (-p) | spec.api.nodePort | Applied only when expose: NodePort and the value is > 0. The chart ships no default. |
Management API authentication
Opt-in authentication for the management API + web dashboard ([Api.Auth]). Disabled by
default. The data plane (gRPC/REST messaging) is unaffected. On the CRD it lives under
spec.api.auth.*.
| Setting | Type | Default | Valid values | Docker (config.yaml key · env var) | Helm/CRD path | Notes |
|---|---|---|---|---|---|---|
| Enable | bool | false | true / false | api.auth.enable · API_AUTH_ENABLE | spec.api.auth.enable | Gates the whole section. |
| Session idle minutes | int | 30 | > 0 when enabled | api.auth.sessionidleminutes · API_AUTH_SESSION_IDLE_MINUTES | spec.api.auth.sessionIdleMinutes | Idle-session timeout. Must be positive. |
| Session absolute hours | int | 8 | > 0 when enabled | api.auth.sessionabsolutehours · API_AUTH_SESSION_ABSOLUTE_HOURS | spec.api.auth.sessionAbsoluteHours | Absolute session lifetime. Must be positive. |
| Store path | string | "" → main store dir | filesystem path | api.auth.storepath · API_AUTH_STORE_PATH | spec.api.auth.storePath | When empty and auth enabled, defaults to Store.StorePath (the main store directory). |
| Trusted TLS proxy | bool | false | true / false | api.auth.trustedtlsproxy · API_AUTH_TRUSTED_TLS_PROXY | spec.api.auth.trustedTLSProxy | Set true when a TLS-terminating reverse proxy fronts the API port; otherwise cookie/session login is refused on plain HTTP. |
| Admin username | string | admin | username | KUBEMQ_API_ADMIN_USERNAME (os env) | spec.api.auth.adminUsername | Env/secret only — not a viper config-file field. Read directly from the environment. |
| Admin password | string | — | password | KUBEMQ_API_ADMIN_PASSWORD / KUBEMQ_API_ADMIN_PASSWORD_FILE (os env) | spec.api.auth.adminSecretRef · adminSecretKey | Secret only — never a config field. The operator injects the password into the pod from a Secret; on Docker set the env var (or _FILE) yourself. Cluster mode requires it when auth is enabled. |
The account model
The two settings above (adminUsername / adminPassword) bootstrap the first account.
They are not the whole model — once auth is on, the control plane has three roles and two
account types, and only the first admin is configured through the server config at all.
Every other account is created through the API or dashboard.
Three roles, each a superset of the one below it:
| Role | Can do |
|---|---|
read_only | Read dashboards, stats, snapshots, audit logs |
read_write | Everything in read_only, plus send/receive messages and subscribe |
admin | Everything in read_write, plus manage accounts and revert configuration |
Two account types:
| Type | Authenticates with | Notes |
|---|---|---|
user | Username + password, cookie session | Subject to the idle and absolute session limits above. |
service | A bearer API key, kmq_<keyid>_<secret> | Sent as Authorization: Bearer …. For scripts, agents, and CI. A service account cannot hold the admin role — that combination is rejected at creation. |
Two behaviors worth knowing before you turn auth on:
- The bootstrap admin must rotate its password on first login. The login response
carries
must_change_password, and the account stays in that state until the password is changed — an automation that logs in with the bootstrap credentials and ignores the flag will not get far. - Cookie-authenticated mutations require an
X-KubeMQ-CSRFheader. Bearer-authenticated service accounts are exempt: there is no ambient credential for a malicious site to replay, so the guard applies to session cookies only.
A read_only account is a real account, and it can read configuration. If you are
handing out dashboard access, read_only is the right default — but treat it as a
principal with visibility into server settings, not as a view of nothing sensitive.
Wildcard CORS is refused when API auth is enabled. With api.auth.enable: true, the
server rejects boot if api.alloworigins is empty or contains "*" — credentialed auth
requires a concrete origin list (e.g. ["https://app.example.com"]). The
sessionIdleMinutes/sessionAbsoluteHours values must both be positive.
Shared HTTP server
The shared HTTP server hosts MCP, A2A, and CloudEvents on the REST port. On Kubernetes it
is a first-class spec.http.* group; its CORS lives under spec.http.cors.*. It has no
enable/disable toggle — it is active whenever REST is, and the CRD emits its env vars only
for the spec.http.* fields you set.
| Setting | Type | Default | Valid values | Docker (config.yaml key · env var) | Helm/CRD path | Notes |
|---|---|---|---|---|---|---|
| Port | string | inherits Rest.Port (9090) | 1–65535 | connectors.http.port · CONNECTORS_HTTP_PORT | spec.http.port | Empty ⇒ inherits the REST port. A differing explicit value logs a warning; the HTTP server uses Http.Port. |
| Read timeout | int (s) | 60 | ≥ 0 (CRD ≥ 1) | connectors.http.readtimeout · CONNECTORS_HTTP_READ_TIMEOUT | spec.http.readTimeout | Negative rejected. |
| Body limit | string | "100M" | Echo size string | connectors.http.bodylimit · CONNECTORS_HTTP_BODY_LIMIT | spec.http.bodyLimit | CRD field is a string. |
| Base URL | string | "" | URL | connectors.http.baseurl · CONNECTORS_HTTP_BASE_URL | spec.http.baseUrl | Server field is BaseURL; env ..._BASE_URL. |
| CORS allow origins | string[] | ["*"] | origin list | connectors.http.cors.alloworigins · CONNECTORS_HTTP_CORS_ALLOW_ORIGINS | spec.http.cors.allowOrigins | |
| CORS allow methods | string[] | GET, POST, DELETE, OPTIONS | method list | connectors.http.cors.allowmethods · CONNECTORS_HTTP_CORS_ALLOW_METHODS | spec.http.cors.allowMethods | Wider than REST — MCP/A2A need DELETE/OPTIONS. |
| CORS allow headers | string[] | Authorization, Content-Type, MCP-Protocol-Version, MCP-Session-Id, Last-Event-ID, Accept | header list | connectors.http.cors.allowheaders · CONNECTORS_HTTP_CORS_ALLOW_HEADERS | spec.http.cors.allowHeaders | Includes the MCP-* headers. |
| CORS allow credentials | bool | false | true / false | connectors.http.cors.allowcredentials · CONNECTORS_HTTP_CORS_ALLOW_CREDENTIALS | spec.http.cors.allowCredentials | |
| CORS expose headers | string[] | MCP-Session-Id, MCP-Protocol-Version | header list | connectors.http.cors.exposeheaders · CONNECTORS_HTTP_CORS_EXPOSE_HEADERS | spec.http.cors.exposeHeaders | |
| CORS max age | int (s) | 86400 | ≥ 0 | connectors.http.cors.maxage · CONNECTORS_HTTP_CORS_MAX_AGE | spec.http.cors.maxAge | Negative rejected. |
Version floor: the shared-HTTP spec.http.* fields are present throughout the current
GA chart line — kubemq-crds and kubemq-cluster 3.x (latest 3.2.0) with
kubemq-controller 2.x (operator v2.3.0). Anything older than the 3.0.0 / 2.0.0 GA
release predates this reference: upgrade to the current line rather than trying to work out
which pre-GA build carried which field. On Docker the connectors.http.* keys are
available regardless of chart version.
Example
Set the gRPC port on each target. On Kubernetes spec.grpc.port moves the in-pod listener,
the Service port/targetPort, and the container port together; on Docker it moves the
listener and you publish it with -p. This is a
single-setting snippet — see the Docker guide and the
Kubernetes guide for complete, runnable configurations.
connectors:
grpc:
port: "50000"grpc:
port: 50000For the full Docker delivery methods and docker run port publishing see the
Docker guide; for values.yaml mapped to the
KubemqCluster spec and Service exposure see the
Kubernetes guide.
Was this page helpful?
Core & Licensing
Core KubeMQ server settings — license key, log level, host identity, and node naming for a single instance or a clustered deployment.
Connectors
Runtime settings for MCP, A2A agents, CloudEvents, and the wire-protocol connectors — MQTT, AMQP 0.9.1/1.0, STOMP, Kafka, AWS, and GCP Pub/Sub.