Configuring Bidirectional Dataflow Between Prosys OPC UA and HiveMQ Edge
Introduction
Industrial IoT systems live or die by the quality of their data pipeline, and the path from a shop floor sensor to a cloud dashboard runs through the protocol layer. OPC UA has become the lingua franca of industrial device communication, but getting it to speak fluently with an MQTT broker requires careful configuration, especially when security is non-negotiable.
This guide walks you through building a secure, bidirectional integration between the Prosys OPC UA Simulation Server and HiveMQ Edge using Mutual TLS. Note that the Prosys OPC UA Simulation Server is intended for development and testing purposes only and should not be used in production environments. For production deployments, refer to Prosys OPC UA Forge.
You'll set up the full certificate trust chain, configure both Northbound (OPC UA → MQTT) and Southbound (MQTT → OPC UA) data flows, and verify end-to-end message delivery. By the end, you'll have a working foundation you can carry directly into production IIoT architectures.
Prerequisites
Latest version of HiveMQ Edge installed
Java keytool (comes with JDK)
OpenSSL
MQTT CLI installed
Review the Northbound HiveMQ documentation
Review the Southbound HiveMQ documentation
Instructions for Integrating Prosys OPC UA with HiveMQ Edge
This guide is organized into 13 sections that walk you through the full integration from installation to verification. Sections 1–7 cover the foundational setup: installing the Prosys simulation server, establishing mutual TLS trust between both systems, and confirming a secure connection. Sections 8–10 focus on Northbound data flow, mapping OPC UA nodes to MQTT topics so telemetry moves from the field up to HiveMQ Edge. Sections 11–13 cover the Southbound path, configuring HiveMQ Edge to push MQTT messages back down to OPC UA nodes for device control.
HiveMQ Edge Client Certificate Architecture
Before we dive into the implementation steps, let's review the role each certificate plays and where they are placed. We generate one HiveMQ Edge client certificate that serves two security purposes in the Prosys server:

Critical Understanding:
Locations #2 and #3 contain the same certificate (exported from #1)
They're in two different folders because OPC UA separates:
Application authentication (PKI) - "Is this a trusted application?"
User authentication (USERS_PKI) - "Is this a trusted user?"
The certificate we generate is:
HiveMQ Edge Client Certificate
Generated with: keytool -genkeypair
Stored as: conf/certs/client-keystore.p12
Contains: Private key + Public certificate
Purpose: HiveMQ Edge's identity for both secure channel and user authentication
The two Prosys certificates we import into HiveMQ Edge’s truststore are:
Prosys Server CA Certificate
Source: ~/.prosysopc/.../PKI/CA/private/SimulationServerCA.der
Imported into: HiveMQ Edge's conf/certs/truststore.jks
Purpose: Trust Prosys's Certificate Authority
2. Prosys Server Certificate
Source: ~/.prosysopc/.../PKI/CA/private/SimulationServer@mac_2048.der
Imported into: HiveMQ Edgeʼs conf/certs/truststore.jks
Purpose: Trust Prosys's server identity
Prosys requires one HiveMQ Edge certificate to be trusted for both Application and User authentication:
Application Trust (Secure Channel)
Location: ~/.prosysopc/.../PKI/CA/certs/[fingerprint].der
Purpose: Prosys trusts HiveMQ Edge for TLS secure channel
Process: Moved from PKI/CA/rejected/ after first connection
User Trust (User Authentication)
Location: ~/.prosysopc/.../USERS_PKI/CA/certs/[fingerprint].der
Purpose: Prosys trusts HiveMQ Edge as an authenticated user
Process: Moved from USERS_PKI/CA/rejected/ after enabling X.509 auth
Section 1: Install Prosys OPC UA Simulation Server
Here are the steps to install Prosys OPC UA simulation server:
Visit the Prosys official download page:

You will first need to fill out a web form with your details and submit it.
Next, you will receive a download link via email.
Once the package is downloaded, run the installer and follow the on-screen instructions.
Launch the Prosys OPC UA Simulation Server and allow it to initialize default settings.
Under the Status tab, you will be presented with an endpoint URL which serves as the connection point for integrating HiveMQ with Prosys.
Section 2: Create HiveMQ Edge's Truststore
This truststore enables HiveMQ Edge to trust the Prosys server.
Steps:
First, let's create a directory where we will keep the client certificate, keystore and truststore:
cd <hivemq>/conf
mkdir certs
cd certs/ 2. Convert the Prosys CA into a PEM:
openssl x509 \
-in ~/.prosysopc/prosys-opc-ua-simulation-server/PKI/CA/private/SimulationServerCA.der \
-inform DER \
-outform PEM \
-out prosys-ca.pem 3. Import the PEM into a newly created truststore:
keytool -import \
-alias prosys-ca \
-file prosys-ca.pem \
-keystore truststore.jks \
-storepass changeit \
-noprompt 4. Import the Prosys Server Certificate:
keytool -import \
-alias prosys-server \
-file ~/.prosysopc/prosys-opc-ua-simulation-server/PKI/CA/private/SimulationServer@mac_2048.der \
-keystore truststore.jks \
-storepass changeit \
-noprompt Note: The filename SimulationServer@mac_2048.der may have a similar variation to mac-1, mac-2.
Section 3: Generate HiveMQ Edge Client Certificate
The client certificate will be the one certificate used for both the Prosys server application and user authentication.
Steps:
Generate the client certificate and keystore:
keytool -genkeypair \
-alias hivemq-edge-client \
-keyalg RSA \
-keysize 2048 \
-validity 3650 \
-storetype PKCS12 \
-keystore client-keystore.p12 \
-storepass changeit \
-keypass changeit \
-dname "CN=HiveMQ-Edge-Client, O=HiveMQ, C=US" \
-ext "SAN=URI:urn:hivemq:edge:client,DNS:mac.home,IP:127.0.0.1" \
-ext "KeyUsage:critical=digitalSignature,keyEncipherment,dataEncipherment,nonRepudiation" \
-ext "ExtendedKeyUsage=clientAuth,serverAuth"
Section 4: Configure HiveMQ Edge
Now that we have the certificate directory fully established, let's move over to HiveMQ Edge for configuration.
Steps:
Open Prosys, and in the Status tab, copy the Connection Address:

Compose your HiveMQ Edge config.xml (<connection_address> and <hivemq_edge> to be supplemented):
<hivemq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="config.xsd">
<config-version>1</config-version>
<mqtt-listeners>
<tcp-listener>
<port>1883</port>
<bind-address>0.0.0.0</bind-address>
</tcp-listener>
</mqtt-listeners>
<protocol-adapters>
<protocol-adapter>
<adapterId>prosys-server</adapterId>
<protocolId>opcua</protocolId>
<configVersion>1</configVersion>
<config>
<auth>
<x509>
<enabled>true</enabled>
</x509>
</auth>
<connectionOptions>
<autoReconnect>true</autoReconnect>
<connectionTimeoutMs>30000</connectionTimeoutMs>
<healthCheckIntervalMs>30000</healthCheckIntervalMs>
<keepAliveFailuresAllowed>3</keepAliveFailuresAllowed>
<keepAliveIntervalMs>10000</keepAliveIntervalMs>
<requestTimeoutMs>30000</requestTimeoutMs>
<retryIntervalMs>30000</retryIntervalMs>
<sessionTimeoutMs>120000</sessionTimeoutMs>
</connectionOptions>
<opcuaToMqtt>
<publishingInterval>1000</publishingInterval>
<serverQueueSize>1</serverQueueSize>
</opcuaToMqtt>
<overrideUri>false</overrideUri>
<security>
<messageSecurityMode>SIGN_AND_ENCRYPT</messageSecurityMode>
<policy>BASIC256SHA256</policy>
</security>
<tls>
<enabled>true</enabled>
<keystore>
<password>changeit</password>
<path><hivemq_edge>/conf/certs/client-keystore.p12</path>
<privateKeyPassword>changeit</privateKeyPassword>
</keystore>
<tlsChecks>STANDARD</tlsChecks>
<truststore>
<password>changeit</password>
<path><hivemq_edge>/conf/certs/truststore.jks</path>
</truststore>
</tls>
<uri><connection_address></uri>
<id>prosys-server</id>
</config>
</northboundMappings/>
<southboundMappings/>
</protocol-adapter>
</protocol-adapters>
</hivemq> Section 5: Trust Client Certificate for Application Authentication
While Section 2 established a one-way trust from HiveMQ Edge to the Prosys server, we must now complete the handshake. This section outlines how to configure the Prosys server to recognize and trust HiveMQ Edge for secure application authentication.
Steps:
Copy the HiveMQ Edge .edgelic file into <hivemq edge>/license.
Start HiveMQ Edge service.
Observe hivemq.log:
2026-02-11 14:22:09,222 ERROR - Connection failed for OPC UA adapter 'prosys-server'
java.lang.RuntimeException: UaException: status=Bad_SecurityChecksFailed, message=UaException: status=Bad_SecurityChecksFailed, message=An error occurred verifying security.
at com.hivemq.edge.adapters.opcua.OpcUaClientConnection.lambda$start$1(OpcUaClientConnection.java:144)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1310)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1841)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1806)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
Caused by: org.eclipse.milo.opcua.stack.core.UaException: UaException: status=Bad_SecurityChecksFailed, message=An error occurred verifying security.
at org.eclipse.milo.opcua.sdk.client.OpcUaClient.connect(OpcUaClient.java:500)
at com.hivemq.edge.adapters.opcua.OpcUaClientConnection.lambda$start$1(OpcUaClientConnection.java:142)
... 7 common frames omitted
Caused by: org.eclipse.milo.opcua.stack.core.UaException: status=Bad_SecurityChecksFailed, description=An error occurred verifying security.
at org.eclipse.milo.opcua.stack.transport.client.uasc.UascClientMessageHandler.onError(UascClientMessageHandler.java:525)
at org.eclipse.milo.opcua.stack.transport.client.uasc.UascClientMessageHandler.decode(UascClientMessageHandler.java:273)
at io.netty.handler.codec.ByteToMessageCodec$1.decode(ByteToMessageCodec.java:42)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:530)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:469)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:354)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1429)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:168)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.handle(AbstractNioChannel.java:445)
at io.netty.channel.nio.NioIoHandler$DefaultNioRegistration.handle(NioIoHandler.java:388)
at io.netty.channel.nio.NioIoHandler.processSelectedKey(NioIoHandler.java:596)
at io.netty.channel.nio.NioIoHandler.processSelectedKeysOptimized(NioIoHandler.java:571)
at io.netty.channel.nio.NioIoHandler.processSelectedKeys(NioIoHandler.java:512)
at io.netty.channel.nio.NioIoHandler.run(NioIoHandler.java:484)
at io.netty.channel.SingleThreadIoEventLoop.runIo(SingleThreadIoEventLoop.java:225)
at io.netty.channel.SingleThreadIoEventLoop.run(SingleThreadIoEventLoop.java:196)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:1193)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at java.base/java.lang.Thread.run(Thread.java:1583)
2026-02-11 14:22:09,224 ERROR - Failed to start writing for adapter with id prosys-server because the status is ERROR.
2026-02-11 14:22:09,227 WARN - OPC UA adapter 'prosys-server' connection returned false, will retry in 30000 milliseconds
Let's verify the certificate that the Prosys Server rejected:
ls -la ~/.prosysopc/prosys-opc-ua-simulation-server/PKI/CA/rejected/
Output similar to --> 86A7A97D1D07DB44452F76B9A9989F6DF29A5CDE.der 4. Enable the Prosys server to trust HiveMQ Edge by migrating its certificate into the trusted folder:
mv ~/.prosysopc/prosys-opc-ua-simulation-server/PKI/CA/rejected/*.der \
~/.prosysopc/prosys-opc-ua-simulation-server/PKI/CA/certs/ 5. Restart the Prosys Server to load the trusted certificate.
Section 6: Trust Client Certificate for User Authentication
Now that the Prosys server recognizes the HiveMQ Edge application, we need to authorize the user.
We will follow a similar workflow (Section 5) to trust the user certificate and enable X.509-based authentication.
Steps:
1. First, let's ensure that the Certificate user authentication method is enabled in the Prosys Server:
2. Restart the HiveMQ Edge service and observe hivemq.log for the new error:
2026-02-12 14:19:06,190 ERROR - Connection failed for OPC UA adapter 'prosys-server'
java.lang.RuntimeException: UaException: status=Bad_IdentityTokenRejected, message=UaServiceFaultException: status=Bad_IdentityTokenRejected, message=The user identity token is valid but the server has rejected it. 3. Let's verify the certificate that the Prosys Server rejected:
ls -la ~/.prosysopc/prosys-opc-ua-simulation-server/USERS_PKI/CA/rejected/
Output similar to --> 86A7A97D1D07DB44452F76B9A9989F6DF29A5CDE.der 4. Move the rejected certificate:
mv ~/.prosysopc/prosys-opc-ua-simulation-server/USERS_PKI/CA/rejected/*.der \
~/.prosysopc/prosys-opc-ua-simulation-server/USERS_PKI/CA/certs/ 5. Restart the Prosys Server to load the trusted certificate.
Section 7: Verify Successful Connection
Steps:
1. After restarting Prosys, check HiveMQ Edge logs:
2026-02-12 14:48:47,303 INFO - Successfully started adapter with id prosys-server
2026-02-12 14:48:47,303 INFO - OPC UA client of protocol adapter 'prosys-server' connected: OpcUaSession{sessionId=NodeId{ns=1, id=38a5acd4-8b32-47b1-9ae0-69f223378dfd}, sessionName=HiveMQ Edge prosys-server}
2026-02-12 14:48:47,308 INFO - All monitored items synchronized successfully
2026-02-12 14:48:47,308 INFO - Client created and connected successfully
2026-02-12 14:48:47,308 INFO - OPC UA adapter 'prosys-server' connected successfully 2. Check Prosys logs:
tail -f ~/.prosysopc/prosys-opc-ua-simulation-server/log/simulationserver.log | grep -i session
02/12/2026 14:51:47.658 INFO [OPC-UA-Stack-Blocking-Work-Executor-3] com.prosysopc.ua.server.ad [] - Session created: HiveMQ Edge prosys-server (ID=ns=1;g=d9d9b5b3-18d4-40d4-bfcc-8924eb6bb7e3 Token=b=8syUjVbSobFEJnJKwmSHyhJ8uoBs6qf5Ci0lSaAJXX4= Channel=(SecureChannelId=10 State=Open URL=opc.tcp://Mac.lan:53530/OPCUA/SimulationServer SecurityPolicy=http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 RemoteAddress=/192.168.1.162:55818)) How to Configure Northbound Data Flow from Prosys OPC-UA to HiveMQ Edge
Having integrated HiveMQ Edge and established a successful connection to Prosys OPC UA, the next phase of your IIoT architecture is to enable the Northbound data flow (Prosys OPC UA → HiveMQ Edge).
“Northbound” refers to the direction of data moving from the field level (edge) to the management/broker level systems (HiveMQ Edge). In HiveMQ Edge, this is achieved by mapping OPC UA nodes to MQTT topics.
Section 8: Review Prosys Server Built-In Simulators
A neat feature with the Prosys server is that it comes pre-installed with dynamic data tags. Sample tag types include: constant, counter, random, sawtooth, sinusoid, square, and triangle waves. For our implementation, we will use Random.
Steps:
1. Open the Prosys server simulation application and navigate to the Objects tab:
Feel free to browse around to see what kind of data each tag produces.
2. Click on the Random variable and make note of the NodeId (ie. ns=3;i=1002).
Section 9: Configure HiveMQ Edge
Once the NodeId is identified, you can configure HiveMQ Edge to ingest data from Prosys nodes via your designated MQTT topics.
Steps:
1. Compose your HiveMQ Edge config.xml (<nodeid> to be supplemented):
</hivemq>
<protocol-adapters>
<protocol-adapter>
...
<tags>
<tag>
<name>Random</name>
<description></description>
<definition>
<node><nodeid></node>
</definition>
</tag>
</tags>
<northboundMappings>
<northboundMapping>
<tagName>Random</tagName>
<topic>factory/machine/north</topic>
<maxQos>0</maxQos>
<includeTagNames>true</includeTagNames>
<includeTimestamp>true</includeTimestamp>
<mqttUserProperties/>
<messageExpiryInterval>9223372036854775807</messageExpiryInterval>
</northboundMapping>
</northboundMappings>
...
</protocol-adapter>
</protocol-adapters>
</hivemq> 2. Restart HiveMQ Edge service
Section 10: Verify Northbound Data Flow
Now that the setup is finished, all thatʼs left is to run a final test.
Steps:
1. Subscribe to the topic defined in config.xml:
mqtt sub -i testclient -t 'factory/machine/north' 2. The Random tag on the Prosys server will now begin publishing telemetry data to HiveMQ Edge:
{
"timestamp" : 1771021379340,
"value" : -1.582064,
"tagName" : "Random"
}
{
"timestamp" : 1771021380337,
"value" : 1.308561,
"tagName" : "Random"
}
{
"timestamp" : 1771021381337,
"value" : 1.65542,
"tagName" : "Random"
}
{
"timestamp" : 1771021382340,
"value" : 0.5460448,
"tagName" : "Random"
} How to Configure Southbound Data Flow from HiveMQ Edge to Prosys OPC-UA
Now that you have been well acquainted with Northbound, let's explore its counterpart: the Southbound data flow (HiveMQ Edge → Prosys OPC UA).
“Southbound” refers to the direction of data moving from management/broker level systems (HiveMQ Edge) down to field devices, sensors, and PLCs.
Section 11: Review Prosys Server Built-In Simulators
In the Northbound tutorial, we utilized the Random data tag. For demonstrative purposes, this time we will use Constant.
Steps:
1. Open the Prosys server simulation application and navigate to the Objects tab:
2. Click on the Constant variable and make note of the NodeId (ie. ns=3;i=1007).
Section 12: Configure HiveMQ Edge
After identifying the NodeId, HiveMQ Edge can be configured to forward received MQTT traffic from defined topics to the appropriate node.
Steps:
1. Compose your HiveMQ Edge config.xml (make note of <NodeId> to be supplemented)
</hivemq>
<protocol-adapters>
<protocol-adapter>
...
<tags>
<tag>
<name>Constant</name>
<description></description>
<definition>
<node><NodeId></node>
</definition>
</tag>
</tags>
<northboundMappings/>
<southboundMappings>
<southboundMapping>
<topicFilter>factory/machine/south</topicFilter>
<tagName>Constant</tagName>
<fieldMapping>
<instructions>
<instruction>
<source>$.value</source>
<destination>$.value</destination>
</instruction>
</instructions>
</fieldMapping>
<fromNorthSchema><![CDATA[
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"value": {
"type": "number"
}
},
"required": [ "value" ],
"additionalProperties": false
}
]]></fromNorthSchema>
</southboundMapping>
</southboundMappings>
...
</protocol-adapter>
</protocol-adapters>
</hivemq> 
2. Restart HiveMQ Edge service.
Section 13: Verify Southbound Data Flow
With the configuration finalized, the remaining task is to verify the setup through testing.
Steps:
1. Go back into Prosys, navigate to the Objects tab and observe the value for the Constant variable:
2. Publish to the topic defined in config.xml:
mqtt pub -t 'factory/machine/south' -m '{"value":2.0}' The Constant value should now reflect the value published from HiveMQ Edge.
Conclusion
With bidirectional communication now established between the Prosys OPC UA Simulation Server and HiveMQ Edge, you've validated the full integration in a test environment. It's worth emphasizing that the Prosys OPC UA Simulation Server used throughout this guide is intended for development and testing purposes only and should not be deployed in production environments. For production-grade deployments, Prosys OPC UA Forge is the recommended solution as it provides the enterprise-level reliability and feature set that industrial environments demand.
Gil Guadana
Gil Guadana is a Senior Support Engineer at HiveMQ with over 20 years of experience supporting Enterprise software. His career has spanned the tech hubs of Canada and Europe—including Malta, Switzerland, and the Netherlands. Gil’s technical repertoire includes extensive work with Java applications, SQL databases, IdPs (RBAC) and orchestrated environments across AKS, EKS, and ARO. Today, he specializes in deep-dive: MQTT troubleshooting, secure deployments, and providing customer-centric guidance within the modern DevOps ecosystem.
Miguel Arregui
Miguel Arregui is a Senior Software Engineer at HiveMQ, based in Castellón, Spain. He's working on the protocol layer of HiveMQ Edge — concurrency, persistence, and the OPC UA adapter exercised against the Prosys Simulation Server. His two decades of prior work span big-science instrumentation at CERN's ALICE experiment and the European Space Agency, bioinformatics text-mining at EBI/EMBL Cambridge (seven peer-reviewed publications, one in Nature Biotechnology), tier-1 investment-bank infrastructure at RBS and UBS, and deep-tech database startups CrateDB and QuestDB.
