Skip to main content

Open navigation

Back to blog

MQTT Authentication: Password, JWT, SCRAM and AUTH

Understand MQTT authentication, configure each Mqttable client method, and separate a successful login from TLS protection and Topic permissions.

Author:
Mqttable Editorial
Published:
Hand-drawn MQTT authentication cover with a client, a key, a credential card and a broker exchanging messages.

An MQTT client can reach a Broker and still fail to connect. It can also connect successfully and then be denied permission to subscribe. Those are different failures, and changing a password will not fix both.

This guide explains the authentication mechanisms first, then uses Mqttable's New/Edit Client forms to configure and test them. Mqttable publishes this article and is the example workbench, not a requirement for implementing the protocol. Screenshots are from an isolated source Web Runtime, with disposable local credentials. They are not desktop-package, hosted-service or production acceptance evidence.

Authentication, AUTH, TLS and ACL are different layers

Authentication establishes the client identity accepted by the Broker. Authorization, often configured through a Topic ACL, decides what that identity may publish or subscribe to. TLS protects the connection and verifies the server; mutual TLS can additionally authenticate a client certificate.

The MQTT 5 AUTH packet is narrower than the word authentication. It carries an enhanced authentication exchange, such as SCRAM challenge response. Ordinary password authentication does not need AUTH packets. Neither does a JWT carried in the CONNECT password field. MQTT 5 defines the framework, not a mandatory password database, JWT issuer or SCRAM algorithm for every Broker. See MQTT 5 sections 3.15 and 4.12.

Schematic separating TLS transport protection, MQTT client authentication and Topic authorization.

Schematic, not a packet capture. A passing check at one layer does not prove the next layer works.

Client ID is also not a password. It identifies an MQTT session and must not collide with another active client. A Broker may include it in authentication or authorization policy, but knowing someone else's Client ID is not a secure authentication mechanism by itself.

Mqttable configures transport, server certificate trust and mTLS on the Broker. It configures Username, Password and Authentication Method on the Client. A CA certificate authenticates the server trust path; it is not a replacement for the client's MQTT password. Follow the TLS certificate guide when the failure occurs before MQTT authentication.

Choose an Authentication Method

The current MQTT 5 client form offers six choices. The selector is hidden for MQTT 3.1 and 3.1.1, where the form still has Username and Password. This is a Mqttable UI boundary, not a claim that MQTT 3.1.1 cannot authenticate or carry a token in the password field.

Scroll the table sideways to see all columns.

MethodMaterial you needWhat crosses the MQTT connectionBroker prerequisite
NoneNo MQTT password; clear Username for the anonymous exampleNo password; a nonempty Username can still be sentExplicitly permits this connection without a password
PasswordBroker-issued username/password, or a password SecretRefCONNECT Username and PasswordMatching password authenticator and account
JWTComplete signed token; Username if policy requires itIn this Mqttable mode, the token occupies CONNECT PasswordAccepts JWT from Password and trusts the correct signing key and claims
SCRAM-SHA-1Username/passwordSCRAM properties and challenge-response data, not a normal CONNECT passwordExplicitly supports this legacy mechanism
SCRAM-SHA-256Username/passwordMQTT 5 enhanced authentication using the exact method nameSupports SCRAM-SHA-256
SCRAM-SHA-512Username/passwordMQTT 5 enhanced authentication using the exact method nameSupports SCRAM-SHA-512

Choose the mechanism configured by the operator, not whichever label looks strongest. SHA-256 and SHA-512 are different SCRAM mechanisms; the client cannot silently substitute one for the other. The local EMQX 6.0.0 experiment supports those two variants, not SHA-1. That is a Broker limitation, not evidence that Mqttable lacks a SHA-1 option. EMQX's SCRAM documentation lists the supported hashes.

These client options are not an exhaustive list of every MQTT deployment's identity system. A Broker may validate certificates, call an HTTP authentication service or consult a database. The client usually needs only the wire-level mechanism and credentials that service expects.

Configure None or Password

None: make the anonymous boundary explicit

Use None only when the listener permits it. For this experiment, the anonymous Mosquitto listener binds to 127.0.0.1; it is not a public anonymous endpoint.

  1. Save a Broker pointing at that listener, then open New Client.
  2. Choose MQTT 5.0 and Authentication Method None.
  3. Clear Username. The password controls are disabled; selecting None suppresses the password, not necessarily the username.
  4. Give the test a unique Client ID and select Test Connection.
Mqttable's MQTT 5 client form with None selected and password controls disabled.

None describes the client's password behavior. Whether this identity may connect is still decided by the Broker.

Password: credentials and transport are separate

Choose Password, enter the MQTT username issued by the operator, and select Raw password for a one-off test. A cloud-console account is not automatically an MQTT account. Check the deployment's actual MQTT authentication settings.

Mqttable client password authentication using a masked raw-password field.

The password remains masked. Client Test Connection tests the current form, including credentials that have not been saved.

Username/password in CONNECT does not encrypt the connection. Use an appropriately verified mqtts or wss endpoint when credentials cross an untrusted network. The plain MQTT listeners in this article are loopback-only laboratories, not production security recommendations.

For repeated use, create a password secret under Credentials, then select Saved SecretRef in the Client form. The picker shows protected-reference metadata, not the raw secret. A missing or deleted reference is not an empty password that can safely be ignored. See Credentials and TLS for storage boundaries.

Mqttable selects a saved password SecretRef without rendering the secret value.

SecretRef changes where Mqttable obtains the credential. It does not change the Broker's password policy or make CONNECT encrypted.

JWT: match the token location, signature and claims

A JWT is a token format, not a new MQTT packet. This Mqttable authentication mode sends the token through Password. Configure the Broker to read JWT from that same field. Some Brokers can also read it from Username; choosing Mqttable's JWT mode does not automatically switch to that arrangement. EMQX documents both token locations.

If an authentication service gives you a complete token, paste it into Password or store it as a password SecretRef. Do not re-sign an issued token. In production, obtaining a token should follow the issuer's login/device flow. Do not distribute an issuer's HMAC master secret or RSA private key to ordinary clients simply so they can mint their own credentials.

HS256: a shared signing secret

For a controlled local experiment, select JWT and open JWT Tools. Choose HMAC (HS256), enter the disposable shared secret, and set the claims required by the Broker. The local experiment binds username to the MQTT Username and checks iss=mqttable-auth-lab and aud=mqttable-auth-demo.

Mqttable JWT Tools configured for HS256 with a masked signing secret and editable claims.

HS256 signs with a shared secret. The initial username, iat and exp rows are editable defaults, not a universal Broker policy.

Select Generate & Fill to place the token in the password draft, then inspect Preview. The signing secret is not the token. The Broker verifies the token with the matching secret and separately checks claims.

RS256: private signing key, public verification key

For RS256, the local signer needs a PEM private key, while the Broker needs the matching public key. Do not upload the private key to the Broker's JWT verification field. Keep the private key out of screenshots, shared logs and the article's example files.

Mqttable JWT Tools showing RSA RS256 and its PEM-key input before private signing material is entered.

Configuration screenshot taken before entering private material. Authentication success is verified separately; an empty key field is not proof of a signed token.

The local experiment generates an RSA key pair, configures only the public key on EMQX, and signs the client token with the private key. HS256 and RS256 are both tested, but this is not an external identity-provider or JWKS integration test.

Claims, Preview and JWT Debugger

Scroll the table sideways to see all columns.

ClaimQuestion to ask
expHas the token expired according to the verifier's clock?
nbfIs it too early to use this token?
iatWhen was it issued, and does this Broker enforce an issued-at policy?
issDoes the issuer exactly match the configured policy?
audWas this token issued for the service accepting it?
subWhich principal does it represent, and how is that mapped to permissions?

Not every Broker requires every claim. Use the operator's policy, including value types and clock tolerance. The local username claim is an experiment-specific check, not a replacement for the standard sub claim. RFC 7519 defines the registered claims.

JWT Tools Preview decodes the current draft so you can read its header and claims. Open in JWT Debugger provides a separate local inspection workflow. In the verified source baseline, its signature check supports HS256, HS384 and HS512, not RS256. The HS256 signature-match check and return with the original draft were exercised; RS256 acceptance was verified at the Broker, not by this debugger. Decoding Base64url is not signature verification, and a signature-valid token can still fail issuer, audience or expiry checks. JWT payloads in these signed JWS examples are readable, not encrypted.

Returning from the debugger with an inspected or edited token does not save the Client or connect it. Hidden saved credentials and signing keys are not automatically retrieved for that handoff. Test the resulting password draft against the actual Broker. Mqttable's connection path does not acquire, automatically renew or refresh the token.

Mqttable Client Test Connection rejecting an expired local JWT.

This is the experiment's observed rejection. A generic authentication reason code alone does not prove that expiry, rather than a signature or claim mismatch, was the cause.

Whether an already connected client is disconnected when its token expires is Broker policy. It is not the same as rejecting an expired token during CONNECT and is not implied by the client selecting JWT.

SCRAM and the MQTT 5 AUTH exchange

SCRAM uses the username and password to construct a challenge-response exchange. Mqttable does not place the password in the normal CONNECT Password field for its SCRAM modes. This avoids transmitting that raw password as the basic MQTT credential, but does not encrypt application messages and does not remove the need for an appropriately protected network path.

  1. Confirm the exact Broker mechanism, then choose MQTT 5.0.
  2. Select SCRAM-SHA-256 or SCRAM-SHA-512 to match it.
  3. Supply both Username and Password, directly or through a populated SecretRef.
  4. Test the current form, then connect a saved Client and verify message permissions separately.
Mqttable client configured for MQTT 5 SCRAM-SHA-256.

The password is used locally to compute the SCRAM proof. Both username and password are required.

Mqttable client configured for SCRAM-SHA-512, matching the experiment's SHA-512 authenticator.

Changing only the client variant does not change the Broker. The experiment reconfigures the isolated Broker before testing this variant.

Read the exchange without calling every step a login success

The SCRAM client-first message supplies the initial identity/nonce data. The server-first challenge adds its nonce, salt and iteration count. The client-final message proves knowledge of the password-derived material, and the server-final message carries the server's signature. The exact calculations belong to the SCRAM mechanism; MQTT transports those messages. See RFC 5802 and SCRAM-SHA-256 in RFC 7677.

Schematic comparing basic CONNECT authentication with MQTT 5 SCRAM challenge response.

Protocol schematic. The initial authentication completes with an accepted CONNACK; AUTH 0x18 means more authentication data is needed.

Authentication Method and Authentication Data are properties, not an AUTH payload; AUTH has no payload. The method must remain consistent with CONNECT. AUTH 0x00 represents successful authentication, 0x18 continues the exchange, and 0x19 is the client's request for re-authentication after connection establishment. Initial authentication acceptance and re-authentication are different flows.

The protocol permits re-authentication, but this guide does not claim Mqttable offers an automatic or user-triggered re-authentication control. It also does not claim channel-binding variants such as SCRAM-SHA-256-PLUS are present in this selector.

SHA-1 is a compatibility option, not a fallback

Mqttable exposes SCRAM-SHA-1. Use it only for an explicitly documented legacy requirement; prefer the supported SHA-256 or SHA-512 mechanism when choosing a new deployment. Do not silently downgrade because a stronger method failed.

Mqttable's SCRAM-SHA-1 selection rejected by the local EMQX authenticator.

This Broker does not support SHA-1. The rejection is not a successful SHA-1 exchange and is not proof of a client implementation failure.

Edit Client: keep, replace or clear a saved credential

Editing a saved client is not the same as entering a fresh password. In Raw password mode, Password saved · Kept unless replaced means the saved value is retained without displaying it.

Mqttable Edit Client showing a retained saved password, Replace and Clear on save.

A retained password is not an empty credential. The UI deliberately does not reveal its original value.

  • Keep: leave the saved credential unchanged. Entering replacement mode but leaving the field blank preserves the existing value unless Clear on save is selected.
  • Replace: select Replace, enter the new password or token, test the current form while the Client is disconnected, then save. A successful test alone does not persist the replacement.
  • Clear: select Clear on save and save deliberately. If the chosen method requires a credential, validation can reject that empty state; do not treat a rejected save as a cleared credential.
  • Saved SecretRef: select the intended reference. It is a different credential source, not a second authentication layer. Switching back to Raw password must be checked rather than assumed to reveal or copy the referenced secret.
  • None: stops using the password for that connection. It is not a command to delete stored secrets or references.

Disconnect before validating a changed configuration. For a connected Client, Mqttable shows authoritative runtime status and warns that current edits are unverified; the draft is not proof that the active connection uses those settings. Use Brokers and connections for the full save/connect workflow.

Prove authentication and Topic permission separately

Broker Test Connection uses the endpoint and configured transport/TLS, but not the New Client username/password. Authentication refusal in that probe is not, by itself, a TLS certificate error.

Client Test Connection tests the full current form without saving it. It can use an unsaved password/token, retained saved credential, SecretRef or SCRAM selection. Success is an ephemeral authenticated connection that immediately disconnects, not a persistent Connected client or a message permission test.

The test uses the real Client ID and session settings. Another client with that identity may be disconnected, its Will may be triggered, and session state may be affected. Mqttable blocks known locally active identities, but cannot rule out an unknown external client. Use dedicated Client IDs, no Will and no valuable persistent sessions in this laboratory.

For each successful method, complete a second test:

  1. Save and connect the Client. Check Connected and an accepted CONNACK where it is visible.
  2. Subscribe to the explicitly permitted mqttable/auth/lab/<method> Topic at QoS 1, with No Local off.
  3. Wait for successful SUBACK before publishing.
  4. Publish a small synthetic JSON payload to that same Topic, QoS 1, Retain off.
  5. Find both outgoing and incoming PUBLISH with the same Topic and payload. PUBACK alone does not prove a subscriber received it.
Mqttable showing a successful authenticated subscribe and matching outgoing and incoming PUBLISH messages.

The message loop proves more than CONNECT. It does not prove TLS, other Topic permissions or production readiness.

The Mosquitto password listener denies the separate mqttable/auth/denied Topic. With the same valid credentials, subscribing returns successful SUBACK in this Mosquitto configuration, but publishing at QoS 1 returns PUBACK 0x87 (Not authorized). The subscription receipt is not a grant of publish permission, and read ACLs can still filter delivery. The screenshot demonstrates the publish denial after authentication has succeeded.

An authenticated Mqttable client receives PUBACK Not authorized for publishing outside its ACL.

Keep the accepted identity and inspect its ACL. Replacing a correct password is not the first fix for this failure.

Troubleshoot the failed stage

Scroll the table sideways to see all columns.

Observed resultCheck next
Form says JWT token or SCRAM credentials are requiredCredential source, populated SecretRef, required username/password and MQTT version; no network authentication has happened yet
TLS fails before CONNACKHost, listener protocol, CA trust, certificate name and required client certificate
MQTT 5 CONNACK 0x86, Bad User Name or PasswordAccount, password/token, JWT signature and claims, enabled authenticator and listener policy
CONNACK 0x87, Not authorizedConnection policy and authentication chain; the result alone does not isolate an ACL rule
CONNACK 0x8C, Bad authentication methodExact enhanced-authentication method and Broker support
Connected, then SUBACK/PUBACK denies an operationTopic, action, QoS/Retain restrictions and the authenticated principal's authorization rules
Mqttable's Client Test Connection reports failure for an intentionally incorrect local password.

One changed credential reproduces this negative case. A generic rejection in another deployment still requires its own evidence.

Do not assume every Broker returns the same detailed failure. The MQTT standard permits refusal or connection closure in several paths, and operators may intentionally avoid disclosing why a credential failed. Record the version, listener, method, packet direction and exact observed result, without copying secrets into support tickets. The authentication guide is the shorter configuration reference.

Does a JWT require MQTT 5 AUTH?

No. A token in CONNECT Password is basic credential transport and can also be used with MQTT 3.1.1 if the Broker supports that arrangement. An enhanced-authentication method could define a token exchange, but that is not what this Mqttable JWT mode does.

Does SCRAM make plain MQTT safe on the public internet?

No. Not sending the raw password as CONNECT Password is narrower than protecting the whole connection. Use verified TLS or an explicitly assessed protected transport, and do not expose this article's plain loopback listeners publicly.

Why does an authentication test pass while publishing fails?

The Broker accepted the connection identity but may deny the Topic operation. Check SUBACK/PUBACK and the ACL, then repeat the publish and subscribe workflow on an allowed Topic.

Is a decoded JWT valid, and will Mqttable renew it?

Decoding only reveals the token's structure. Acceptance still requires the right signature and claims policy, and this connection path does not automatically acquire or refresh tokens. Obtain replacements through the issuer's authorized flow and test the updated draft.

Can I copy the signing keys and screenshot credentials into my deployment?

No. The experiment uses disposable local material. Create credentials under your own operator's policy, keep signing keys in the proper issuer boundary, and rotate any secret that has been exposed. Start with the Broker's required mechanism, prove the connection, then prove the exact Topic operation you need.