Join our Newsletter — 33% off our NHI Course
Home› Guides› MQTT Security Guide: Broker Authentication, ACLs, TLS and…
Guide OT & IoT Security

MQTT Security Guide: Broker Authentication, ACLs, TLS and Client Identity

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 14 min read
On this page

An MQTT broker that accepts anonymous connections on port 1883 lets anyone on the network read every sensor reading and publish commands to every device subscribed to a topic. MQTT is the default messaging protocol for IoT and increasingly for industrial telemetry, from building sensors to Sparkplug-based SCADA integration. The protocol itself leaves security to the implementation: the specification says brokers should offer authentication, authorisation and secure communication, and strongly advises using them for critical infrastructure and personal data, but does not force any of it. This guide covers broker authentication, topic-level authorisation, TLS, client credential management, detection and the failure patterns seen in real deployments. It is for engineers who run brokers (Mosquitto, EMQX, HiveMQ and similar) or use cloud IoT services, and for security teams assessing them.

Key takeaways

  • Anonymous access is the first thing to check. Mosquitto 2.0 changed the default so anonymous clients are refused unless explicitly allowed; brokers configured on 1.6.x or earlier, or copied from old tutorials, often still allow them.
  • Authentication without authorisation is not enough. A broker that checks passwords but grants every client read and write on # lets one stolen device credential reach the whole fleet. Scope every client to its own topics.
  • TLS on 8883 is the baseline, client certificates are the target. Passwords over plaintext 1883 can be sniffed; per-device X.509 certificates remove shared secrets and bind identity to the client ID.
  • Every device, gateway and backend service is a non-human identity. Shared fleet passwords and backend "superuser" accounts are the MQTT equivalent of a shared admin password.
  • Check what "deny" actually does. Under MQTT 3.1.1 a broker may silently drop an unauthorised publish, and some brokers ignore denials by default, so failures do not show up unless you log and monitor them.

How MQTT works and where the risks sit

MQTT is a publish and subscribe protocol: clients connect to a broker, publish messages to topics (for example site1/line3/press/temperature) and subscribe to topic filters that may use wildcards (+ for one level, # for all remaining levels). The current versions are MQTT 3.1.1 (OASIS, October 2014, also published as ISO/IEC 20922:2016) and MQTT 5.0 (OASIS Standard, 7 March 2019). The IANA ports are 1883 for plain TCP and 8883 for MQTT over TLS.

MQTT featureWhat it doesSecurity consequence
Wildcard subscriptions (#, +)Subscribe to many topics at onceA client allowed to subscribe to # receives every message on the broker, including commands and credentials sent in payloads
Retained messagesBroker keeps the last message per topic for new subscribersStale or malicious retained commands are delivered to every device that reconnects
Will messagesBroker publishes on the client's behalf if it disconnects uncleanlyA client that may set any will topic can publish to topics it is not otherwise allowed to
Client IDIdentifies the sessionA second connection with the same client ID disconnects the first, so a guessed ID can knock a device offline (session takeover)
$SYS topicsBroker statistics and versionReveals broker software, version and client counts to anyone allowed to subscribe
BridgesBroker to broker forwardingBridge credentials often have wide topic rights and sit in configuration files
MQTT over WebSocketsBrowser and firewall-friendly transportA second listener with its own authentication settings, often forgotten in reviews

The threats map to a small set of ATT&CK for ICS techniques: Internet Accessible Device (T0883) for brokers reachable from the internet, Default Credentials (T1694.001) for factory or tutorial passwords, Network Sniffing (T0842) and Adversary-in-the-Middle (T0830) on plaintext links, and Unauthorized Message: Command Message (T1692.001) when an attacker publishes to a command topic.

Broker authentication options

The MQTT CONNECT packet carries a client ID and optional username and password. MQTT 5.0 adds enhanced authentication: an Authentication Method property (0x15), Authentication Data (0x16) and an AUTH packet, so a broker can run challenge and response schemes and ask a client to re-authenticate (reason code 0x19) during a long-lived session.

MethodHow it worksStrengthsWeaknessesUse when
AnonymousNo credentialsNoneAnyone who can reach the port is a clientNever on shared networks; only local loopback test brokers
Username and passwordChecked against a password file, database or pluginUniversally supportedShared secrets, often reused across a fleet; exposed without TLSConstrained devices without certificate support, always over TLS, one credential per device
TLS client certificateBroker validates the certificate against a CA; CN or subject becomes the usernameNo password to steal or reuse; revocable per deviceNeeds enrolment, renewal and revocation processesProduction fleets and all backend services
TLS-PSKPre-shared key per identityLighter than certificatesKeys are shared secrets held on both sidesVery constrained devices that cannot do certificates
Token (JWT, SAS)Signed token in the password field or via enhanced authShort lived, can carry claimsSigning key becomes a high-value secret; expiry must be enforcedCloud IoT services and brokers integrated with an identity provider
External plugin or HTTPBroker calls an auth serviceCentral policy, integrates with existing identity storesAuth service availability becomes broker availabilityLarge deployments with an existing IAM or device registry

Product specifics worth knowing:

  • Mosquitto: allow_anonymous defaults to false in 2.x unless no listener is defined, in which case only local connections are accepted. Versions 1.6.x and earlier defaulted to true. With per_listener_settings false (the default) authentication settings are global, so a WebSockets listener added later inherits them; with it set to true each listener needs its own settings. require_certificate true plus use_identity_as_username true makes the certificate CN the username.
  • AWS IoT Core: the device certificate identifies the thing, and thing policy variables such as iot:Connection.Thing.ThingName and iot:Connection.Thing.IsAttached let one policy restrict each device to its own client ID and topics, provided the client ID equals the thing name.
  • Azure IoT Hub: MQTT 3.1.1 on 8883 or over WebSockets on 443, TLS 1.2 required and plain 1883 not supported. The client ID is the device ID and the password is a SAS token; Microsoft's documentation recommends X.509 certificates for production. IoT Hub is not a general-purpose broker: topics are fixed per device.

MQTT 5.0 also gives the broker defensive options: close connections that do not send CONNECT promptly, and on public networks close a failed connection without sending a CONNACK so an attacker cannot confirm a broker is there or iterate passwords quickly.

Topic authorisation and ACL design

Authorisation decides what an authenticated client may publish, subscribe to and receive. Design topics so that ACLs can be written with substitution variables rather than one rule per device.

  • Put identity in the topic: a structure like tenant/site/<clientid>/telemetry and tenant/site/<clientid>/cmd lets one rule scope every device. Mosquitto ACL files support pattern lines with %c (client ID) and %u (username); EMQX uses ${clientid} and ${username}.
  • Separate publish and subscribe: devices publish telemetry and subscribe only to their own command topic; backend services subscribe to telemetry and publish commands. No device needs #.
  • Deny by default: check what happens when no rule matches. EMQX's no_match default changed to deny in EMQX 6.0, and its sample ACL file ends with an allow-all rule that must be removed. The Mosquitto Dynamic Security plugin defaults to deny for publish and subscribe but allow for receiving messages on topics already subscribed.
  • Restrict $SYS and will topics: limit $SYS to monitoring accounts and make sure will messages are subject to the same publish ACL as normal publishes.
  • Revoke cleanly: in EMQX, changing a rule does not revoke existing subscriptions; delete the client's session as well. In the Mosquitto Dynamic Security plugin, disabling a client disconnects its sessions.
  • Industrial namespaces: the Eclipse Sparkplug 3.0.0 specification (November 2022) uses topics of the form spBv1.0/group_id/message_type/edge_node_id/device_id and suggests ACLs so each edge node can publish only on topics for its own group and edge node ID, which makes spoofing harder. Only the Primary Host Application should be allowed to publish command (NCMD, DCMD) messages.
Client typePublishSubscribeNotes
Field device or sensor…/%c/telemetry, …/%c/status…/%c/cmdOne credential per device; no wildcards
Edge gatewayTopics for devices behind itCommands for those devicesScope to the gateway's site or group
Ingestion serviceNone or acknowledgements…/+/telemetryRead-only on telemetry; separate from command service
Command service…/+/cmdStatus topicsHighest-risk credential: protect like a privileged account
MonitoringNone$SYS/#No access to business topics
BridgeOnly forwarded topicsOnly forwarded topicsExplicit topic list, never # in both directions

TLS configuration

  • Listeners: bind 1883 to loopback only (or remove it) and expose 8883. Audit every listener, including WebSockets and any management or HTTP API listener.
  • Versions: set a minimum of TLS 1.2 (Mosquitto tls_version tlsv1.2) and prefer 1.3 where clients support it. Bridges need TLS too: in Mosquitto at least one of bridge_cafile, bridge_capath or bridge_tls_use_os_certs must be set.
  • Server authentication on the client: devices must validate the broker certificate and hostname. Disabling verification to "make it work" (for example an insecure flag in the client library) turns TLS into encryption to an unknown party.
  • Client certificates: issue from a dedicated device CA, one certificate per device, with the client ID in the CN or SAN, and a defined renewal path. See the IoT and Device Certificate Provisioning Guide and the mTLS Guide.
  • Revocation: confirm the broker checks a CRL or equivalent; otherwise removing a stolen device means rotating the CA.

Where identity fits: client credentials as NHIs

Every MQTT client is a non-human identity, and fleets create them by the thousand. The common anti-pattern is one username and password baked into firmware for every device of a model, plus a backend service account with read and write on # stored in a configuration file or container image.

  • Inventory: list every broker identity with owner, type (device, gateway, service, bridge), authentication method, topic rights and last connection time. Remove identities that have not connected in 90 days.
  • Unique per device: provision credentials or certificates individually at manufacture or first boot so one extracted credential compromises one device. See the Identity for IoT Fleets Guide.
  • Backend secrets in a vault: service and bridge credentials belong in a secrets manager with rotation, not in mosquitto.conf, environment files or source control. See the Secrets Management Guide.
  • Bootstrap files: Mosquitto's mosquitto_ctrl dynsec init writes generated initial passwords in plain text to a file that should be deleted once used.
  • Management APIs: admin consoles, the Dynamic Security control topic $CONTROL/dynamic-security/v1 and broker REST APIs can create clients and change ACLs. Restrict them to named administrators.

Rolling out MQTT security on an existing broker

  1. Discover: scan your own address space for 1883 and 8883 and list every broker, listener and version. Treat any internet-reachable broker as an incident until proven otherwise. See the Attack Surface Management Guide.
  2. Log before you enforce: enable connection and subscribe logging (Mosquitto log_type includes subscribe) and collect a week of client IDs, usernames and topic use.
  3. Write ACLs from observed behaviour: draft per-role ACLs from the logs, deploy them on a staging broker and replay traffic.
  4. Turn on TLS alongside plaintext: add an 8883 listener, migrate clients in rings (lab devices, one site, then the fleet), then close 1883.
  5. Disable anonymous access and enforce ACLs: in a maintenance window, with the previous configuration file kept so the broker can be reverted in minutes.
  6. Move to per-device certificates: as devices are replaced or reflashed, switching from shared passwords to certificates.
  7. Set limits: connection limits, maximum packet size (Mosquitto max_packet_size defaults to 2,000,000 bytes from 2.1) and connection rate limits to reduce denial-of-service risk.

Self-hosted vs cloud IoT service: a cloud service such as AWS IoT Core or Azure IoT Hub enforces TLS and per-device identity by design but restricts topic structures; a self-hosted broker gives full MQTT 5 features and on-premises operation (common in OT) but makes every control your responsibility. Small deployments with tens of devices can manage a password file and static ACL; fleets in the thousands need a device registry, certificate automation and an authorisation plugin or database.

Detection and measurement

  • Authentication failures: CONNACK reason codes 0x86 (bad user name or password), 0x87 (not authorized) and 0x8C (bad authentication method) in broker logs; alert on bursts from one source.
  • Session takeovers: repeated disconnects with reason 0x8E (session taken over) for the same client ID suggest a cloned credential or a duplicate device.
  • Wildcard subscriptions: any subscription to # or $SYS/# by an identity not on the approved list.
  • Publish to command topics: commands from identities other than the command service.
  • New identities: first-seen client IDs and usernames, especially outside provisioning windows.

Metrics: brokers reachable from the internet (target zero); listeners without TLS (target zero outside loopback); percentage of clients using per-device certificates; identities with wildcard rights; identities unused for 90 days; denied operations per day by identity, with each persistent one investigated. See the OT Network Security Monitoring Guide.

Framework mapping

MQTT controlNIST SP 800-53 Rev. 5NIST CSF 2.0Threat (ATT&CK for ICS v20)
Per-device authentication, no anonymous accessIA-3, IA-5PR.AA-03T1694.001 Default Credentials
Topic ACLs, deny by defaultAC-3, AC-6PR.AA-05T1692.001 Command Message
TLS on all listeners and bridgesSC-8PR.DS-02T0842 Network Sniffing, T0830
Remove unused listeners, restrict $SYSCM-7, CM-6PR.PS-01T0883 Internet Accessible Device
Connection and packet limitsSC-5PR.PS-01Denial of service
Broker and auth loggingAU-12, SI-4DE.CM-01Detection of the above
Broker and identity inventoryCM-8ID.AM-01Unmanaged brokers

Common failure patterns

  • Tutorial configuration in production: a broker built from an old guide with allow_anonymous true on 1883, then exposed when a firewall rule is opened for a cloud dashboard.
  • One fleet password: the same username and password in every device's firmware; extracting it from one device unlocks the broker for all of them.
  • Allow-all ACL left in place: authentication is configured, but the default authoriser or sample ACL still allows everything, so every client can subscribe to #.
  • Second listener, no security: a WebSockets listener added for a web dashboard with different or no authentication settings.
  • Disabled certificate verification: device code that skips broker certificate validation, accepting any server on the path.
  • Silent denials: brokers configured to ignore unauthorised publishes without logging, so a misbehaving or compromised client is never noticed.

No live NHI Mgmt Group breach page currently covers an MQTT broker exposure, so none is linked here.

Practitioner checklist

  • Scan for brokers on 1883 and 8883 across your ranges and close any that are reachable from the internet.
  • Confirm anonymous access is disabled on every listener, including WebSockets and bridges.
  • Enforce TLS 1.2 or later on every listener and bridge, and verify that clients validate the broker certificate.
  • Issue one credential or certificate per device and per service; retire shared fleet passwords.
  • Write deny-by-default ACLs using client ID or username substitution; remove allow-all defaults.
  • Restrict command topics to the command service and $SYS to monitoring accounts.
  • Move backend and bridge credentials into a secrets manager with rotation.
  • Log authentication failures, session takeovers and wildcard subscriptions, and alert on them.
  • Set connection limits, packet size limits and rate limits.
  • Review broker identities quarterly and remove those unused for 90 days.

Standards and references

Related NHI Mgmt Group resources: IoT Security Guide · Industrial IoT (IIoT) Security Guide · Device and IoT Identity Guide · Industrial Protocol Security Guide · Kafka Security Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org