Skip to content

Authorization

In EMQX, authorization refers to the permission control over the publish/subscribe operation of the MQTT clients. When a client performs a publish/subscribe operation, EMQX follows a specific procedure or uses the user-specified query statement to query the client's permission list from the configured data source. Based on the query result, EMQX allows or rejects the current operation.

A single permission data of a client has the following components:

PermissionClientOperationOperation Details
Allow/DenyClient ID/Username/IPPublish/Subscribe/Publish-SubscribeTopic/QoS/Retained Message

TIP

Starting from EMQX 5.1.1, the support for checking QoS and retained messages in operation details is introduced.

The permission list of the client needs to be stored in a specific data source (database, file) in advance. You can update the list during runtime by updating the corresponding data record.

A file-based authorizer is configured in EMQX by default and you can use the authorizer directly. The authorization is processed based on the predefined rules configured in the ACL file.

How Authorization Works

Authorization Chain

EMQX allows users to create an authorization chain by configuring multiple authorizers rather than one single authorizer to make authorization more flexible. EMQX follows the authorizers' position in the chain to perform the authorization in sequence. With the authorization chain configured, when EMQX fails to retrieve the matching authentication information from the first authorizer, it switches to the next authenticator to continue the process.

The process of the authorization check is as follows:

  1. If EMQX successfully retrieves the client's permission information, it matches the client's operation to the retrieved permission list.

    • If they match, EMQX allows or denies the operation based on permission setting.
    • If they do not match, EMQX switches to the next authorizer to continue the process.
  2. If EMQX fails to retrieve the client's permission information, it checks if there are any other authorizers configured.

    • If yes, EMQX switches to the next authorizer to continue the process.
    • If it is already the last authorizer, EMQX follows the setting of no_match to determine whether to allow or reject the client operation.

Note

To avoid problems with the authorization, you need to remember to disable or remove the ACL file authorizer when necessary because it has {allow, all} at the end by default to allow all authz requests.

For information on how to adjust the sequence of the authorizer in an authorization chain and how to check the running metrics, see Manage Authorizers.

Authorization Cache

To better handle the access pressure brought by a large number of publish/subscribe requests, EMQX introduces the authorization cache mechanism. You can enable cache through the Authorization page in EMQX Dashboard (Access Control->Authorization->Settings).

Authorization-settings_ee
  • Enable Cache: Setting for whether to enable cache for the authorization data.

  • Max number of cached items: The maximum number of cache for single client; the default setting is 32.

  • Time to live for the cached data: The living time of cached data, defaulting to 1 minute.

  • Excluded Topics: Provides a list of topics for which authorization cache will not be generated.

  • No Match Action: The action to take when all authorizers fail to retrieve authorization information; values to choose: allow (to operate), deny (to operate); default value: allow.

  • Deny Action: The action to take when denying the operating request from the current client; values to choose: ignore (operating request), disconnect (the connection of current client); default value: allow.

  • Clear Cache: Clear the cache of all current authorization results.

You can also configure the authorization data cache through the configuration file. For more information, see Configuration file.

TIP

If set properly, caching can greatly improve performance. So, it is recommended to timely adjust the setting based on your system performance.

Authorization Placeholders

EMQX authorizers allow using placeholders in their configuration. During the authorization step, these placeholders are replaced with actual client information to construct a query or HTTP request that matches the current client.

Placeholders in Data Queries

Placeholders are used to construct query statement. For example, in one EMQX MySQL authorizer, the default query SQL uses the placeholder ${username}:

sql
SELECT action, permission, topic FROM mqtt_acl where username = ${username}

When a client (name: emqx_u) initiates a connect request, the constructed query statement is like:

sql
SELECT action, permission, topic FROM mqtt_acl where username = 'emqx_u'

The following placeholders are supported in query statements:

  • ${username}: It is replaced with the username at runtime. The username comes from the Username field in the CONNECT packet. If peer_cert_as_username is enabled, it is overridden by the fields or the content of the certificate.
  • ${clientid}: It is replaced by the client ID at runtime. The client ID is normally explicitly specified by the client in the CONNECT packet. If use_username_as_clientid or peer_cert_as_clientid is enabled, this field is overridden by the username, fields in the certificate, or the content of the certificate.
  • ${peerhost}: It is replaced with the client's IP address at runtime. EMQX supports Proxy Protocol, that is, even if EMQX is deployed behind some TCP proxy or load balancer, users can still use this placeholder to get the real IP address.
  • ${peername}: It is replaced with the client's IP address and port in runtime, and the format is IP: PORT.
  • ${cert_common_name}: It is replaced by the Common Name of the client's TLS certificate at runtime. If the load balancer sends client certificate information to the TCP listener, ensure that Proxy Protocol v2 is in use.
  • ${cert_subject}: It is replaced by the subject of the client's TLS certificate at runtime. If the load balancer sends client certificate information to the TCP listener, ensure that Proxy Protocol v2 is in use.
  • ${client_attrs.NAME}: A client attribute. NAME will be replaced by an attribute name set based on predefined configurations at runtime. For details about the client attributes, see MQTT Client Attributes.

Topic Placeholders

EMQX also allows placeholders to be used in topics to support dynamic themes. The supported placeholders are as follows:

  • ${clientid}
  • ${username}
  • ${client_attrs.NAME}: A client attribute. NAME is to be replaced by an attribute name extraction rule configured in mqtt.client_attrs_init.

Placeholders can be used as topic segments, like a/b/${username}/c/d.

To avoid placeholder interpolation, starting from EMQX 5.4, you can escape $ as ${$}. For example, t/${$}{username} is treated as t/${username} literally without interpolation, rather than the topic name with username replaced.

TIP

If you use the eq syntax in query statements, note that the topic following eq does not support placeholder interpolation. This behavior can change in future versions.

The eq syntax is to match exactly a topic filter, but not any topic that matches the filter. For example, eq t/# matches t/#, not t/1 or t/2.

Authorization Check Priority

Besides the cache and authorization checker, the authorization result may also be affected by the Super User Role and Permission set during the authentication phase.

For super users, all their operations will be skipped from the authorization check. If the Access Control List (ACL) list is set, EMQX will first follow the client's permission data before running the authorization checker. The priority is as follows:

bash
Super user > permission data > authorization check

Manage Authorizers

You can view and manage authorizers in the Access Control->Authorization page in the Dashboard.

Manage Authorizers

As mentioned in Authorization chain, authorizers are executed according to the configured sequence. You can select Up, Down, Move to top, and Move to bottom from the More dropdown list to move the authorizer. You can also adjust the authorizer positions in the authorization.sources configuration item.

Check Authorizer Status

You can check the connection status in the Status column:

StatusMeaningTroubleshooting
ConnectedAll nodes are connected to the data source successfully.-
DisconnectedParts of or all nodes are not connected to the data source (database, file).Check if the data source is available;
Restart the authorizer manually (Disable and Enable again) after troubleshooting.
ConnectingParts of or all nodes are reconnecting to the data source (database, file).Check if the data source is available;
Restart the authorizer manually (Disable and Enable again) after troubleshooting.

Running Metrics

You can view the statistic metrics of each authorizer on the Overview page of the authorizer. The following metrics are listed:

  • Allow: Number of authorizations passed.
  • Deny: Number of authorizations failed.
  • No match: Number of times client authorization data is not found.
  • Ignored: Number of ignored authorization queries because the authorization is not applicable or encounters an error, resulting in an undecidable outcome.
  • Rate(tps): Execution rates of authorizations.

You can also check the authorization status and execution status on each node through Node Status.

If you want to view the overall running metrics of authorization, see Metrics - Authentication & Authorization.

Integrate with Data Storage Objects

The EMQX authorization mechanism supports integration with various data storage objects, including built-in databases, files, MySQL, PostgreSQL, MongoDB, and Redis. You can manage permission data through REST API or EMQX Dashboard. .

In addition, EMQX can also connect to HTTP services developed by our users to meet different authorization requirements.

According to the backend data storage used, there are different types of EMQX authorizers as listed below. Each authorizer has its own configuration options. You can click the corresponding links in the table for more details.

DatabaseDescription
ACL FileAuthorization with static rules configured in a file
Built-in databaseAuthorization with built-in database as rules storage
MySQLAuthorization with MySQL as rules storage
PostgreSQLAuthorization with PostgreSQL as rules storage
MongoDBAuthorization with MongoDB as rules storage
RedisAuthorization with Redis as rules storage
LDAPAuthorization with LDAP directory as rules storage
HTTPAuthorization with external HTTP service

Below is an example of how to configure an EMQX MySQL authorizer.

Example:

bash
{

    type = mysql
    database = "mqtt"
    username = "root"
    password = "public"

    query = "SELECT permission, action, topic FROM mqtt_acl WHERE username = ${username}"
    server = "10.12.43.12:3306"
}

Configure Authorization Mechanisms

EMQX provides 3 ways to configure authorization, namely: Dashboard, Configuration file, and HTTP API.

Configure with Dashboard

EMQX Dashboard is an intuitive way to configure EMQX authorizer, where you can configure relevant parameters, check their working status, and adjust their position in the authorization chain.

authentication-with-dashboard

Configure with Configuration File

You can also configure authorization in the authorization fields in the configuration file emqx.conf. The general config structure is the following:

bash
authorization {
  sources = [
    { ...   },
    { ...   }
  ]
  no_match = allow
  deny_action = ignore
  cache {
    max_size = 32
    excludes = ["t/1", "t/2"]
    ttl = 1m
  }
}

Where,

  • sources (optional): An ordered array; each array element defines the data source of the corresponding authorizer. For detailed configurations, see the corresponding configuration file.

  • no_match: Determines the default action for a publish/subscribe request if none of the configured authorizers find any authorization rules; optional value: allow or deny; default: allow. The setting also triggers the enabling of black/white list.

  • deny_action: Determines the next step if a publish/subscribe operation is rejected; optional value: ignore or disconnect; default: ignore. If set to ignore, the operation is silently ignored; if set to disconnect, the client connection is dropped.

  • cache: Defines the caching settings, including:

  • cache.enable: Specifies whether to enable caching, default: true. If the authorization is solely based on the JWT packets, it is recommended to configure this field false.

  • cache.max_size: Specifies the maximum number of elements in the cache; default: 32. Older records will be removed from the cache if the specified number exceeds.

  • cache.excludes: A list of excluded topics, for which authorization cache will not be generated; default value: [].

  • cache.ttl: Specifies the effective time of cached values, default: 1m (one minute).

HTTP API

There are several API endpoints for managing authorization:

  • /api/v5/authorization/settings: for general parameters, no_match, deny_action, and cache;
  • /api/v5/authorization/sources: for managing and arranging authorizers;
  • /api/v5/authorization/cache: for cleaning authorization cache;
  • /api/v5/authorization/sources/built_in_database: for managing authorization rules of built_in_database authorizer.

For detailed operation steps, see HTTP API.