Skip to content

Emqx-ACL

Introduction

This document describes how EMQX delegates MQTT client authentication and per-topic ACL enforcement to an external HTTP service. You’ll see:

  1. What the HTTP service must return
  2. How EMQX calls and consumes that response
  3. A sequence diagram illustrating the interaction
  4. Dashboard configuration and client usage
  5. Troubleshooting tips

Data Flow Overview

Before diving into configuration details, here’s a high-level view of the runtime flow:

  1. An MQTT client attempts to CONNECT to EMQX with a username/password.
  2. EMQX issues an HTTP POST to your /emqx-auth endpoint, passing those credentials.
  3. Your service validates the user and returns a flat JSON including result and an acl array.
  4. EMQX reads result to accept or reject the connection, and—on success—applies each ACL entry as a topic filter.
  5. The client then issues SUBSCRIBE calls, which EMQX authorizes against the installed ACLs.

EMQX workflow

Backend Response Format

Your /emqx-auth endpoint must return HTTP 200 and a JSON object at its root:

{
  "result":       "allow",        // or "deny"
  "is_superuser": false,          // true for superadmin
  "acl": [
    {
      "permission": "allow",      // "allow" or "deny"
      "action":     "all",        // "publish"|"subscribe"|"all"
      "topic":      "dt/V01/GPRSV2/+/VCUA/#"
    },
    {
      "permission": "allow",
      "action":     "all",
      "topic":      "cmd/V01/GPRSV2/+/VCUA/#"
    }
  ]
}
  • result controls CONNECT approval.
  • acl entries drive EMQX’s per-session topic filters.

EMQX Dashboard Setup

  1. Disable any HTTP entries under Access Control ▶ Authorization.
  2. Create a new HTTP AuthN under Access Control ▶ Authentication:

    • Mechanism: Password‐Based
    • Backend: HTTP Server
    • Method: POST
    • URL:
      • Bridge: http://172.17.0.1:3010/emqx-auth
      • Host-networked: http://127.0.0.1:3010/emqx-auth
    • Headers: Content-Type: application/json
    • Body (raw JSON):

      {
        "username": "${username}",
        "password": "${password}"
      }
      
  3. Save and toggle the entry ON.


MQTT Client Usage

After a successful CONNECT (CONNACK), the client must explicitly subscribe to its allowed topics:

mosquitto_sub \
  -h <EMQX_HOST> \
  -u username@example.com \
  -P theirPassword \
  -t 'dt/V01/GPRSV2/+/VCUA/#'

Or in code:

client.subscribe('dt/V01/GPRSV2/+/VCUA/#', (err, granted) => {
  console.log(granted);
});

Troubleshooting

Symptom Cause & Fix
health_check_failed / Connection refused EMQX’s GET health-check is failing. Ensure your service listens on 0.0.0.0:3010 and add a GET /emqx-auth returning HTTP 200.
not_authorized Endpoint returned non-200 or result:"deny". Verify @HttpCode(200) on your POST handler and the JSON contains result:"allow".
No messages after SUBSCRIBE Make sure you subscribe to the exact topic filters returned in the acl array.

With this configuration, EMQX will enforce exactly the per-topic permissions your HTTP service provides, and clients will only see the topics you allow.