HiveMQ Edge REST API

HiveMQ Edge can be optionally configured to expose an administrative API and an administrative user interface. The admin user interface uses the API to fulfill all of its features.

HiveMQ Edge REST API Configuration

HiveMQ Edge is designed to use sensible default values. When you run the default HiveMQ Edge configuration, the HiveMQ Edge API web server and user interface start up with a listener bound to port 8080.

HiveMQ Edge default API configuration
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <admin-api>
        <enabled>true</enabled>
    </admin-api>
</hivemq>
Example configuration to change the HiveMQ Edge API listener address and port
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <admin-api>
        <listeners>
            <http-listener>
                <port>80</port>
                <bind-address>0.0.0.0</bind-address>
            </http-listener>
        </listeners>
    </admin-api>
</hivemq>

HiveMQ Edge API and User Interface Authentication

The HiveMQ Edge API is secured using a Bearer Token scheme. This authentication method involves presenting an HTTP header with the following format in all requests for secured resources:

Authorization : "Bearer <JWT>"

The JWT (JSON Web Token) is generated by calling the API endpoint:

POST  /api/v1/auth/authenticate

Username and password credentials that match an entity in your configuration XML should be posted to the endpoint. If the credentials are valid, the webservice returns a JWT that can be used to secure future requests. To add, remove, or modify the users who are allowed access to the API and user interface, edit the users element in your config.xml file.

Changing API Users
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <admin-api>
        <users>
            <user>
                <username>admin</username>
                <password>hivemq</password>
                <roles>
                    <role>admin</role>
                </roles>
            </user>
        </users>
    </admin-api>
</hivemq>

Access to the HiveMQ Edge Admin UI and Admin REST API is controlled by role-based access control (RBAC).

HiveMQ Edge provides three roles:

  • user

  • super

  • admin

Each user is assigned one or more roles. When a user belongs to multiple roles, the highest-privilege role determines the effective access level.

Table 1. Roles and permissions
Permission No Role user super admin

Front page / login

Read Edge configuration (adapters, bridges, mappings, etc.)

Edit Edge configuration (create/update/delete adapters, bridges, mappings, etc.)

Read Data Hub configuration (policies, schemas, scripts)

-

Edit Data Hub configuration (create/update/delete policies, schemas, scripts)

Start, stop, and restart protocol adapters

Read access to REST API (GET)

-

Write access to REST API (POST, PUT)

-

-

-

Authentication REST API (get, refresh, validate Auth token)

Liveliness and readiness REST API

Role-based access control is fully enforced in the HiveMQ Edge backend. However, the frontend UI does not yet completely reflect these restrictions. Currently, users with read-only roles (user, super) can interact with edit controls (for example, forms to create tags or mappings), but the backend rejects the write requests. However when the frontend tries to store this in the backend, the backend will fail this write request. No data is modified without the correct permissions. A view-only mode will be implemented in a future release to ensure frontend permissions accurately mirror backend access control.

By default, the JWTs the authenticate endpoint issues expire after 30 minutes. You can change the expiry, and other parameters of the generated token in the API configuration XML file.

Example cURL command to request a JWT from localhost:8080
curl 'http://localhost:8080/api/v1/auth/authenticate' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  --data-raw '{"password":"hivemq","userName":"admin"}' \
  | jq .token -r
Example configuration to change the generated JWT
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <admin-api>
        <generated-tokens>
            <keySize>2048</keySize>
            <issuer>HiveMQ-Edge</issuer>
            <audience>HiveMQ-Edge-Api</audience>
            <expiryTimeMinutes>30</expiryTimeMinutes>
            <tokenEarlyEpochThresholdMinutes>2</tokenEarlyEpochThresholdMinutes>
        </generated-tokens>
    </admin-api>
</hivemq>
Example configuration to add secure TLS to API
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <admin-api>
        <listeners>
            <https-listener>
                <port>443</port>
                <bind-address>127.0.0.1</bind-address>
                <tls>
                    <protocols>
                        <protocol>TLSv1.2</protocol>
                    </protocols>
                    <cipher-suites>
                        <cipher-suite>TLS_RSA_WITH_AES_128_CBC_SHA</cipher-suite>
                        <cipher-suite>TLS_RSA_WITH_AES_256_CBC_SHA256</cipher-suite>
                        <cipher-suite>SSL_RSA_WITH_3DES_EDE_CBC_SHA</cipher-suite>
                    </cipher-suites>
                </tls>
            </https-listener>
        </listeners>
    </admin-api>
</hivemq>
Table 2. Available TLS parameters
Name Default Mandatory Description

protocols

All enabled

no

The enabled protocols. Possible entries are TLSv1.2, TLSv1.1, and TLSv1.

cipher-suites

All cipher suites enabled

no

The enabled cipher suites. If desired, define specific cipher suites to limit the number of suites that are enabled. NOTE: The available cipher suits are dependent on the SSL implementation that is used and not necessarily the same for all machines.

keystore.path

none

yes

The path to the key store where your certificate and private key are located.

keystore.password

none

yes

The password to open the key store.

keystore.private-key-password

none

no

The password for the private key (if applicable).

LDAP Authentication

HiveMQ Edge supports LDAP (Lightweight Directory Access Protocol) authentication for the Admin API, enabling centralized user management and authentication against your organization’s LDAP directory server.

Overview

LDAP authentication allows you to:

  • Authenticate Admin API users against an existing LDAP directory (Active Directory, OpenLDAP, etc.)

  • Centralize user management without maintaining separate credentials

  • Support enterprise identity management systems

  • Enable secure authentication with TLS/SSL encryption

All authenticated users are assigned the ADMIN role with full access to the Admin API.

Connection Security

HiveMQ Edge supports three TLS modes for LDAP connections:

LDAP over TLS/SSL establishes an encrypted connection from the start. This is the most secure option.

  • Default Port: 636

  • TLS Mode: LDAPS

  • Use Case: Production deployments with strict security requirements

START_TLS

Upgrades a plain LDAP connection to TLS using the StartTLS extended operation.

  • Default Port: 389

  • TLS Mode: START_TLS

  • Use Case: Production environments where LDAPS is not available

Unencrypted LDAP connection. Credentials and data are transmitted in clear text.

  • Default Port: 389

  • TLS Mode: NONE

  • Use Case: Development and testing only

For production use, we strongly recommend using LDAPS or START_TLS to protect credentials and data in transit.

LDAP Authentication Modes

HiveMQ Edge supports two methods for resolving user Distinguished Names (DNs):

Direct Binding (Default)

The user DN is constructed by combining the username with a base DN template. This is the fastest method and works well for flat LDAP structures.

Example for username alice with configuration:
<uid-attribute>uid</uid-attribute>
<rdns>ou=people</rdns>
<base-dn>dc=example,dc=org</base-dn>

the constructed DN is: uid=alice,ou=people,dc=example,dc=org

Use this mode when:

  • Users are stored in a single organizational unit

  • The LDAP structure is flat and predictable

  • Performance is critical (Direct binding adds no search overhead)

Directory Descent

Performs an LDAP search to locate the user’s DN. This method supports complex hierarchical LDAP structures where users may be in nested organizational units.

Use this mode when:

  • Users are distributed across multiple organizational units

  • The LDAP structure is hierarchical (e.g., separate OUs for departments)

  • User locations in the directory tree are not predictable

Directory Descent requires a service account with search permissions on the LDAP directory.

LDAP Authorization (Role Assignment)

After a user is authenticated, HiveMQ Edge can execute LDAP queries to assign roles to that user. Each query checks group membership in the LDAP directory. If a query returns at least one result, the user is assigned the corresponding role. assign roles to the user. This happens after the authentication has resolved the user DN as described above and the user has been authenticated with their password.

The queries have the form (&(entryDN={userDn})(memberOf=CN=EdgeAdmins,OU=Groups,DC=Example,DC=Org)). Edge executes the queries after the user has been authenticated and assigns the corresponding role to the user for any query that returns at least one result.

Configuration

LDAP authentication is configured in the Admin API section of the HiveMQ Edge configuration file (config.xml).

Basic Configuration Example

<admin-api>
    <enabled>true</enabled>
    <listeners>
        <http-listener>
            <port>8080</port>
            <bind-address>0.0.0.0</bind-address>
        </http-listener>
    </listeners>
    <ldap>
        <servers>
            <ldap-server>
                <host>ldap.example.com</host>
                <port>636</port>
            </ldap-server>
        </servers>
        <tls-mode>LDAPS</tls-mode>
        <simple-bind>
            <rdns>cn=admin,ou=people</rdns>
            <userPassword>secret</userPassword>
        </simple-bind>
        <uid-attribute>uid</uid-attribute>
        <rdns>ou=people</rdns>
        <base-dn>dc=example,dc=org</base-dn>
    </ldap>
</admin-api>

Configuration Example with User Roles

Role assignment is configured using <user-roles>. Each <user-role> entry maps a role name to an LDAP query. HiveMQ Edge executes each query after authentication. If a query returns at least one result, the user is assigned the corresponding role.

<admin-api>
    <enabled>true</enabled>
    <listeners>
        <http-listener>
            <port>8080</port>
            <bind-address>0.0.0.0</bind-address>
        </http-listener>
    </listeners>
    <ldap>
        <servers>
            <ldap-server>
                <host>ldap.example.com</host>
                <port>636</port>
            </ldap-server>
        </servers>
        <tls-mode>LDAPS</tls-mode>
        <simple-bind>
            <rdns>cn=admin,ou=people</rdns>
            <userPassword>secret</userPassword>
        </simple-bind>
        <uid-attribute>uid</uid-attribute>
        <rdns>ou=people</rdns>
        <base-dn>dc=example,dc=org</base-dn>
        <user-roles>
            <user-role>
                <role>admin</role>
                <query>(&amp;(entryDN={userDn})(memberOf=CN=EdgeAdmins,ou=groups,dc=example,dc=org))</query>
            </user-role>
            <user-role>
                <role>user</role>
                <query>(&amp;(entryDN={userDn})(memberOf=CN=EdgeUsers,ou=groups,dc=example,dc=org))</query>
            </user-role>
        </user-roles>
    </ldap>
</admin-api>

The queries in this example search the user entry for a memberOf attribute matching the target group. This requires the memberOf overlay, which is enabled by default in OpenLDAP and most other LDAP servers.

The ampersand &, which denotes the logical AND in LDAP query syntax, must be escaped as &amp; in the XML configuration file.
If your LDAP server does not support the memberOf overlay (for example, some lightweight LDAP implementations), search the group entry for a member or uniqueMember attribute instead: (&(objectClass=groupOfNames)(cn=administrators(member={userDn})). Again, remember to escape & as &amp; in XML.

Configuration with TLS Truststore

When using self-signed certificates or custom Certificate Authorities:

<ldap>
    <servers>
        <ldap-server>
            <host>ldap.example.com</host>
            <port>636</port>
        </ldap-server>
    </servers>
    <tls-mode>LDAPS</tls-mode>
    <tls>
        <truststore-path>/opt/hivemq/conf/truststore.jks</truststore-path>
        <truststore-password>changeit</truststore-password>
        <truststore-type>JKS</truststore-type>
    </tls>
    <simple-bind>
        <rdns>cn=service-account</rdns>
        <userPassword>secret</userPassword>
    </simple-bind>
ERWIN
    <uid-attribute>sAMAccountName</uid-attribute>
    <rdns>dc=corp,dc=example,dc=com</rdns>
</ldap>

Configuration with Directory Descent

For hierarchical LDAP structures with nested organizational units:

<ldap>
    <servers>
        <ldap-server>
            <host>ldap.example.com</host>
            <port>389</port>
        </ldap-server>
    </servers>
    <tls-mode>START_TLS</tls-mode>
    <simple-bind>
        <rdns>cn=admin,ou=people</rdns>
        <userPassword>secret</userPassword>
    </simple-bind>
    <uid-attribute>uid</uid-attribute>
    <base-dn>dc=example,dc=org</base-dn>
    <directory-descent>true</directory-descent>
    <search-timeout-seconds>10</search-timeout-seconds>
</ldap>

Multiple LDAP Servers (High Availability)

Configure multiple LDAP servers for failover, they will be used in a round robin fashion:

<ldap>
    <servers>
        <ldap-server>
            <host>ldap1.example.com</host>
            <port>636</port>
        </ldap-server>
        <ldap-server>
            <host>ldap2.example.com</host>
            <port>636</port>
        </ldap-server>
        <ldap-server>
            <host>ldap3.example.com</host>
            <port>636</port>
        </ldap-server>
    </servers>
    <tls-mode>LDAPS</tls-mode>
    <max-connections>5</max-connections>
    <simple-bind>
        <rdns>cn=admin,ou=people</rdns>
        <userPassword>secret</userPassword>
    </simple-bind>
    <uid-attribute>uid</uid-attribute>
    <rdns>ou=people</rdns>
    <base-dn>dc=example,dc=org</base-dn>
</ldap>

Configuration Options

LDAP Server Configuration

Element Required Default Description

<servers>

Yes

-

Container for LDAP server definitions

<ldap-server>

Yes

-

Individual LDAP server configuration

<host>

Yes

-

LDAP server hostname or IP address

<port>

Yes

-

LDAP server port (389 for plain/START_TLS, 636 for LDAPS)

TLS Configuration

Element Required Default Description

<tls-mode>

No

NONE

TLS encryption mode: NONE, START_TLS, or LDAPS

<tls>

No

-

TLS truststore configuration (optional)

<truststore-path>

No

System CAs

Path to Java truststore file

<truststore-password>

No

-

Truststore password

<truststore-type>

No

JKS

Truststore type: JKS, PKCS12, JCEKS

Authentication Configuration

Element Required Default Description

<simple-bind>

Yes

-

Service account credentials for LDAP binding

<rdns> (under simple-bind)

Yes

-

Relative DN of the service account

<userPassword>

Yes

-

Password for the service account

<uid-attribute>

No

uid

LDAP attribute used for username lookup

<rdns> (under ldap)

Yes

-

Relative DN used for user name construction or search

<base-dn>

No (but recommended)

-

Base DN for DN construction

<directory-descent>

No

false

Enable directory descent for hierarchical searches

<required-object-class>

No

-

Optional object class filter for search results

<user-roles>

No

-

List of user-role role-query pairs. If no user role-query pairs are specified, the user is assigned the admin role.

<user-role> (under user-roles)

No, can appear multiple times

-

One role-query pair.

<role> (under user-role)

Yes

-

The role admin, super, user

<query>(under user-role)

Yes

-

The query to execute. Such queries would take the form of (&(entryDN={userDn})(memberOf=CN=EdgeAdmins,OU=Groups,DC=Example,DC=org)), where {userDn} is replaced by the user’s DN. If the query is successful (returns at least one result), the user is assigned the role.

<search-timeout-seconds>

No

5

Timeout for directory descent searches

The <rdns> element represents a comma-separated sequence of RDN (Relative Distinguished Name) components. The full Distinguished Name (DN) is constructed by concatenating components:
- User DN (direct binding) = <uid-attribute>={username},<rdns>,<base-dn>
- Search Root (directory descent) = <rdns>,<base-dn>
- Service Account DN = <simple-bind-rdns>,<base-dn>
However, if the <base-dn> is not present or empty, then the full DN for the service account is constructed relative to the <rdns> (from the ldap element) for backward compatibility reasons:
- Service Account DN = <simple-bind-rdns>,<rdns>

Connection Pool Configuration

Element Required Default Description

<max-connections>

No

1

Maximum number of connections in the pool

<connect-timeout-millis>

No

10000 (system default)

Connection timeout in milliseconds

<response-timeout-millis>

No

10000

Response timeout in milliseconds

Active Directory Configuration

Example for Active Directory

<ldap>
    <servers>
        <ldap-server>
            <host>ad.corp.example.com</host>
            <port>636</port>
        </ldap-server>
    </servers>
    <tls-mode>LDAPS</tls-mode>
    <simple-bind>
        <rdns>CN=HiveMQ Service,OU=Service Accounts</rdns>
        <userPassword>ServiceAccountPassword</userPassword>
    </simple-bind>
    <uid-attribute>sAMAccountName</uid-attribute>
    <base-dn>DC=corp,DC=example,DC=com</base-dn>
    <directory-descent>true</directory-descent>
    <required-object-class>person</required-object-class>
</ldap>

Active Directory Considerations

  • Use sAMAccountName as the uid-attribute (the Windows login name)

  • Enable directory-descent if users are in multiple OUs

  • The service account needs read access to the directory

  • Use person or user as the required-object-class to filter results

OpenLDAP Configuration

Example for OpenLDAP

<ldap>
    <servers>
        <ldap-server>
            <host>ldap.example.org</host>
            <port>389</port>
        </ldap-server>
    </servers>
    <tls-mode>START_TLS</tls-mode>
    <simple-bind>
        <rdns>cn=admin</rdns>
        <userPassword>admin</userPassword>
    </simple-bind>
    <uid-attribute>uid</uid-attribute>
    <base-dn>dc=example,dc=org</base-dn>
    <directory-descent>true</directory-descent>
</ldap>

OpenLDAP Considerations

  • Use uid as the uid-attribute (standard for OpenLDAP)

  • The cn=admin account typically has full read access

  • Use inetOrgPerson as the required-object-class if needed

Troubleshooting

Authentication Fails

Problem: Users cannot authenticate even with correct credentials.

Solution:

  1. Verify the service account credentials in <simple-bind> are correct

  2. Check that the <rdns> (base DN) matches your LDAP structure

  3. Test LDAP connectivity using ldapsearch: ldapsearch -H ldap://your-server -D "cn=admin,dc=example,dc=org" -w password -b "dc=example,dc=org"

  4. Enable debug logging in HiveMQ Edge to see detailed error messages

TLS Connection Errors

Problem: Cannot connect to LDAP server with TLS enabled.

Solution:

  1. Verify the LDAP server supports TLS on the specified port

  2. Check that the truststore contains the correct CA certificate

  3. Test the TLS connection: openssl s_client -connect ldap.example.com:636

  4. For START_TLS, ensure port 389 is used, not 636

Directory Descent Issues

Problem: Directory descent mode cannot find users.

Solution:

  1. Verify <directory-descent> is set to true

  2. Ensure the service account has search permissions on the base DN

  3. Check that the <rdns> (base DN) is set to a high enough level in the tree

  4. Verify the <uid-attribute> matches your LDAP schema (e.g., uid vs sAMAccountName)

Service Account DN Construction

Problem: The service account cannot bind to LDAP.

Solution:

The service account DN is constructed by combining:

If <base-dn> is not empty:

  • <simple-bind><rdns> , <base-dn>

If <base-dn> is empty, then the <rdns> element from the <ldap> element is used:

  • <simple-bind><rdns> , <rdns> (from <ldap> element)

Example:

<simple-bind>
    <rdns>uid=admin,ou=admins</rdns>
    <userPassword>hivemq</userPassword>
</simple-bind>
<rdns>ou=people</rdns>
<base-dn>dc=example,dc=org</base-dn>

Results in service account DN: uid=admin,ou=admins,dc=example,dc=org

Ensure this matches an actual account in your LDAP directory.

User DN Construction (Direct Binding)

Problem: Users exist but authentication fails with direct binding.

Solution:

User DNs are constructed by combining:

  • <uid-attribute>={username} , <rdns> , <base-dn>

Example:

<uid-attribute>uid</uid-attribute>
<rdns>ou=people</rdns>
<base-dn>dc=example,dc=org</base-dn>

For username alice, the constructed DN is: uid=alice,ou=people,dc=example,dc=org

Verify your users are actually stored at this location in the LDAP tree. If users are in nested OUs, enable directory-descent.

Security Best Practices

  1. Always use TLS in production: Use LDAPS or START_TLS to encrypt all LDAP traffic

  2. Use a dedicated service account: Create a read-only service account specifically for HiveMQ Edge

  3. Limit service account permissions: Grant only the minimum permissions needed (read access to user entries)

  4. Rotate passwords regularly: Change service account passwords on a regular schedule

  5. Monitor failed authentication attempts: Set up alerts for unusual authentication patterns

  6. Use certificate validation: Configure a proper truststore with your organization’s CA certificates

Performance Considerations

  • Connection pooling: Increase <max-connections> for high-traffic deployments (recommended: 5-10)

  • Direct binding vs. Directory descent: Direct binding is faster but requires a flat LDAP structure

  • Timeout tuning: Adjust <search-timeout-seconds> and <response-timeout-millis> based on your LDAP server performance

  • Multiple servers: Configure multiple LDAP servers for load distribution and failover

  • Network latency: Place HiveMQ Edge close to your LDAP servers to minimize network latency

Example: Complete Production Configuration

<admin-api>
    <enabled>true</enabled>
    <listeners>
        <http-listener>
            <port>8080</port>
            <bind-address>0.0.0.0</bind-address>
        </http-listener>
    </listeners>
    <ldap>
        <!-- Multiple servers for high availability -->
        <servers>
            <ldap-server>
                <host>ldap1.corp.example.com</host>
                <port>636</port>
            </ldap-server>
            <ldap-server>
                <host>ldap2.corp.example.com</host>
                <port>636</port>
            </ldap-server>
        </servers>

        <!-- LDAPS for security -->
        <tls-mode>LDAPS</tls-mode>
        <tls>
            <truststore-path>/opt/hivemq/conf/truststore.jks</truststore-path>
            <truststore-password>changeit</truststore-password>
            <truststore-type>JKS</truststore-type>
        </tls>

        <!-- Service account credentials -->
        <simple-bind>
            <rdns>CN=HiveMQ Service,OU=Service Accounts</rdns>
            <userPassword>SecureServiceAccountPassword</userPassword>
        </simple-bind>

        <!-- Active Directory configuration -->
        <uid-attribute>sAMAccountName</uid-attribute>
        <rdns>DC=corp,DC=example,DC=com</rdns>
        <directory-descent>true</directory-descent>
        <required-object-class>person</required-object-class>

        <!-- Performance tuning -->
        <max-connections>10</max-connections>
        <connect-timeout-millis>5000</connect-timeout-millis>
        <response-timeout-millis>10000</response-timeout-millis>
        <search-timeout-seconds>10</search-timeout-seconds>
    </ldap>
</admin-api>

Security Log for LDAP Authentication

For LDAP we support logging successful and unsuccessful authentication attempts. The log will be in the file logs/security.log.

OIDC (Single Sign-On) Authentication

HiveMQ Edge supports OpenID Connect (OIDC) authentication for the Admin API and user interface. OIDC provides single sign-on (SSO) against your organization’s identity provider (IdP), such as Keycloak or Microsoft Entra ID (Azure AD).

Overview

OIDC authentication allows you to do the following:

  • Let users sign in to HiveMQ Edge with their existing organizational account (Login with SSO).

  • Delegate authentication to a central identity provider (IdP) instead of local credentials.

  • Assign HiveMQ Edge roles based on the roles or groups managed in the IdP.

  • Keep the HiveMQ Edge backend stateless, with no server-side user sessions.

When OIDC is enabled, the HiveMQ Edge login page shows a Login with SSO button alongside (or instead of) the username and password form.

Local username and password authentication and OIDC are independent. You can enable either, both, or neither: OIDC alongside local login, OIDC only, local login only — or neither, which closes Admin API login entirely. Because the combination determines who can get in, you must state it explicitly — see the note below.

OIDC authentication is disabled by default.

When an <oidc-authentication> stanza is enabled, any error in it prevents HiveMQ Edge from starting. Validate an OIDC configuration change before you roll it out.

For example, an enabled stanza is invalid when it has any of the following:

  • A missing <issuer-uri>, <client-id>, or <redirect-uri>.

  • An issuer URI that is not https, or that carries a query or fragment.

  • An unsupported identity-token signing algorithm.

  • A connection timeout below 100 ms.

  • A truststore that cannot be read.

  • A <role-mappings> block with no mappings.

When you add an <oidc-authentication> stanza, you must also add a <username-authentication> stanza that states whether local username and password login stays enabled. This makes the choice explicit so that local login is never left on implicitly alongside OIDC. If <oidc-authentication> is present but <username-authentication> is absent, HiveMQ Edge refuses to start and logs the reason.

<username-authentication>
    <enabled>true</enabled>  <!-- or false, for OIDC-only login -->
</username-authentication>

Local username and password login stays enabled by default only when neither stanza is present.

How It Works

HiveMQ Edge implements the OIDC authorization-code flow with Proof Key for Code Exchange (PKCE):

  1. The user clicks Login with SSO. HiveMQ Edge redirects the browser to the identity provider (IdP).

  2. The user authenticates with the IdP.

  3. The IdP redirects the browser back to HiveMQ Edge with a one-time authorization code.

  4. HiveMQ Edge exchanges the code for the user’s ID token, validates the ID token, reads the user’s roles, and issues its own short-lived HiveMQ Edge token.

  5. HiveMQ Edge signs the user in with the HiveMQ Edge roles mapped from the IdP.

HiveMQ Edge discovers the IdP’s endpoints automatically from the issuer’s OIDC discovery document ({issuer-uri}/.well-known/openid-configuration). You only need to configure the issuer URI, client credentials, and redirect URI.

OIDC Authorization (Role Assignment)

After a user authenticates, HiveMQ Edge reads the roles from a claim in the identity token (by default the roles claim) and turns each identity provider (IdP) role name into a HiveMQ Edge role (admin, super, or user) through a required <role-mappings> block. Each identity provider role is matched against the configured <idp-role> values and translated to the corresponding <edge-role>. Any identity provider role that has no mapping is ignored. This lets the identity provider use its own role or group names.

Matching is exact: role names are compared literally, with no trimming of surrounding whitespace and no change of case. Configure <idp-role> values to match exactly what the IdP emits. HiveMQ Edge denies access when a user’s IdP roles do not map to any HiveMQ Edge role.

<role-mappings> is required whenever OIDC is enabled and must contain at least one <role-mapping>. Identity providers use their own role or group names, so every deployment needs the block; an enabled stanza without it, or with an empty block, prevents HiveMQ Edge from starting.

Configuration

You configure OIDC authentication in the Admin API section (<admin-api>) of the HiveMQ Edge configuration file (config.xml).

Basic Configuration Example

<admin-api>
    <enabled>true</enabled>
    <listeners>
        <http-listener>
            <port>8080</port>
            <bind-address>0.0.0.0</bind-address>
        </http-listener>
    </listeners>
    <oidc-authentication>
        <enabled>true</enabled>
        <issuer-uri>https://idp.example.com/realms/acme</issuer-uri>
        <client-id>hivemq-edge</client-id>
        <client-secret>your-client-secret</client-secret>
        <redirect-uri>https://edge.example.com/api/v1/auth/oidc/callback</redirect-uri>
        <role-claim-name>roles</role-claim-name>
        <role-mappings>
            <role-mapping>
                <idp-role>edge-admin</idp-role>
                <edge-role>admin</edge-role>
            </role-mapping>
            <role-mapping>
                <idp-role>edge-user</idp-role>
                <edge-role>user</edge-role>
            </role-mapping>
        </role-mappings>
    </oidc-authentication>
</admin-api>

The <redirect-uri> must point to the HiveMQ Edge callback endpoint (/api/v1/auth/oidc/callback) at the address the browser uses to reach HiveMQ Edge. Register this URI as a valid redirect URI for the client in the identity provider (IdP).

Configuration Options

Element Required Default Description

<enabled>

No

false

Enables OIDC authentication when set to true.

<issuer-uri>

Yes

-

The IdP’s issuer URI. Must be an https URL with no query or fragment component. HiveMQ Edge discovers the authorization, token, and key endpoints from {issuer-uri}/.well-known/openid-configuration

<client-id>

Yes

-

The client identifier registered for HiveMQ Edge in the IdP.

<client-secret>

No

-

The client secret for confidential clients, which HiveMQ Edge keeps server-side and never exposes to the browser.

<redirect-uri>

Yes

-

The callback URL the IdP redirects to after authentication. The URL must be …​/api/v1/auth/oidc/callback and registered in the IdP.

<role-claim-name>

No

roles

The name of the ID token claim that lists the user’s roles.

<extra-scopes>

No

-

Container for additional OAuth2 scopes to request, one <extra-scope> element per scope (for example, email and profile). The openid scope is always requested.

<role-mappings>

Yes

-

Container for role mappings from IdP roles to HiveMQ Edge roles. Required when OIDC is enabled, and must contain at least one <role-mapping>.

<id-token-signing-algorithms>

No

All supported asymmetric algorithms

Container that restricts which signature algorithms HiveMQ Edge accepts on the identity token. When omitted, HiveMQ Edge accepts any supported asymmetric algorithm. Configure this to pin the exact algorithm your client is registered for at the identity provider

<truststore>

No

System default CA certificates

Container for the truststore that validates the identity provider’s TLS certificate. When omitted, HiveMQ Edge validates against the system default CA certificates. Configure this when the identity provider certificate is signed by a private or internal Certificate Authority

<connection-timeout-millis>

No

5000

Timeout in milliseconds for each connection to the identity provider, with a minimum of 100. The default assumes a good connection. Raise it for an identity provider behind a slow or distant network path

Identity-Token Signing Algorithms

By default HiveMQ Edge accepts an identity token signed with any supported asymmetric algorithm: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, or ES512. Symmetric algorithms (HS*) and the none algorithm are never accepted.

To restrict the accepted algorithms, list one or more <id-token-signing-algorithm> elements. Set this to the single algorithm your client is registered for at the identity provider.

<id-token-signing-algorithms>
    <id-token-signing-algorithm>ES256</id-token-signing-algorithm>
</id-token-signing-algorithms>
Element Required Default Description

<id-token-signing-algorithm>

Yes (within <id-token-signing-algorithms>)

-

An accepted signature algorithm. Must be one of the supported asymmetric algorithms listed above. At least one is required when <id-token-signing-algorithms> is present

Identity Provider Truststore

HiveMQ Edge fetches the discovery document, tokens, and signing keys from the identity provider over TLS. By default it validates the identity provider certificate against the system default CA certificates.

Configure a <truststore> when the identity provider certificate is signed by a private or internal Certificate Authority, as is common for on-premises deployments. This is the same truststore configuration used for LDAP.

<truststore>
    <truststore-path>/opt/hivemq/conf/idp-truststore.p12</truststore-path>
    <truststore-password>changeit</truststore-password>
    <truststore-type>PKCS12</truststore-type>
</truststore>
Element Required Default Description

<truststore-path>

Yes (within <truststore>)

-

Path to the truststore file holding the CA that signs the identity provider certificate

<truststore-password>

No

-

Password for the truststore

<truststore-type>

No

Platform default (usually PKCS12)

Type of the truststore, for example JKS or PKCS12

When a <truststore> is configured, HiveMQ Edge fails to start if the file is missing or the password is wrong. It does not fall back to the system default CA certificates.

Role Mapping Configuration

Element Required Default Description

<role-mapping>

Yes (within <role-mappings>)

-

A single mapping from an identity provider role to a HiveMQ Edge role. At least one is required when <role-mappings> is present

<idp-role>

Yes

-

The role name the IdP emits.

<edge-role>

Yes

-

The HiveMQ Edge role to assign: admin, super, or user.

Keycloak Configuration

To use Keycloak as the identity provider (IdP):

  1. Create a realm (or use an existing one) and note its issuer URI: https://<keycloak-host>/realms/<realm>;.

  2. Create a confidential client with client ID hivemq-edge, standard flow enabled, and PKCE method S256.

  3. Add …​/api/v1/auth/oidc/callback to the client’s Valid redirect URIs.

  4. Add a realm role or client role mapper that puts the user’s roles into a roles claim in the ID token.

  5. Map the Keycloak roles to HiveMQ Edge roles using <role-mappings>.

Keycloak Considerations

  • Ensure the roles mapper has Add to ID token enabled. HiveMQ Edge reads roles from the ID token.

  • If you use client roles rather than realm roles, adjust the mapper type accordingly.

Microsoft Entra ID (Azure AD) Configuration

To use Microsoft Entra ID as the identity provider (IdP):

  1. Register an application and note the issuer URI (typically https://login.microsoftonline.com/<tenant-id>/v2.0).

  2. Add …​/api/v1/auth/oidc/callback as a Web redirect URI.

  3. Create a client secret.

  4. Define app roles and assign them to users or groups, then configure the token to emit the roles in the roles claim.

  5. Map the Entra ID app roles to HiveMQ Edge roles using <role-mappings>.

Entra ID Considerations

  • Entra ID emits roles in the roles claim by default, which matches the HiveMQ Edge default <role-claim-name>.

  • App-role values are defined per application registration; use those values as <idp-role>.

Troubleshooting

The SSO Button Does Not Appear

The login page shows the Login with SSO button only when OIDC is enabled and completely configured. Verify the following:

  • <oidc-authentication><enabled> is set to true.

  • You have set values for all three of the required properties: <issuer-uri>, <client-id>, and <redirect-uri>. If any is missing while OIDC is enabled, HiveMQ Edge logs an error and refuses to start — so a running HiveMQ Edge with no SSO button has OIDC disabled rather than misconfigured.

  • A request to {edge-url}/api/v1/auth/mode lists OPEN_ID in its modes array, for example {"modes":["OPEN_ID"]} or {"modes":["USERNAME_PASSWORD","OPEN_ID"]}. If the array contains only USERNAME_PASSWORD, OIDC is not active.

The Identity Provider (IdP) Is Unreachable

If login fails immediately (HTTP 503), HiveMQ Edge cannot reach the IdP’s discovery document. Verify the following:

  • {issuer-uri}/.well-known/openid-configuration is reachable from the HiveMQ Edge host and returns JSON.

  • The <issuer-uri> matches the issuer value in that discovery document exactly.

Login Fails After Entering Credentials

If authentication at the IdP succeeds but HiveMQ Edge rejects the login, check the HiveMQ Edge log. The log names the specific failure. Common causes include the following:

  • The <redirect-uri> in the configuration is not registered as a valid redirect URI for the client in the IdP.

  • The <client-secret> does not match the secret configured in the IdP.

Signed In With the Wrong or No Permissions

If a user signs in but has unexpected permissions, the roles claim is not reaching HiveMQ Edge or the role mappings do not match. Verify the following:

  • The IdP emits the user’s roles in the claim named by <role-claim-name> (default roles), and that claim is present in the ID token.

  • The <idp-role> values in <role-mappings> match the role names the IdP emits.

  • If a mapping key differs from an IdP role only by case or whitespace, HiveMQ Edge logs a warning that names the key. Check the HiveMQ Edge log for this warning. HiveMQ Edge matches mapping keys to IdP roles exactly. A mapping key that differs in any way does not match, and the mapping has no effect.

Security Best Practices

  • Serve the HiveMQ Edge API over HTTPS to protect tokens in transit.

  • Use an https issuer URI. HiveMQ Edge fetches the discovery document, token, and signing keys from the issuer. An unencrypted issuer lets a network attacker forge the identity provider, so HiveMQ Edge requires https.

  • Use a confidential client with a client secret that never leaves the HiveMQ Edge backend.

  • Grant each user the least-privileged HiveMQ Edge role that their IdP roles require.

  • Restrict the client’s valid redirect URIs in the IdP to the exact HiveMQ Edge callback URL.

Example: Complete Configuration

<admin-api>
    <enabled>true</enabled>
    <listeners>
        <https-listener>
            <port>8443</port>
            <bind-address>0.0.0.0</bind-address>
            <tls>
                <keystore>
                    <path>/opt/hivemq/conf/keystore.jks</path>
                    <password>changeit</password>
                    <private-key-password>changeit</private-key-password>
                </keystore>
            </tls>
        </https-listener>
    </listeners>
    <oidc-authentication>
        <enabled>true</enabled>
        <issuer-uri>https://idp.example.com/realms/acme</issuer-uri>
        <client-id>hivemq-edge</client-id>
        <client-secret>your-client-secret</client-secret>
        <redirect-uri>https://edge.example.com/api/v1/auth/oidc/callback</redirect-uri>
        <role-claim-name>roles</role-claim-name>
        <extra-scopes>
            <extra-scope>email</extra-scope>
            <extra-scope>profile</extra-scope>
        </extra-scopes>
        <role-mappings>
            <role-mapping>
                <idp-role>edge-admin</idp-role>
                <edge-role>admin</edge-role>
            </role-mapping>
            <role-mapping>
                <idp-role>edge-user</idp-role>
                <edge-role>user</edge-role>
            </role-mapping>
        </role-mappings>
    </oidc-authentication>
</admin-api>

Testing Security Configuration

You can test authentication using the Admin API directly:

curl -X POST http://localhost:8080/api/v1/auth/authenticate \
  -H "Content-Type: application/json" \
  -d '{"userName":"alice","password":"user-password"}'

A successful authentication returns a JWT bearer token:

{
  "token": "eyJraWQiOiIwMDAwMSIsImFsZyI6IlJTMjU2In0..."
}

An unsuccessful authentication returns:

{
  "type": "Unauthorized",
  "title": "Unauthorized",
  "detail": "Unauthorized",
  "status": 401,
  "errors": [{
    "detail": "Invalid username and/or password"
  }]
}

HiveMQ Edge User Interface Pre Login Notice

The HiveMQ Edge administrative user interface supports the configuration of a pre-login notice that users must acknowledge before accessing the system. This feature allows administrators to display a customizable notice dialog with a title, message, and optional consent confirmation. When consent is set, users must explicitly accept the terms presented in the notice to proceed with the login process.

UI-Screenshot Pre-Login Notice

The pre-login notice can be configured through the pre-login-notice element.

Example configuration to add pre login notice
<?xml version="1.0"?>
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <admin-api>
        <pre-login-notice>
           <enabled>true</enabled>
           <title>Notice (Area 12, Munich)</title>
           <message>User, please note you’re accessing the HiveMQ Edge instance that collects data for Area 12, Munich.  Please ensure you’re making changes to the correct instance, to continue log in check ‘Proceed’ and click ‘Proceed to sign in’.</message>
           <consent>Proceed</consent>
        </pre-login-notice>
    </admin-api>
</hivemq>

Using The HiveMQ Edge API

The HiveMQ Edge API is generated from JAX-RS compliant web service definitions based on the OpenAPI specification. The latest version of the specification document can be generated from the source repository using the supplied gradle task:

./gradlew :openApiSpec
You can also refer to the version-controlled HiveMQ Edge Open API document.

The HiveMQ Edge API provides functionality to control the addition, removal, modification, and runtime control of MQTT bridges and protocol adapters. The API also gives you the ability to set up and modify Unified Namespace (UNS) configurations.

For a list of all the available services, see HiveMQ Edge Open API.