Get OPC UA Security Right the First Time, Before It Ever Reaches MES

Engineer configuring OPC UA server security settings on an industrial control panel

Every controls engineer who’s dealt with OPC UA long enough has a version of the same story: a connection that worked fine for weeks, or months, and then just stops. No alarm, no obvious fault on the PLC side, just a client that silently fails to reconnect. Nine times out of ten, the root cause traces back to something that was set up wrong, or set up as a shortcut, during initial onboarding — a certificate that was trusted manually instead of through a proper chain, a security policy picked because it was the default, a user token configuration that happened to work in the moment but wasn’t built to survive a certificate rotation or a firmware update.

This is the preventive companion to that problem. Instead of walking through how to fix the 2 AM cert failure, this is about not creating it in the first place. With CISA’s Known Exploited Vulnerabilities catalog driving faster patch cycles, and Secure by Demand language increasingly baked into OT procurement contracts, plant teams are standing up more OPC UA endpoints, more often, under tighter security expectations than they were even a year or two ago. Getting the onboarding sequence right matters more now because there’s simply more of it happening, and less tolerance for waving through an insecure default “just to get it running.”

Start with the security policy, not the certificate

The instinct on most onboarding tickets is to jump straight to certificates — generate one, trust one, done. That’s backwards. The certificate only matters in the context of the security policy and message security mode the endpoint is actually going to use, and that decision should be made deliberately, not inherited from whatever the server shipped with.

OPC UA defines several standard security policies — Basic256Sha256, Aes128Sha256RsaOaep, Aes256Sha256RsaPss, and the deprecated Basic128Rsa15 and Basic256 policies that most current guidance says to retire outright. If your server or client stack still lists Basic128Rsa15 as an available option, that’s a flag to disable it at the endpoint, not just avoid selecting it. An endpoint that offers a weak policy is an endpoint an attacker — or a misconfigured client — can still negotiate down to.

Pick the strongest policy both the OPC UA server and the MES connector genuinely support, set the message security mode to Sign & Encrypt rather than Sign-only or None, and confirm that decision in writing as part of the onboarding record. “None” mode has legitimate uses in isolated test rigs. It should never survive the trip to a production network.

Match the endpoint to what the MES connector can actually negotiate

This is where a lot of quiet failures get seeded. Many MES OPC UA client libraries — whether embedded in a historian connector, an MES gateway module, or a UA-to-MQTT bridge — support a narrower set of policies than the server does. If the server is configured to only offer Aes256Sha256RsaPss and the MES client library was built against an older UA stack that tops out at Basic256Sha256, the connection may still establish during commissioning testing (if the tester happens to pick a compatible profile) and then break the moment someone “tightens” the server later, or a patch changes the default offered policy order. Confirm supported policies on both ends before you configure anything, not after the connection is already live.

Build the trust chain deliberately, not by clicking “accept”

OPC UA application instance certificates are not user certificates and they’re not TLS certificates in the browser sense — they identify the specific application instance (the server or client software instance, tied to its host), and trust between two OPC UA endpoints is established by explicitly exchanging and trusting those certificates, ideally through a proper certificate authority and trust list rather than by clicking “trust” on a self-signed cert during commissioning.

  • Use a real CA hierarchy where the vendor stack supports it. Many OPC UA servers and MES platforms support a Global Discovery Server or at least a managed trust list. If yours does, use it instead of ad hoc self-signed trust.
  • Check the certificate’s Subject Alternative Name against the actual hostname or IP the MES client will connect to. A mismatch here is one of the most common causes of connections that fail specifically after a DNS change, a server migration, or a network re-IP — the exact kind of change that happens long after the person who did the original onboarding has moved to another project.
  • Record certificate expiry dates somewhere the MES admin team actually looks — not just in the OPC UA server’s own certificate store. A calendar reminder or asset-management entry beats discovering an expired cert when the connection drops.
  • Reject self-signed certificates as a long-term posture, even when they’re convenient for a quick proof-of-concept. If the connection is going to production, it should be on a trust chain someone can actually manage and rotate.

Don’t forget the reverse direction

Trust in OPC UA is mutual. The server has to trust the MES client’s application certificate just as much as the client has to trust the server’s. It’s common to see engineers carefully configure the server side and then let the MES client auto-accept whatever certificate it’s presented — which defeats the purpose. Both trust lists need to be populated deliberately, and both need the same discipline around chain validation and revocation checking.

Get user token authentication right, separate from transport security

Transport-level security (the policy and mode discussed above) and user authentication are two different layers, and OPC UA gives you options: anonymous, username/password, and X.509 certificate-based user tokens. Anonymous access with encryption might be acceptable in a tightly segmented cell network; it’s a poor choice for anything touching a plant-wide MES integration. Username/password over an encrypted channel is the common middle ground, but it only works if credentials are unique to the MES service account, not shared with an engineering workstation login, and are stored in whatever secrets management your MES platform supports rather than hardcoded in a connector config file.

If the server supports certificate-based user authentication, it’s worth the extra setup effort for anything classified as a critical process line — it removes password rotation as a recurring failure point and aligns cleanly with IEC 62443 zone-and-conduit thinking about who’s allowed to talk to what.

The pre-go-live checklist

Before handing a newly onboarded OPC UA server and its tag set to production, run through this list. It’s short on purpose — the goal is a five-minute gate check, not a new bureaucratic process.

  1. Confirm the security policy in use is not Basic128Rsa15 or Basic256, and that weaker policies are disabled at the endpoint, not just unselected.
  2. Confirm message security mode is Sign & Encrypt, and that “None” mode was only ever used on an isolated test network.
  3. Verify the MES client library’s supported policy list actually overlaps with what the server offers — don’t assume compatibility just because a test connection succeeded once.
  4. Check that the server’s application instance certificate has a Subject Alternative Name matching the real production hostname/IP, not a test environment value.
  5. Confirm mutual trust: the server trusts the MES client certificate and the MES client trusts the server certificate, both through a managed trust list or CA rather than a manual one-off “accept.”
  6. Confirm the MES service account used for the user token is dedicated, not shared, and is stored per your platform’s secrets-management practice.
  7. Log certificate expiry dates in an asset or maintenance system with a reminder well ahead of expiry — not just inside the OPC UA server’s certificate manager.
  8. Document the final configuration (policy, mode, token type, cert thumbprints) in the handoff package so the next engineer who touches this connection isn’t reverse-engineering it during an incident.

None of this is exotic. It’s the same handful of settings, checked in the same order, every time. The reason it doesn’t happen consistently isn’t complexity — it’s that onboarding tends to get compressed under go-live pressure, and security configuration is the part that’s invisible right up until it isn’t. Building this checklist into the standard tag-onboarding runbook, rather than treating it as a separate cybersecurity task bolted on afterward, is what actually keeps it from getting skipped.

The connections that “just work” for years are, almost without exception, the ones where somebody took the extra twenty minutes at commissioning to get the trust chain and policy selection right instead of accepting whatever default got the demo running. That twenty minutes is a lot cheaper than the diagnostic session weeks later trying to figure out why a client that’s worked fine since installation suddenly can’t reconnect.


This article was written with the assistance of artificial intelligence. While we aim for accuracy, the information may be incomplete, out of date, or incorrect, and should be independently verified before you rely on it for any decision. It is provided for general information only and does not constitute professional advice.

Related posts