MQTT JWT authentication means a client puts a signed JSON Web Token in the password field of its CONNECT packet, and the broker validates the signature and claims instead of looking up a stored password. This article explains how that works on the wire, how to deal with token expiry and refresh on real devices, and when the extra moving parts are worth it compared with static per-device credentials.
How a JWT Rides Inside MQTT CONNECT
MQTT has no dedicated token field in its basic authentication. What it has is a username string and a password field that the specification defines as binary data. Brokers that support JWT reuse that field:
CONNECT
Client ID: sensor-0042
Username: sensor-0042 (often ignored or matched to a claim)
Password: eyJhbGciOiJSUzI1NiIs... (the encoded JWT)
A JWT has three base64url-encoded parts separated by dots: a header naming the algorithm, a payload of claims and a signature. A typical device token's claims look like this:
{
"iss": "https://auth.example.com",
"sub": "sensor-0042",
"aud": "mqtt.example.com",
"iat": 1792130400,
"exp": 1792134000,
"topics": {
"pub": ["plant1/line3/sensor-0042/#"],
"sub": ["plant1/line3/sensor-0042/cmd/#"]
}
}
The broker, or an authentication plugin attached to it, then:
- Decodes the token and checks the signature with a shared secret (HS256) or a public key (RS256, ES256).
- Checks
exp,nbf,issandaud. - Optionally compares
subwith the client ID or username. - Optionally reads custom claims to decide which topics the client may use.
Because the token travels as a password, the same rule applies as for any MQTT username password authentication scheme: it must be sent over TLS. A JWT is a bearer credential. Anyone who captures it can use it until it expires.
MQTT 5 Enhanced Authentication
MQTT 5.0 adds an Authentication Method property and an AUTH packet so broker and client can run challenge-response exchanges, and re-authenticate during a live session without disconnecting. Some brokers expose token methods through this mechanism, which allows refreshing a token on an open connection. Support varies a lot between brokers and client libraries, so most deployments still use the simpler password-field approach and reconnect to refresh. The OASIS MQTT 5.0 specification describes the AUTH flow.
Which Brokers Support JWT?
JWT is a broker or plugin feature, not part of MQTT itself. Some brokers include a JWT authenticator, and Mosquitto can validate tokens through third-party authentication plugins. Check your broker's documentation for which algorithms, key sources (static key or a JWKS endpoint) and claim mappings it supports.
ConnectMQ does not support JWT authentication. A ConnectMQ broker authenticates clients with the username and password generated in the portal, and binds each client ID to its issued credentials. Tenants are isolated from each other, so those credentials only reach your own broker. The trade-offs below will help you decide whether that model or a token model suits your project.
Issuing and Using a Token: Example
The example below shows the two halves of a JWT setup against a hypothetical broker at mqtt.example.com that validates RS256 tokens. First, a minimal issuer service signs a token for a device:
# pip install pyjwt cryptography
import time
import jwt
PRIVATE_KEY = open("issuer_private.pem", "rb").read()
def issue_device_token(device_id: str, ttl_seconds: int = 3600) -> str:
now = int(time.time())
claims = {
"iss": "https://auth.example.com",
"sub": device_id,
"aud": "mqtt.example.com",
"iat": now,
"nbf": now - 30, # tolerate small clock skew
"exp": now + ttl_seconds,
}
return jwt.encode(claims, PRIVATE_KEY, algorithm="RS256")
if __name__ == "__main__":
print(issue_device_token("sensor-0042"))
Then the device connects with the token as its password and reconnects with a fresh token before expiry:
# pip install paho-mqtt requests
import ssl
import time
import requests
import paho.mqtt.client as mqtt
DEVICE_ID = "sensor-0042"
TOKEN_URL = "https://auth.example.com/device-token"
REFRESH_EVERY = 50 * 60 # refresh 10 minutes before a 60-minute expiry
def fetch_token() -> str:
# The device authenticates to the issuer with its own long-term secret
r = requests.post(TOKEN_URL, json={"device": DEVICE_ID}, timeout=10)
r.raise_for_status()
return r.json()["token"]
def on_connect(client, userdata, flags, reason_code, properties):
print("CONNACK:", reason_code)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=DEVICE_ID, protocol=mqtt.MQTTv5)
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.on_connect = on_connect
def connect_with_fresh_token():
client.username_pw_set(DEVICE_ID, fetch_token())
client.connect("mqtt.example.com", 8883, keepalive=60)
client.loop_start()
connect_with_fresh_token()
while True:
time.sleep(REFRESH_EVERY)
client.disconnect() # clean disconnect, session kept if configured
client.loop_stop()
connect_with_fresh_token()
Note the comment in fetch_token: the device still needs some long-term secret or certificate to prove itself to the issuer. JWT moves the static credential from the broker connection to the issuer connection; it does not remove it.
Expiry and Refresh Patterns
Expiry is the main reason to use tokens, and also the main source of production incidents. Brokers handle an expiring token in one of two ways:
| Broker behaviour | Effect on the client |
|---|---|
Checks exp only at CONNECT |
Session continues after expiry until the next reconnect |
Disconnects the client at exp |
Client must reconnect with a new token before that moment |
Patterns that work on devices:
- Refresh early. Request a new token at roughly 80 percent of its lifetime, not at expiry.
- Reconnect cleanly. Use a persistent session (Clean Start false with a session expiry) so subscriptions and queued QoS 1 messages survive the reconnect.
- Keep the clock right. A device whose clock is wrong will produce or reject tokens incorrectly. Sync time with NTP before requesting a token, and allow a small skew with
nbf. - Handle issuer outages. If the issuer is down, the device keeps its current connection and retries with backoff; it should not drop a working session.
- Log CONNACK reasons. An expired or invalid token typically produces
0x86(Bad User Name or Password) or0x87(Not authorized) in MQTT 5.
Token Security Pitfalls
Tokens fail in ways that passwords do not, so review these before going to production:
- Algorithm confusion. Configure the broker to accept only the algorithm you issue, for example RS256. Never accept
none, and never let the token header choose between symmetric and asymmetric verification. - Shared HMAC secrets on devices. If devices could sign their own HS256 tokens, every device holds the master secret. Sign tokens on the server side only.
- Overly long lifetimes. A token valid for a year is just a password with extra steps. Keep lifetimes short enough that a leaked token expires quickly, and long enough that devices on poor networks are not refreshing constantly.
- Missing audience checks. Without
aud, a token issued for another service can be replayed against your broker. - Logging tokens. Tokens end up in debug logs and crash reports just like passwords. Log the
subandexp, never the token.
JWT Versus Static Per-Device Credentials
| Factor | JWT | Static per-device credentials |
|---|---|---|
| Lifetime of a stolen secret on the wire | Until token expiry | Until the credential is rotated |
| Extra infrastructure | Token issuer, key management, clock sync | None beyond the broker |
| Revocation | Wait for expiry or maintain a deny list | Revoke the credential |
| Authorization data | Can carry topic claims in the token | Managed on the broker side |
| Device complexity | HTTP client, token refresh logic, NTP | Store one password |
| Debugging | Decode token, check claims and clocks | Check username and password |
JWT shines when you already run an identity provider, when users (not just devices) connect from browsers or mobile apps with short sessions, or when you want authorization embedded in the credential itself.
Static per-device credentials shine for device fleets where simplicity matters: microcontrollers with limited resources, sites with unreliable access to an issuer, and teams that do not want to operate an authentication service. Their weakness, long-lived secrets, is handled with protected storage and planned rotation. See how to rotate MQTT credentials and the design notes in MQTT ACL concepts for the authorization side.
A Middle Ground With a Managed Broker
If what you want from JWT is mostly "no shared secrets and a quick way to cut off one device", you can get most of that without tokens: give each device its own credential set, bind it to a client ID, keep it in protected storage and rotate it on a schedule. That is the model a fully managed MQTT service like ConnectMQ provides out of the box, with TLS on 8883 and 8084, IP blocking after repeated failed logins and tenant isolation. For browser apps, keep the broker credentials on your backend and let users authenticate to your backend with whatever token system you already use.
Get Started with ConnectMQ
Want strong per-device authentication without running a token issuer? Create a free Serverless cloud MQTT broker at app.connectmq.com, no credit card required, and connect your first device over TLS with generated credentials in minutes.
Frequently Asked Questions
Does ConnectMQ support MQTT JWT authentication?
No. ConnectMQ authenticates clients with generated usernames and passwords, with each client ID bound to its issued credentials. Tenants are isolated from each other.
Where does the JWT go in an MQTT connection?
Most brokers expect it in the password field of CONNECT, sometimes with the username set to the device ID or a fixed value. Some MQTT 5 brokers also accept tokens through enhanced authentication.
What happens when the token expires during a session?
It depends on the broker. Some only validate at connect time, others disconnect the client at expiry, so devices should refresh and reconnect before the token expires.
Is JWT more secure than a password?
A short-lived token limits how long a stolen credential works, but devices still need a long-term secret to obtain tokens. Overall security depends on how both secrets are stored and transported.



