Safeguard
Security Guides•

How do you give each MQTT device access to just its own topics?

Use pattern ACLs that put the username or client ID into the topic, so one rule covers every device. Includes examples, wildcard traps and test steps.

Safeguard Security Team
5 min read

Use pattern based access control lists that insert the client's username or client ID into the topic path. One line such as a write rule on sensor/%u/data then lets each device publish to its own branch and nowhere else. Combine it with required logins and a default of no access.

The problem with shared access

A broker with many devices and one set of rules tends to end up with all devices able to read and write all topics. If one device is stolen or compromised, the attacker can read every other device's data and publish false commands to them. Per device topic rules limit that damage to one device.

How pattern ACLs work in Mosquitto

The Mosquitto configuration manual describes an access control file. If an ACL file is defined, the topics it lists are the ones accessible. Each line grants an access type of read, write, readwrite or deny for a topic, and topics can use the usual + and # wildcards. Rules after a user line apply to that username. Note that the username is the one used in the password file, not the client ID.

Pattern lines use the same format but substitute values. %u matches the client's username and %c matches its client ID. The substitution must be the sole text for that level of the topic hierarchy, and pattern rules apply to all users. The manual's example is:

pattern write sensor/%u/data

With that rule, a device logged in as thermostat7 can write to sensor/thermostat7/data and to no other device's branch. The manual also notes that it is generally not possible to grant write access to the $SYS topic tree, with a stated exception for bridge connection state.

The manual suggests using the dedicated ACL file plugin instead of the older option, because plugins give more control over which listeners they apply to. It also points to the dynamic security plugin for administering clients and roles remotely.

Username or client ID

SubstituteProsCons
UsernameTied to a credential checked at loginNeeds one credential per device
Client IDEasy to set on devicesChosen by the client unless otherwise enforced

The safer pattern is to bind topics to the username, since the broker has verified it. A client ID is a label the client picks, so an attacker with any valid login might choose someone else's ID. Use client ID patterns when another control, such as certificates with an identity check, ties it to the credential.

The wildcard trap

The manual describes a plugin option that denies ACL checks when the username or client ID contains a plus or hash character. Its purpose is to prevent a malicious user from using wildcard characters in a name to match topics they should not. If you use a plugin that substitutes names into topics, check whether it has an equivalent option and enable it, and reject names containing wildcards at registration time.

Steps

  1. Require authentication on every listener first.
  2. Give each device its own username and credential. Avoid shared accounts.
  3. Design a topic tree with the device identity as one level, for example devices/ID/telemetry and devices/ID/commands.
  4. Add pattern rules: write to the device's own telemetry branch, read from its own command branch.
  5. Add explicit rules for any shared topics, with read access where possible.
  6. Use deny rules for sensitive branches.
  7. Test with two device accounts. Device A must fail to subscribe to or publish on device B's topics, including through wildcard subscriptions.
  8. Reload rules and re test, since the manual notes existing subscriptions are affected after a reload.

What to log

Log failed publishes and subscribes. A device that repeatedly tries topics outside its branch is either misconfigured or compromised, and both are worth knowing about.

Try it yourself

Click through it at your own pace, or open it full screen.

Look at how API scan findings describe access problems, then think about what a two device test would show.

Quick check

Which is safer to match in an ACL, username or client ID?

Username, because the broker verified it at login. A client ID is chosen by the client unless another control enforces it.

Can a device use wildcards to read other devices' topics?

Yes, if the rules allow it. Test with a wildcard subscription from a second account, and deny names containing wildcard characters.

Safeguard scans your dependencies and SBOMs for known vulnerabilities, including MQTT libraries in your devices and services. A free scan is at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.