Guides

MQTT Security Best Practices: A Practical Checklist

Secure MQTT step by step: TLS, authentication with passwords, certificates or tokens, topic ACLs, client ID rules, payload encryption, rate limits, monitoring.

Updated · 8 min read

MQTT was designed for constrained networks, not hostile ones. Out of the box, many brokers accept anonymous clients on port 1883 and send everything in clear text. None of that is a flaw in the protocol — MQTT has all the hooks you need — but security is something you have to switch on. This guide walks through each layer and ends with a checklist you can use for reviews.

What you are protecting against

  • Eavesdropping — reading credentials and payloads on the network.
  • Impersonation — a rogue client connecting as one of your devices or services.
  • Unauthorized publishing — someone sending unlock to home/door/cmd.
  • Data leakage — a client subscribing to # and reading everything.
  • Denial of service — floods of connections or messages exhausting the broker.

1. Encrypt everything with TLS

TLS protects credentials and payloads in transit and lets clients verify they are talking to the real broker. Use port 8883 for MQTT over TLS and wss:// for browsers; disable or firewall the plain 1883 listener anywhere outside a trusted local network. Details in MQTT ports explained and MQTT over WebSockets.

  • Require TLS 1.2 or newer.
  • Always verify the server certificate on clients. Options such as --insecure, setInsecure() or rejectUnauthorized: false are for local debugging only.
  • Plan certificate renewal — an expired certificate takes every device offline at once.
Test a TLS connection with server verification
mosquitto_sub -h broker.example.com -p 8883 --cafile ca.crt \
  -u sensor-01 -P 'secret' -t 'devices/sensor-01/#' -v

2. Authenticate every client

Turn off anonymous access. Then choose an authentication method that fits each kind of client:

MethodGood forWatch out for
Username and passwordMost setups; supported by every client libraryOnly safe over TLS; give each device its own credentials
Client certificates (mutual TLS)Device fleets with a provisioning processNeeds a CA, revocation and certificate rotation
Tokens (for example JWT in the password field)Browser and mobile apps, short-lived accessBroker support varies; keep lifetimes short
MQTT 5 enhanced authenticationChallenge/response schemes such as SCRAMLimited support in brokers and client libraries

Never share one login across a fleet: if a single device is compromised, you want to revoke one credential, not re-flash every device. Store passwords hashed on the broker — Mosquitto users can follow the Mosquitto authentication guide, and the mosquitto.conf generator builds a secure configuration with TLS and password files.

3. Authorize topics with ACLs

Authentication answers who are you; authorization answers what may you do. Without ACLs, any authenticated client can read and write every topic. Apply least privilege: each client gets read or write access only to the topics it needs.

Mosquitto ACL file example
# backend service: read all telemetry, send commands
user backend
topic read devices/+/telemetry
topic write devices/+/cmd

# every device: only its own topics (%u = username)
pattern write devices/%u/telemetry
pattern read devices/%u/cmd

Pattern rules that substitute the username or client ID scale far better than one rule per device. Verify your filters with the topic matcher; MQTT wildcards are covered in topics and wildcards.

4. Control client IDs

A client that connects with an existing client ID kicks the original connection off the broker. An attacker who knows your IDs can use that to disconnect devices, and an accidental duplicate causes endless reconnect loops. Bind client IDs to credentials where your broker allows it (for example, require the client ID to equal the username or certificate common name), and avoid predictable IDs on shared brokers. The client ID generator helps create unique ones.

5. Design topics with security in mind

  • Put the device or tenant ID in a fixed position so ACL patterns can match it.
  • Separate telemetry (device writes) from commands (device reads) into different subtrees.
  • Keep secrets and personal data out of topic names — topics show up in logs and monitoring tools.
  • Be careful with retained messages on command topics: a retained unlock fires again on reconnect.

6. Encrypt or sign sensitive payloads

TLS protects each hop, but the broker sees payloads in clear text. If the broker operator or other services on it should not read the data, encrypt payloads end to end (for example AES-GCM with keys managed outside MQTT), or at least sign commands so devices can reject forged ones. Validate every incoming payload on the device: enforce size limits, check types and ignore unknown commands.

7. Set limits and rate limits

Cap maximum packet size, inflight and queued messages per client, connection rate and the number of subscriptions. MQTT 5 lets the broker announce limits such as maximum packet size and receive maximum to clients. Rate limits stop a buggy device in a publish loop from taking down everyone else — use the packet size calculator to set realistic size caps.

8. Protect credentials on devices and in apps

Device credentials end up in flash memory, and browser credentials end up in JavaScript bundles anyone can read. Assume they can be extracted: give each client the narrowest ACL possible, provision credentials per device at manufacturing or first boot instead of baking one secret into the firmware, and use flash encryption or a secure element where the hardware supports it. For web and mobile apps, issue short-lived credentials from your backend instead of shipping a long-lived password.

9. Monitor and log

  • Log connects, disconnects and authentication failures, and alert on spikes.
  • Watch for clients subscribing to # or $SYS/# unexpectedly.
  • Track connection counts and message rates per client to spot compromised or misbehaving devices.
  • Keep the broker and client libraries patched.

MQTT security checklist

AreaCheck
TransportTLS on 8883 / wss; plain 1883 disabled or firewalled; clients verify the server certificate
CertificatesRenewal automated or scheduled; expiry monitored
AuthenticationAnonymous access off; unique credentials per device or service; passwords hashed
AuthorizationACLs enforce least privilege; no client can subscribe to # without a reason
Client IDsUnique, ideally bound to the username or certificate
TopicsTelemetry and commands separated; no secrets in topic names; no retained commands
PayloadsValidated on receipt; sensitive data encrypted or signed end to end
LimitsMax packet size, queue sizes, connection and message rate limits configured
MonitoringAuth failures and unusual traffic logged and alerted; software patched
EnvironmentsNo production data on public brokers; separate credentials for dev and prod

When a locked-down client cannot connect, the CONNACK reason code tells you whether it was credentials or authorization — look it up in the MQTT reason code reference.

Frequently asked questions

Is MQTT secure by default?

No. Plain MQTT on port 1883 sends credentials and payloads unencrypted, and many brokers allow anonymous connections out of the box. MQTT becomes secure when you add TLS, require authentication and restrict each client to the topics it needs with ACLs.

Should I use username/password or client certificates for MQTT?

Both are fine over TLS. Username and password is simpler to manage and supported everywhere. Client certificates (mutual TLS) avoid shared secrets and suit large device fleets with a provisioning process. Many deployments use certificates for devices and passwords or tokens for backend services.

Is it safe to use a public MQTT broker?

Only for testing with dummy data. On a public broker anyone can subscribe to your topics and publish to them, there is no access control and no guarantee of availability. Real devices and real data belong on a private broker with authentication and TLS.