MQTT brokers are surprisingly leaky by default, allowing any client to connect, publish, and subscribe to any topic. This article covers how to lock them down using authentication and Access Control Lists (ACLs).

Let’s see this in action. We’ll set up a Mosquitto broker with a simple username/password authentication and an ACL that restricts one user to a specific topic.

First, the broker configuration. We need password_file and acl_file.

# mosquitto.conf
# ... other config ...
password_file /etc/mosquitto/passwd
acl_file /etc/mosquitto/acl
allow_anonymous false

Next, create the password file. We’ll use mosquitto_passwd to add a user named alice with the password secret.

sudo mosquitto_passwd -c /etc/mosquitto/passwd alice
# Enter password: secret
# Re-enter password: secret

Now, the ACL file. This grants alice read/write access to sensors/temperature/#.

# /etc/mosquitto/acl
# user <username> <topic> <rw>
user alice sensors/temperature/# rw

Restart Mosquitto for these changes to take effect:

sudo systemctl restart mosquitto

With this setup, a client connecting as alice with password secret can publish and subscribe to sensors/temperature/room1, sensors/temperature/kitchen, etc. If alice tries to subscribe to alarms/# or publish to status/broker, the broker will deny the connection or the operation.

The core problem MQTT solves is efficient, low-overhead messaging for devices with limited resources. Authentication and ACLs are built on top of this to prevent unauthorized access and manipulation of that messaging.

Authentication verifies who a client is. This is typically done with username/password pairs, client certificates, or other credentials. The broker checks these credentials against a source of truth (like our password_file).

ACLs, on the other hand, determine what an authenticated client can do. They define granular permissions for specific topics. A common ACL structure is topic read/write. rw means both publish and subscribe. r is subscribe only, w is publish only.

The allow_anonymous false directive is crucial. Without it, any client can connect without providing credentials, bypassing authentication entirely.

The topic matching in ACLs uses the same wildcards as MQTT subscriptions: + for a single level and # for multiple levels. So, sensors/temperature/# allows access to any topic under sensors/temperature/.

The most surprising thing about MQTT ACLs is how easily they can be misconfigured to grant overly broad permissions, especially when using wildcards. A simple typo like sensors/# rw instead of sensors/temperature/# rw could expose all sensor data to an authenticated user. The broker doesn’t inherently know your intended security boundaries; it strictly enforces the rules you define.

A common mistake is forgetting to restart the broker after updating the mosquitto.conf, passwd, or acl files. Mosquitto needs to re-read these configurations to apply the changes.

The next step in securing your MQTT deployment is often encrypting the communication itself using TLS/SSL.

Want structured learning?

Take the full Mqtt course →