KubeMQ
ConfigureReference

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.

SettingTypeDefaultValid valuesDocker (config.yaml key · env var)Helm/CRD pathNotes
Enable / disableboolenabled (true)true / falseconnectors.grpc.enable · CONNECTORS_GRPC_ENABLEspec.grpc.disabledInverted boolean: Docker enable: true, Helm disabled: false. When disabled, no listener starts and the rest of the section is skipped.
Portint (string)500001–65535connectors.grpc.port · CONNECTORS_GRPC_PORTspec.grpc.portServer field is a string port; rejected if non-numeric or out of range.
Sub buffer sizeint100≥ 0connectors.grpc.subbuffsize · CONNECTORS_GRPC_SUB_BUFF_SIZEspec.grpc.bufferSizePer-subscription channel buffer. Negative rejected. Name divergence: server subBuffSize ↔ CRD bufferSize.
Body limitint (bytes)104857600 (100 MB)≥ 0 bytesconnectors.grpc.bodylimit · CONNECTORS_GRPC_BODY_LIMITspec.grpc.bodyLimitServer int bytes; CRD int32 bytes, emitted only when non-zero (no CRD type default). Chart example sets 10000000.
gRPC reflectionboolfalsetrue / falseconnectors.grpc.enablereflection · CONNECTORS_GRPC_ENABLE_REFLECTIONspec.grpc.enableReflectionEnables server reflection for grpcurl/tooling.
Service exposureenumClusterIPClusterIP / NodePort / LoadBalancer(-p host port)spec.grpc.exposeKubernetes Service type; empty ⇒ ClusterIP. The chart ships no expose value. On Docker use -p.
NodePortint0 (kernel-assigned)30000–32767(-p)spec.grpc.nodePortApplied 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.

SettingTypeDefaultValid valuesDocker (config.yaml key · env var)Helm/CRD pathNotes
Enable / disableboolenabled (true)true / falseconnectors.rest.enable · CONNECTORS_REST_ENABLEspec.rest.disabledInverted 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.
Portint (string)90901–65535connectors.rest.port · CONNECTORS_REST_PORTspec.rest.portString port; rejected if non-numeric or out of range.
Body limitstring / intserver "100M"Echo size string or bytesconnectors.rest.bodylimit · CONNECTORS_REST_BODY_LIMITspec.rest.bodyLimitServer size-string ("100M"); CRD int32 bytes, emitted only when non-zero. Chart example sets 1000000.
Sub buffer sizeint100≥ 0connectors.rest.subbuffsize · CONNECTORS_REST_SUB_BUFF_SIZEspec.rest.bufferSizeNegative rejected. Name divergence: subBuffSizebufferSize.
Read timeoutint (s)60≥ 0 (CRD ≥ 1)connectors.rest.readtimeout · CONNECTORS_REST_READ_TIMEOUTspec.rest.readTimeoutSeconds. Server rejects negative; CRD enforces Minimum=1.
Write timeoutint (s)60≥ 0 (CRD ≥ 1)connectors.rest.writetimeout · CONNECTORS_REST_WRITE_TIMEOUTspec.rest.writeTimeoutSeconds. Server rejects negative; CRD enforces Minimum=1.
Service exposureenumClusterIPClusterIP / NodePort / LoadBalancer(-p host port)spec.rest.exposeKubernetes Service type; empty ⇒ ClusterIP. The chart ships no expose value. On Docker use -p.
NodePortint0 (kernel-assigned)30000–32767(-p)spec.rest.nodePortApplied 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.

SettingTypeDefaultValid valuesDocker (config.yaml key · env var)Helm/CRD pathNotes
Allow originsstring[]["*"]origin listconnectors.rest.cors.alloworigins · CONNECTORS_REST_CORS_ALLOW_ORIGINSspec.rest.cors.allowOriginsMust be non-empty — validation rejects an empty list.
Allow methodsstring[]["GET","POST"]method listconnectors.rest.cors.allowmethods · CONNECTORS_REST_CORS_ALLOW_METHODSspec.rest.cors.allowMethodsMust be non-empty.
Allow headersstring[][]header listconnectors.rest.cors.allowheaders · CONNECTORS_REST_CORS_ALLOW_HEADERSspec.rest.cors.allowHeadersEmpty list allowed.
Allow credentialsboolfalsetrue / falseconnectors.rest.cors.allowcredentials · CONNECTORS_REST_CORS_ALLOW_CREDENTIALSspec.rest.cors.allowCredentials
Expose headersstring[][]header listconnectors.rest.cors.exposeheaders · CONNECTORS_REST_CORS_EXPOSE_HEADERSspec.rest.cors.exposeHeaders
Max ageint (s)0≥ 0connectors.rest.cors.maxage · CONNECTORS_REST_CORS_MAX_AGEspec.rest.cors.maxAgeNegative 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.

SettingTypeDefaultValid valuesDocker (config.yaml key · env var)Helm/CRD pathNotes
Enable / disableboolenabled (true)true / falseapi.enable · API_ENABLEspec.api.disabledInverted boolean.
Portint80801–65535api.port · API_PORTspec.api.portValidated only when the API is enabled.
Bind addressstring127.0.0.1 (empty → 0.0.0.0)IP addressapi.bindaddress · API_BIND_ADDRESSConfig/env only; no typed CRD field. An empty value is normalized to 0.0.0.0.
Allow origins (CORS)string[]["*"]origin listapi.alloworigins · API_ALLOW_ORIGINSspec.api.allowOriginsCRD joins the list with commas into the env var. When API auth is enabled, "*" and an empty list are rejected (see below).
Service exposureenumClusterIPClusterIP / NodePort / LoadBalancer(-p host port)spec.api.exposeKubernetes Service type; empty ⇒ ClusterIP. The chart ships no expose value. On Docker use -p.
NodePortint0 (kernel-assigned)30000–32767(-p)spec.api.nodePortApplied 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.*.

SettingTypeDefaultValid valuesDocker (config.yaml key · env var)Helm/CRD pathNotes
Enableboolfalsetrue / falseapi.auth.enable · API_AUTH_ENABLEspec.api.auth.enableGates the whole section.
Session idle minutesint30> 0 when enabledapi.auth.sessionidleminutes · API_AUTH_SESSION_IDLE_MINUTESspec.api.auth.sessionIdleMinutesIdle-session timeout. Must be positive.
Session absolute hoursint8> 0 when enabledapi.auth.sessionabsolutehours · API_AUTH_SESSION_ABSOLUTE_HOURSspec.api.auth.sessionAbsoluteHoursAbsolute session lifetime. Must be positive.
Store pathstring"" → main store dirfilesystem pathapi.auth.storepath · API_AUTH_STORE_PATHspec.api.auth.storePathWhen empty and auth enabled, defaults to Store.StorePath (the main store directory).
Trusted TLS proxyboolfalsetrue / falseapi.auth.trustedtlsproxy · API_AUTH_TRUSTED_TLS_PROXYspec.api.auth.trustedTLSProxySet true when a TLS-terminating reverse proxy fronts the API port; otherwise cookie/session login is refused on plain HTTP.
Admin usernamestringadminusernameKUBEMQ_API_ADMIN_USERNAME (os env)spec.api.auth.adminUsernameEnv/secret only — not a viper config-file field. Read directly from the environment.
Admin passwordstringpasswordKUBEMQ_API_ADMIN_PASSWORD / KUBEMQ_API_ADMIN_PASSWORD_FILE (os env)spec.api.auth.adminSecretRef · adminSecretKeySecret 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:

RoleCan do
read_onlyRead dashboards, stats, snapshots, audit logs
read_writeEverything in read_only, plus send/receive messages and subscribe
adminEverything in read_write, plus manage accounts and revert configuration

Two account types:

TypeAuthenticates withNotes
userUsername + password, cookie sessionSubject to the idle and absolute session limits above.
serviceA 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-CSRF header. 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.

SettingTypeDefaultValid valuesDocker (config.yaml key · env var)Helm/CRD pathNotes
Portstringinherits Rest.Port (9090)1–65535connectors.http.port · CONNECTORS_HTTP_PORTspec.http.portEmpty ⇒ inherits the REST port. A differing explicit value logs a warning; the HTTP server uses Http.Port.
Read timeoutint (s)60≥ 0 (CRD ≥ 1)connectors.http.readtimeout · CONNECTORS_HTTP_READ_TIMEOUTspec.http.readTimeoutNegative rejected.
Body limitstring"100M"Echo size stringconnectors.http.bodylimit · CONNECTORS_HTTP_BODY_LIMITspec.http.bodyLimitCRD field is a string.
Base URLstring""URLconnectors.http.baseurl · CONNECTORS_HTTP_BASE_URLspec.http.baseUrlServer field is BaseURL; env ..._BASE_URL.
CORS allow originsstring[]["*"]origin listconnectors.http.cors.alloworigins · CONNECTORS_HTTP_CORS_ALLOW_ORIGINSspec.http.cors.allowOrigins
CORS allow methodsstring[]GET, POST, DELETE, OPTIONSmethod listconnectors.http.cors.allowmethods · CONNECTORS_HTTP_CORS_ALLOW_METHODSspec.http.cors.allowMethodsWider than REST — MCP/A2A need DELETE/OPTIONS.
CORS allow headersstring[]Authorization, Content-Type, MCP-Protocol-Version, MCP-Session-Id, Last-Event-ID, Acceptheader listconnectors.http.cors.allowheaders · CONNECTORS_HTTP_CORS_ALLOW_HEADERSspec.http.cors.allowHeadersIncludes the MCP-* headers.
CORS allow credentialsboolfalsetrue / falseconnectors.http.cors.allowcredentials · CONNECTORS_HTTP_CORS_ALLOW_CREDENTIALSspec.http.cors.allowCredentials
CORS expose headersstring[]MCP-Session-Id, MCP-Protocol-Versionheader listconnectors.http.cors.exposeheaders · CONNECTORS_HTTP_CORS_EXPOSE_HEADERSspec.http.cors.exposeHeaders
CORS max ageint (s)86400≥ 0connectors.http.cors.maxage · CONNECTORS_HTTP_CORS_MAX_AGEspec.http.cors.maxAgeNegative 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.

config.yaml
connectors:
  grpc:
    port: "50000"
values.yaml
grpc:
  port: 50000

For 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?

On this page