Skip to content
Stand with Ukraine flag

Security model

TBMQ enforces security in three sequential layers: transport encryption, authentication, and authorization. Every connection passes through all three in order — a client cannot reach the authentication step without a valid transport channel, and cannot publish or subscribe without passing authorization. Understanding this layered model helps you decide which options to enable and in what combination for your deployment.

The three layers are independent and composable. You can run unencrypted TCP with Basic authentication in a trusted private network, or mutual TLS with JWT and strict per-topic authorization for a public-facing deployment. Each layer has sensible defaults, and each can be tuned without touching the others.

Transport security is configured through listeners — the network endpoints the broker accepts connections on. Four listener types are available:

ListenerProtocolDefault portEncrypted
TCPMQTT over plain TCP1883No
SSL/TLSMQTT over TLS8883Yes
WSMQTT over WebSocket8084No
WSSMQTT over WebSocket Secure8085Yes

Each listener is independently enabled or disabled. In production, disable the plain TCP and WS listeners and use only TLS or WSS to prevent credentials from being sent in clear text.

One-way vs mutual TLS: TLS listeners support both modes.

  • One-way TLS: the client verifies the broker’s certificate. Credentials still travel in the CONNECT packet.
  • Mutual TLS (mTLS): both sides present certificates. This is the foundation for X.509 certificate authentication.

For configuration details, see Listeners and MQTTS.

Authentication verifies client identity during the MQTT CONNECT handshake. TBMQ implements authentication as pluggable providers — each method is a separate, individually enabled provider. TBMQ tries them in a configurable execution order and grants access on the first successful match.

MethodHow identity is provedCredential locationNotes
BasicclientId, username, and/or passwordCONNECT packet fieldsMost common; Redis lookup for performance
X.509Client TLS certificate (CN matched against stored credentials)TLS handshakeRequires mTLS listener; supports exact and regex CN matching
JWTSigned JSON Web Tokenpassword field of CONNECTNo static credentials stored; supports HMAC, PEM, and JWKS verifiers
SCRAMChallenge-response using hashed credentialsMQTT 5.0 enhanced authPassword never transmitted in clear text; MQTT 5.0 only
HTTPDelegated to an external HTTP serviceExternal systemReturns clientType and authorization rules dynamically

Adding or removing providers is not supported — only their configuration and execution order can be changed.

When multiple providers are enabled, TBMQ tries each in the configured sequence until one successfully authenticates the client. If no provider grants access, the connection is refused.

Configure the order on the MQTT Authentication Settings page.

Matched credentials are cached in Redis for fast lookups on subsequent CONNECT packets from the same client. PostgreSQL is the persistent store; Redis is the performance layer in front of it.

SituationRecommended method
Internal IoT devices with fixed credentialsBasic
Devices already enrolled with certificates via PKIX.509
Integration with an OAuth2 / OpenID Connect identity providerJWT
Regulated environment where plaintext passwords are not acceptableSCRAM
Credentials managed by an existing external system or custom logicHTTP
Multiple credential types coexist in the same deploymentEnable multiple providers, set execution order

Authorization controls what an authenticated client can do after connecting. TBMQ enforces topic-level access control per credential using regular expression patterns. Publish and subscribe permissions are configured independently.

For example, a credential sensor-device-001 might carry these rules:

FieldValue
Publish rulesensors/device-001/.*
Subscribe rulecommands/device-001/[^/]+

When a client publishes to a topic not covered by its authorization rules, the broker’s response depends on the MQTT version:

  • MQTT 3.x — the broker disconnects the client.
  • MQTT 5.0 — the broker sends a PUBACK (QoS 1) or PUBREC (QoS 2) with the Not Authorized reason code, and the client remains connected.

When a client subscribes to a topic not covered by its authorization rules, the broker sends a SUBACK with the Not Authorized reason code. The subscription is not established.

Two providers support returning authorization rules at connection time rather than storing them statically:

  • JWT: rules extracted from token claims. The token payload can specify client type and topic patterns, enabling centralized access control through your identity provider.
  • HTTP: the external authentication service returns clientType and authorization rules in its response body. If the response omits these fields, the provider’s default rules apply.

This means you can manage topic permissions in your identity system and have TBMQ enforce them without maintaining per-device credential records in the broker.

Each credential carries two things: topic authorization rules and a client type. Both are resolved from the same credential during the CONNECT handshake.

The clientType field determines whether the connecting client is treated as DEVICE or APPLICATION, which controls how the broker stores its session state and routes messages to it — not just what topics it can access.

For example, a credential sensor-gateway-001 might carry these attributes:

FieldValue
clientTypeDEVICE
Publish rulesensors/gateway-001/.*
Subscribe rulecommands/gateway-001/[^/]+

For static providers (Basic, X.509, SCRAM), clientType is set when the credential is created in the UI and does not change between connections. For dynamic providers (JWT, HTTP), clientType is returned at connection time — the JWT payload or HTTP response body can specify it, which allows the same broker credential store to serve clients of different types without creating separate credential records.

A practical example for a production IoT deployment:

LayerConfiguration
TransportSSL listener (mutual TLS, port 8883)
AuthenticationX.509 provider — CN matched against device credentials
AuthorizationPublish to sensors/{device-id}/+, subscribe to commands/{device-id}/+

Result: the device’s identity is proven by its certificate (no password needed), the channel is encrypted, and the broker rejects any attempt to publish to another device’s topic.