Skip to content

Migrating from Azure IoT Hub to EMQX

This guide provides a practical walkthrough for migrating IoT devices from Azure IoT Hub to EMQX. It covers two migration paths:

  1. X.509 certificate authentication: For devices using client certificates
  2. SAS token authentication: For devices using Shared Access Signature (SAS) tokens with HTTP-based authentication

Migration at a Glance

For devices using X.509 certificates, the migration is primarily a configuration change. Device certificates and private keys remain unchanged; only the broker endpoint and server CA certificate need updates. EMQX must be configured to trust the same CA that Azure trusts and to replicate Azure's identity mapping model, where the certificate Common Name (CN) equals the deviceId.

The migration process consists of three main phases:

  1. Locate Your CA Certificate. Find the CA certificate that signed your device certificates.

  2. Configure EMQX for mTLS. Set up an SSL/TLS listener on the EMQX broker, enable mandatory peer verification, and configure the listener to trust your CA and map the certificate CN to deviceId.

  3. Update Device Clients. Update device code to connect to the EMQX endpoint and trust the EMQX server CA certificate. Devices can continue to use the Azure IoT SDK or utilize standard MQTT clients.

The following table summarizes the parameter changes:

ParameterAzure IoT Hub (Example)EMQX (Example)Notes
Endpoint Hostnamemy-hub.azure-devices.netmqtt.example.comUpdate device client code
Device Certificatedevice-001.cert.pemdevice-001.cert.pemNo change. Devices continue using the existing certificate
Device Private Keydevice-001.key.pemdevice-001.key.pemNo change. Devices continues using the existing private key
Server Verification (Device trusts Server)Device trusts Azure's public CADevice must trust emqx-server-ca.pemDeploy EMQX server CA to devices
Client Verification (Server trusts Device)Azure trusts your CA (registered via CA upload or thumbprint)EMQX cacertfile must be set to your CASame CA used in Azure
Identity MappingAzure extracts CN=deviceIdEnable mqtt.peer_cert_as_clientid = cnPreserves deviceId-based authorization

Phase 1: Locate Your CA Certificate

What you need: The CA certificate that signed your device certificates (in PEM format, e.g., device-ca.pem). This certificate is essential for EMQX to verify device identities during mTLS authentication.

Azure IoT Hub supports two X.509 registration methods:

  • CA registration: You uploaded a CA to Azure IoT Hub. You must locate the same CA file that you originally uploaded.
  • Thumbprint registration: You registered each device individually by its certificate thumbprint. Although no CA was uploaded to Azure, the device certificates were still signed by a CA (such as an internal CA, a self-signed CA, or an enterprise PKI). You must locate the CA that issued these certificates.

Regardless of the method, the certificate hierarchy is the same: your devices are always signed by your own CA. For migration to EMQX, you must obtain this CA certificate so EMQX can verify your devices.

Identify the CA That Issued Your Device Certificates

Use OpenSSL to inspect the Issuer field in a device certificate:

bash
openssl x509 -in device-001.cert.pem -noout -issuer

Expected output:

issuer=CN = MyCompany-Device-CA

The corresponding CA file (e.g., MyCompany-Device-CA.pem) is the CA certificate you must provide to EMQX. This is the most reliable way to determine the correct CA, especially when using thumbprint registration.

Verify Certificate Requirements

Azure requires that the certificate Subject Common Name (CN) match the deviceId (or deviceId/moduleId for modules). You can verify this using:

bash
openssl x509 -in device-001.cert.pem -noout -subject

Expected output:

subject=CN = device-001

EMQX extracts this CN during mTLS authentication and use it as the device’s identity.

Confirm Device Credential Access

Each device retains secure access to its own credentials:

  • The device's leaf certificate (device-001.cert.pem)
  • The device's private key (device-001.key.pem)

Because Azure IoT Hub and EMQX both use standard X.509 authentication, no certificate re-provisioning is required for this migration path.

Phase 2: Configure EMQX for Azure-Compatible mTLS

Configure EMQX to authenticate devices using the same CA and identity-mapping rules that Azure IoT Hub uses for X.509 authentication.

Enable and Configure the mTLS Listener

Configure EMQX to enable two-way SSL/TLS authentication (mTLS) on the SSL listener. For detailed information on SSL/TLS configuration, see Enable SSL/TLS Connection.

Open the EMQX configuration file (emqx.conf) and configure the SSL/TLS listener, or use the Dashboard (Management -> Listeners):

hocon
listeners.ssl.default {
  bind = "0.0.0.0:8883"

  ssl_options {
    # Your EMQX server's certificate
    certfile = "etc/certs/server-cert.pem"

    # Your EMQX server's private key
    keyfile = "etc/certs/server-key.pem"

    # --- mTLS Configuration for Device Authentication ---

    # The CA certificate that signed your device certificates
    cacertfile = "etc/certs/azure-device-ca.pem"

    # Enable client certificate verification
    verify = verify_peer

    # Reject clients that do not present a certificate
    fail_if_no_peer_cert = true
  }
}

TIP

Both Azure IoT Hub and EMQX use port 8883 as the default for MQTT over TLS/SSL, so no port changes are needed in device clients.

Key Configuration Parameters:

  • cacertfile: Path to your CA certificate (or bundle of self-signed device certificates). EMQX will use this to verify device certificates.
  • verify: Must be set to verify_peer to enable mTLS.
  • fail_if_no_peer_cert: Must be set to true to enforce certificate requirement.

Replicate Azure's CN=deviceId Identity Mapping

Azure IoT Hub extracts the certificate's Common Name and uses it as the deviceId for authorization. Replicate this in EMQX:

hocon
mqtt.peer_cert_as_clientid = cn
mqtt.peer_cert_as_username = cn

This configuration ensures that:

  • The MQTT ClientID is automatically set to the certificate CN (deviceId)
  • The username is also set to the certificate CN
  • You can configure EMQX ACL rules using ${clientid} or ${username} to match the deviceId, replicating Azure's authorization model

For devices using modules (deviceId/moduleId format), the CN contains both identifiers and can be used directly in EMQX ACLs.

Apply Configuration Changes

After updating the configuration file, reload the configuration:

bash
emqx ctl conf reload

If you made changes via the Dashboard, click Update to apply them. The listener will restart automatically to apply the new settings.

Verify the listener is enforcing mTLS:

bash
openssl s_client -connect mqtt.example.com:8883 -showcerts

The connection should fail without a client certificate.

Phase 3: Update Device Clients and Verify Migration

The final phase is to update the device client code to connect to EMQX instead of Azure IoT Hub.

Prepare EMQX Server CA Certificate

Before updating the device code, you need to obtain the EMQX server's CA certificate. This is the CA that signed the EMQX server's TLS certificate.

For self-signed EMQX server certificates, you must add the server CA to your device's trusted certificate store:

Linux:

bash
# Copy CA to system trust store
sudo cp emqx-server-ca.pem /usr/local/share/ca-certificates/emqx-ca.crt
sudo update-ca-certificates

macOS:

bash
# Add to system keychain
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain emqx-server-ca.pem

Windows:

powershell
# Import certificate to Trusted Root CA store
Import-Certificate -FilePath emqx-server-ca.pem -CertStoreLocation Cert:\LocalMachine\Root

TIP

If your EMQX server uses a certificate from a public CA (like Let's Encrypt), this step is not needed as the CA is already trusted by the system.

Update Device Client Code

The Azure IoT SDK for Python (and other languages) supports connecting to custom MQTT brokers through the server_verification_cert and custom hostname parameters. This allows for minimal code changes.

Python Example:

python
from azure.iot.device import IoTHubDeviceClient, X509

# Load device credentials
x509 = X509(
    cert_file="certs/device-001.cert.pem",
    key_file="certs/device-001.key.pem"
)

# Read EMQX server CA certificate content
with open("certs/emqx-server-ca.pem", "r") as f:
    emqx_server_ca = f.read()

# Create client pointing to EMQX
client = IoTHubDeviceClient.create_from_x509_certificate(
    x509=x509,
    hostname="mqtt.example.com",  # EMQX hostname instead of Azure
    device_id="device-001",
    server_verification_cert=emqx_server_ca  # CA cert content as string
)

# Connect and use as before
client.connect()
client.send_message("Hello from migrated device")

TIP

  • The server_verification_cert parameter expects the certificate content as a string, not a file path.
  • If you've added the EMQX server CA to your system's trusted certificate store (recommended), you can omit this parameter and let the system handle verification.
  • Using the Azure IoT SDK preserves your existing application code structure, requiring only configuration changes. This is the simplest migration path for devices already using X.509 authentication.

Device-Side Parameter Summary

These are the parameter changes needed:

  1. Endpoint/Hostname:

    • Azure: my-hub.azure-devices.net
    • EMQX: mqtt.example.com
  2. Server CA Certificate:

    • Azure: Uses the system trust store or Azure CA
    • EMQX: Must explicitly provide emqx-server-ca.pem
  3. Device Credentials (no changes):

    • Certificate: Keep the existing device certificate
    • Private key: Keep the existing private key
  4. ClientId: Set to deviceId (matching certificate CN)

Validation Checklist

  1. Device appears in EMQX Dashboard with clientid = deviceId.
  2. TLS handshake succeeds, and the device certificate is verified.
  3. The device can publish to authorized topics.
  4. The device can subscribe to authorized topics.
  5. No authentication errors in EMQX logs.

Variations of the Standard Migration Path

Besides the core migration workflow described above, some device fleets follow simple variations that still fit within the same X.509-based migration process. This section highlights two common variations and explains how EMQX accommodates them without requiring changes to device certificates or firmware.

CA-Signed Device Fleets

  • Upload the CA certificate to EMQX.
  • All devices whose certificates were signed by this CA will be trusted automatically.
  • Certificate lifecycle management remains centralized and simple.
  • New devices can be added without any EMQX configuration changes.

This scenario mirrors Azure IoT Hub’s CA-based provisioning model and offers the most scalable migration path for large fleets.

Devices Using Modules (deviceId/moduleId)

  • Devices whose certificates include a Common Name (CN) in the format deviceId/moduleId are fully supported.
  • EMQX can use the full CN for identity mapping and authentication.
  • Authorization rules (ACLs) can reference the entire CN, preserving Azure’s module-level access control behavior.

This allows devices using Azure’s module hierarchy to migrate seamlessly, without certificate modification or custom identity logic.

Alternative: SAS Token Authentication with HTTP Authenticator

If your devices use Azure SAS tokens, you can continue using this authentication method in EMQX by implementing a simple HTTP authentication service. For detailed information on HTTP authentication, see Use HTTP Service.

How SAS Token Authentication Works

Azure IoT Hub sends SAS credentials through the MQTT username and password fields:

  • Username: {iothubhostname}/{deviceId}/?api-version=2021-04-12
  • Password: SharedAccessSignature sr={resource}&sig={signature}&se={expiry}

EMQX forwards these values to your HTTP service, which performs the actual SAS token validation.

Implement HTTP Authentication for SAS Tokens

  1. Create an HTTP authentication service. Your service should perform the following tasks:

    • Receive the username and password from EMQX.
    • Extract the deviceId from the username.
    • Parse the SAS token from the password field.
    • Validate the token signature using the device's symmetric key.
    • Check the token expiry value (se field).
    • Return {"result": "allow"} or {"result": "deny"} based on the validation result.
  2. Configure EMQX HTTP Authenticator to use your HTTP service. Add an HTTP authenticator either through the Dashboard or configuration file:

hocon
authentication = [
  {
    mechanism = password_based
    backend = http
    method = post
    url = "http://your-auth-service:8080/auth"
    body {
      username = "${username}"
      password = "${password}"
      clientid = "${clientid}"
    }
    headers {
      "Content-Type" = "application/json"
    }
  }
]
  1. Provision Device Credentials. Export device identities and symmetric keys from the Azure IoT Hub identity registry. Store them in the database used by your HTTP authentication service so it can validate SAS signatures.

Example HTTP Authentication Service Response

Your service should respond with JSON similar to the following:

json
{
  "result": "allow",
  "is_superuser": false,
  "client_attrs": {
    "device_id": "device-001"
  }
}

TIP

This approach allows SAS token-based devices to migrate without firmware changes. However, for long-term portability and security, migrating to X.509 certificate authentication is recommended.

Conclusion

Migrating devices from Azure IoT Hub to EMQX can follow one of two authentication paths, depending on how your devices are currently provisioned.

X.509 Certificate–Based Devices

This is the simplest and most direct migration path. Your existing device certificates and private keys remain unchanged, and only the following updates are required:

  • Configure EMQX to trust the same CA used in Azure
  • Enable mTLS and certificate-based identity mapping
  • Update device endpoints and server CA certificates

With these adjustments, devices can connect to EMQX while preserving the same security model and certificate workflow.

SAS Token–Based Devices

Devices using Azure SAS tokens can continue using them in EMQX by implementing an HTTP authentication service that validates token signatures and expiry. This enables migration without firmware changes.

However, for long-term portability and stronger security, transitioning to X.509 certificates is recommended.

TIP

If your deployment includes both X.509 and SAS token devices, consider migrating the X.509 fleet first to reduce effort and accelerate validation. Then evaluate whether SAS token devices should use an HTTP authentication service for immediate compatibility or migrate to X.509 certificates for long-term maintainability.