Skip to content
AdminKit

How to secure an MQTT broker: authentication, TLS and ACLs

Secure an MQTT broker by requiring authentication for every connection, disabling anonymous access, encrypting traffic with TLS on port 8883 instead of plaintext 1883, and restricting each client to the topics it actually needs with an access-control list — in that order, since authentication without TLS still leaks credentials in transit, and neither one limits what an already-authenticated client can do once connected.

By AdminKit team, Netbase JSC · Updated October 27, 2026

Why MQTT deployments start insecure by default

MQTT is a lightweight publish/subscribe protocol built for constrained devices and unreliable networks, which is exactly why it’s the default choice behind most IoT sensors, building-automation systems, and message buses between backend services. The OASIS MQTT 5.0 standard (read 2026-10-27) dedicates a full section to security and explicitly supports authentication, authorization, and encrypted transport — but it makes none of them mandatory. A conforming broker can accept anonymous connections, send every message in plaintext, and let any connected client publish or subscribe to any topic, all without violating the spec. Most broker software ships with anonymous access enabled out of the box specifically to make initial setup painless, which means every deployment starts from “open” and has to be deliberately locked down — nothing does that automatically.

This guide covers the four controls that matter, in the order that makes each one effective: confirm what’s currently exposed, require authentication, encrypt the connection, and restrict topics. It applies whether you’re running a single Mosquitto instance for a dev prototype, a broker behind a fleet of production IoT devices, or a cluster fronting an industrial sensor network — the configuration directives differ by broker software, but the four controls are the same everywhere.

Step 1: Find out what you’re starting from

Before changing anything, confirm your current exposure. AdminKit’s MQTT exposure check is built to test whether a broker is reachable from outside your network and whether it accepts an anonymous connection on the standard plain (1883) or TLS (8883) ports — registered with IANA for exactly that purpose, per the IANA Service Name and Transport Protocol Port Number Registry (read 2026-10-27). That check is coming with the AdminKit Check API and is not live yet, so today the equivalent manual test, with the mosquitto client tools installed, is:

mosquitto_sub -h <host> -p 1883 -t '#' -v -C 1

If this connects and either prints a retained message or simply returns without an authentication error within a few seconds, the broker currently accepts anonymous connections. Run this only against a broker you own or are explicitly authorized to test — confirm your own public IP first with what is my IP if you’re testing from outside your own network. Knowing whether you’re starting from “wide open” or “already requires credentials” changes how urgently each step below matters.

Step 2: Require authentication for every client

Disable anonymous access and issue a distinct username and password to every device or application that connects. On Mosquitto, this means setting allow_anonymous false in the configuration and maintaining credentials with mosquitto_passwd, written into the file referenced by the broker’s password_file directive, per the mosquitto.conf documentation (read 2026-10-27) — which also notes that allow_anonymous defaults to false already, unless no listener is defined at all, in which case it defaults to true but only for connections from the local machine. In other words, the moment you configure a network-facing listener, you’re responsible for setting allow_anonymous false explicitly; the safe default only covers the trivial local-only case.

Avoid one shared credential for every device. A single username and password used across an entire fleet means one leaked or extracted credential — pulled from a device’s flash memory, a misconfigured mobile app, or a support ticket pasted into the wrong place — compromises every other client using it. Per-client credentials mean a single compromise is contained to that one client, and let you revoke exactly one credential without disrupting the rest of the fleet.

Step 3: Encrypt the connection with TLS

Authentication and encryption are two separate settings, and enabling one does not enable the other — a broker can require a valid username and password while still accepting that login over an unencrypted connection, which means the credential itself travels in plaintext and can be captured by anything observing the network path. Move clients from plaintext port 1883 to TLS on port 8883, the registered port for secure MQTT per the IANA registry cited above. On Mosquitto, this means configuring a dedicated listener with cafile, certfile, and keyfile pointing at a certificate authority bundle and the broker’s own certificate and private key, as described in the mosquitto-tls documentation (read 2026-10-27).

For deployments where devices are unattended and credential theft from the device itself is a realistic risk — a fleet of sensors in physically accessible locations, for example — consider mutual TLS: requiring the broker to also verify a client certificate (require_certificate true on Mosquitto), binding the connection to a certificate issued to that specific device rather than a credential alone. This is more operational overhead (issuing and rotating a certificate per device, instead of a password) and isn’t necessary for every deployment, but it closes a gap that username/password alone cannot: a stolen password can be reused from anywhere, while a private key that never leaves the device cannot.

Step 4: Restrict topics with an access-control list

Authentication answers “who is this client.” A topic-level access-control list answers a separate question: “which topics can this specific, already-authenticated client publish to or subscribe to.” Without one, every authenticated client — including a temperature sensor that should only ever publish to its own topic — can typically subscribe to and publish on every topic the broker serves, including ones that control other devices entirely.

Mosquitto’s acl_file directive, per the mosquitto.conf documentation, lets you scope each authenticated user to specific topic patterns, with only the topics explicitly listed granted access. A practical pattern is to scope each device to a namespace under its own identity — devices/<device-id>/# for publish, with read access only to the specific command topics it needs to subscribe to — rather than a flat, shared topic space every client can see into. This is the control that limits the blast radius when, not if, one device on the broker is eventually compromised: a compromised temperature sensor restricted to its own topic namespace cannot also read or forge commands meant for a door-lock controller on the same broker.

Step 5: Harden broker-level settings beyond auth and ACLs

A handful of broker-level settings matter beyond the three controls above:

  • Bind to the interfaces you actually need. Many broker installs listen on every network interface by default (0.0.0.0), which is convenient during setup but means the broker is reachable from every network segment the host touches, not just the intended one. Configure each listener to bind to a specific interface instead.
  • Set connection and message-rate limits. A broker with no limit on simultaneous connections or message rate from a single client is more exposed to a resource-exhaustion attack from either a misbehaving device or a malicious actor who’s obtained valid credentials.
  • Disable any listener you’re not using. If a broker ships with a default configuration exposing both an unencrypted and an encrypted listener, and you’ve moved every client to TLS, turn the plaintext listener off entirely rather than leaving it reachable “just in case.”

MQTT 3.1.1 versus 5: what changed for security

Most of the controls above apply identically to MQTT 3.1.1 and 5, since authentication, TLS, and ACLs are implementation-level broker features, not protocol-version features. The one protocol-level addition in MQTT 5 is the AUTH packet, described in the OASIS standard’s enhanced authentication section, which supports extended, challenge-response authentication methods (such as SCRAM) beyond the plain username/password fields both versions carry in CONNECT. It’s additive, not a replacement: a broker can run MQTT 5 and still authenticate every client with a username and password exactly as MQTT 3.1.1 does, and most production deployments do exactly that today, since enhanced authentication requires both broker and client library support that isn’t universal yet.

Re-check after every change

Broker configuration is easy to get subtly wrong: a password file with permissions that let other local accounts read it, an ACL rule scoped more broadly than intended, or a TLS listener left pointed at the wrong certificate path. Re-run the exposure check — MQTT exposure check once it ships, or the manual mosquitto_sub command above today — after each configuration change, rather than assuming an edited config file took effect the way you expect. A broker that’s been reconfigured correctly should now refuse the exact anonymous connection attempt that succeeded before you started.

Where AdminKit’s Secure Broker fits

Everything above is self-configuration: directives you set yourself on a broker you run. AdminKit’s Secure MQTT Broker is a planned managed alternative for teams who’d rather not configure and operate all of this — a hosted broker that requires credentials for every connection by default, with per-topic ACLs and anomaly detection for unusual publish patterns, aimed at IoT product builders and system integrators who today often find every device on a broker sharing one set of credentials with access to every topic. It is early access / in development, not live yet, which means the steps in this guide remain the practical path for securing a broker today, self-hosted or otherwise.

MQTT isn’t the only machine protocol where “no authentication by default” is documented, spec-compliant behavior rather than a bug. Modbus TCP, common on industrial and building-automation networks, has the same history for similar reasons — see the Modbus TCP 502 remediation playbook if your MQTT broker also bridges data from OT equipment on the same network. If your deployment is specifically a home or small-business setup rather than a production or industrial one, see how to harden a home or SMB MQTT broker for the same controls applied to that smaller-scale context.

Defensive use only

Every check this guide links to is for brokers and networks you own or are explicitly authorized to test. Never connect to or attempt to read from a broker you don’t control — AdminKit’s active checks only ever run against the IP making the request or an asset you’ve verified ownership of. See our Disclaimer and Acceptable Use Policy for the full terms.

This guide is general information, not a security audit of your specific network — see our disclaimer for what AdminKit's guidance does and does not commit to.

Frequently asked questions

If I can only do one thing today, what's the highest-priority fix?

Disable anonymous access and require a distinct username and password for every client. An unauthenticated broker lets anyone who can reach it read and publish to every topic; that single setting change closes the most severe gap, even before TLS or ACLs are in place.

Does MQTT 5's enhanced authentication (the AUTH packet) replace username and password?

No. MQTT 5 added an AUTH packet to support extended, challenge-based authentication methods (such as SCRAM) beyond the simple username/password fields carried in the CONNECT packet, but it's an additional, optional mechanism, not a replacement — a broker is free to keep using username/password, and most deployments still do.

Is mutual TLS (client certificates) necessary, or is username/password enough?

Username and password over a TLS-encrypted connection is a reasonable baseline for most deployments. Mutual TLS, where the broker also verifies a certificate presented by the client, adds a second factor tied to the device itself rather than a credential that could be copied or shared, which matters more for fleets of unattended IoT devices than for a handful of trusted services.

How do I know if my broker is already exposed before I touch its configuration?

Use AdminKit's MQTT exposure check to test whether a broker responds from outside your network and whether it accepts an anonymous connection. That tool is coming with the AdminKit Check API and isn't live yet — see the manual mosquitto_sub command in this guide for the same check today.

Can a topic-level ACL substitute for authentication?

No. An access-control list scopes what an already-identified client can do; it has nothing to check against if the broker doesn't first establish who the client is. Configuring an ACL on a broker that still allows anonymous connections means every anonymous client inherits whatever the ACL's default or catch-all rule allows.

Where does a managed broker fit if I'd rather not configure all of this myself?

AdminKit's planned Secure MQTT Broker is a managed service aimed at exactly this: authentication required by default, with no anonymous-access option, plus per-topic ACLs and anomaly detection. It's early access / in development, not live yet, so self-configuring the steps below remains the practical path today.

Want AdminKit to watch this for you?

Free checks tell you the state today. Protective DNS and monitoring tell you when it changes.

Huy Nguyen (David), Founder and CEO of Netbase JSC

Talk to an expert

Huy Nguyen (David), Founder & CEO, Netbase JSC

Ask whether this fix applies to your setup, or get a second pair of eyes on your DNS and mail records.