Authentication
EMQX Authentication: creating and disabling users with Password-Based Built-in Database, credential formats, JWT concepts, HTTP and LDAP concepts, and why authentication has to be set up the first time round.
Why this matters
In Chapter 5 you could already reach the broker with the WebSocket client, but you did it with an empty username and password. Until you create an authentication resource, EMQX lets a client connect straight through — convenient while you are only confirming that a single instance works, but it also means anyone who can reach your 1883 or 8083 can publish to, and read, your whole topic space. The Woow add-on documentation lists "set up MQTT authentication after your first login" as required, not optional.
You will create a real Password-Based mechanism with the Built-in Database backend, add the accounts you want Home Assistant and your devices to use, and learn how to disable an authentication resource and delete a user. It also makes the JWT, HTTP and LDAP mechanisms clear enough that you can recognize each one and know when it is worth reaching for, so that later you can build the authentication setup that fits what you need.
Core concepts
EMQX keeps authentication and authorization apart. Authentication answers "who are you?", confirmed by a username and password, a client ID, a JWT or a similar mechanism; Authorization answers "what publishes and subscribes may this identity make?", and that is Chapter 7. Expand Access Control in the Dashboard's left menu and you get Authentication, Authorization and Banned Clients (the blocklist).
Creating an authenticator usually takes four steps: choose a Mechanism, choose a Backend that stores or fetches the data, fill in the connection details, and create it. The mechanisms are Password-Based (username/password), JWT (a token) and MQTT 5.0's SCRAM (a stronger, mutual check). The backends are the EMQX built-in database, an external database (MySQL/PostgreSQL/MongoDB/Redis) and an HTTP Server; JWT needs no backend.
For a home add-on install the practical step is Password-Based plus Built-in Database: there is no second database to maintain, and adding a user directly in the Dashboard is enough to let Home Assistant and Zigbee2MQTT connect with a username and password.
Terms at a glance
| Term | Plain English | In one line |
|---|---|---|
| Authentication | identity check | Confirms who you are |
| Password-Based | password mechanism | Checks a username (or client ID) plus a password |
| Built-in Database | built-in store | EMQX keeps the users and passwords itself |
| Credential | credentials | The data that proves an identity |
| JWT | signed token | A token signed by an issuer that carries claims |
| HTTP Server | HTTP backend | Your own HTTP service returns the authentication verdict |
| LDAP | directory protocol | A company directory that checks a user and password |
Hands-on
Open the Authentication page
Log in to the Dashboard, go to Access Control → Authentication in the left menu, and click Create at the top right.
Create Password-Based plus the built-in database
On the Create page, pick Password-Based as the mechanism and Built-in Database as the backend (external databases and HTTP Server are left to the concept sections below). Set whether it matches on Username or ClientID and which password hash to use, to suit your case, then click Create.
Add a user
Find the authenticator you just created in the Authenticator List, click User Management, and add a username and password (for example
ha_broker/<your-password>). It is stored in the EMQX built-in database.Verify a working connection, then disable it
Go back to the WebSocket client from Chapter 5 and connect with the credentials you just created, to confirm that authentication really took effect (a wrong password is rejected). Then go to the Authenticator List, turn this authenticator's Enable switch off, and watch what "every client can connect" does — turn it straight back on when the experiment is over. Delete any user you no longer need from User Management.
Password-based built-in database
The built-in database is the backend with the least to look after: usernames and passwords live in EMQX's own database, and there is no separate data service to run. You can add and delete accounts by hand in User Management, or download the official template, fill it in, and use Import to create many at once.
Two details are worth watching while you set it up. The first is UserID Type: whether an account is identified by its username or by its client ID when it connects, which has to match the field your client actually sends. The second is the password hash (Password Hash) and salt position: once you change Password Hash or Salt Position, every credential already created stops working, and you have to create the users again.
As for disabling: the EMQX Enable switch turns a whole authenticator off at once. The official documentation is explicit that after that, "all clients can connect" — it does not shut everyone out, it takes this identity check away. If you disabled it for a maintenance job, turn it back on the moment you are done; if what you want is "they can connect but cannot necessarily do anything", that is authorization's job, in Chapter 7.
How JWT authentication works
JWT (JSON Web Token) is token-based authentication: the client puts a JWT token in the username or password field when it connects, and EMQX only has to check the signature and the claims in the Payload, which is why JWT needs no backend of its own. When you create it you choose Secret (verify with a shared key) or Public Key (verify with a public key), say whether the secret is Base64-encoded, and fill the claims you want checked into Payload.
If you use a JWKS Endpoint, EMQX periodically fetches a set of RSA/ECDSA public keys from the authorization server to verify the JWT, and you can set the refresh interval in seconds. JWT fits the case where an existing identity service already issues the tokens and you only want EMQX to accept them too.
For a plain self-hosted Home Assistant setup this is usually a bonus rather than a requirement: if you have no token-issuing service yet, a username and password is simpler.
HTTP and LDAP concepts
HTTP Server hands authentication to an external HTTP service you provide yourself: EMQX sends every connection request to that URL and allows or denies it according to the response. You configure the request method (POST or GET), the request URL (which must include the http or https scheme), the headers, and the data to be checked in the body (usually username and password). It can sit on top of an account system you already have, but you have to maintain it and make sure the response format is what EMQX expects.
LDAP (Lightweight Directory Access Protocol) is the protocol for checking a user against a directory server. The important part first: in EMQX, LDAP is only available in the paid Enterprise edition, so you will not find it in your Open Source 5.8.9 Dashboard. Conceptually it borrows an existing LDAP directory as the source of accounts, but for a home add-on install the built-in database or HTTP is the more practical place to start.
Troubleshooting
- Home Assistant stops connecting once you create an authenticator: usually the field you matched on, or the password, is wrong. Go back and check whether UserID Type reads the username or the client ID, the case of the account name you added and its password, and that the authenticator has not been left disabled. If your experiment turned Enable off, switching it back on restores things.
- After you turn Enable off, "every client can connect": that is by design. Disabling takes the whole authentication layer away; it does not tighten anything. To keep out clients you do not recognize you need authorization (Chapter 7) alongside a working authenticator — do not read a disabled authenticator as protection switched on.
- JWT keeps failing authentication: check whether you chose Secret or Public Key, whether the Base64 switch matches on both sides, and whether the Payload claims match the claims inside your JWT. Start with a token you can read on the issuing side and test it in the Dashboard by the shortest path.
- The external database or HTTP backend shows Disconnected: EMQX cannot reach that server, or the query failed. Check the server address, the port, the credentials and whether the response format is what EMQX expects; once the external side is fixed, go back to the Authenticator List and let it connect again.
FAQ
Aren't authentication and authorization the same thing?
No. Authentication confirms who you are; authorization decides what you may do on which topics. A username and password only completes the first half: with no authorization rules, a client that can log in is still free to publish and subscribe on every topic. Authorization is how you close that door to the minimum, and it is Chapter 7.
Which suits home use, the built-in database or MySQL/Redis?
For a home add-on install the built-in database is already enough, and it saves you maintaining a second database. An external database suits a large number of accounts, central management, or an identity system you already run. If you want a clean setup with one less thing to fail, choose the built-in one.
Where does JWT fit in a smart home?
If some token-issuing service already hands out all your tokens and you want EMQX to accept them too, JWT is the natural answer. For a self-hosted Home Assistant where you just want HA and Zigbee to connect, a username and password is usually more obvious; leave JWT until you really need central tokens.
Why can't I find LDAP?
Because the LDAP authentication backend is only in the EMQX Enterprise edition, and Open Source 5.8.9 does not have it. If you want to reuse an account directory you already run, your options under Open Source are the built-in database, or an HTTP Server that fronts your existing identity service.