OPC UA (OPC Unified Architecture) is the industrial interoperability standard that lets PLCs, gateways, SCADA, MES and cloud services exchange typed, self-describing data and commands over one service model, with security built into the protocol. It is published by the OPC Foundation as the OPC 10000 series and by the IEC as IEC 62541, and it runs mainly over TCP port 4840 using the opc.tcp scheme.
This post covers the information model, how a connection goes from Hello to SecureChannel to Session, what security modes and policies mean, how certificates and trust lists decide who may talk, and how PubSub (Part 14) is secured. Then it covers the weakness classes the specification lists, defender side checks, and OPC UA versus MQTT and Modbus. A shorter post covers what the MQTT and OPC UA specs say about security; this one is the full protocol deep dive.
Key takeaways
- OPC UA is an application layer protocol. IANA registers 4840/tcp (
opcua-tcp), 4840/udp (opcua-udp) and 4843/tcp (opcua-tls). It also runs over HTTPS and WebSockets, and PubSub adds UDP, raw Ethernet, MQTT and AMQP. - Unlike register based protocols, a server exposes a browsable address space of typed nodes linked by references, so clients learn what values mean.
- A client sends Hello, opens a SecureChannel, then creates and activates a Session. Applications authenticate with X.509 certificates on the channel; users authenticate on the session.
- The security modes are None, Sign and SignAndEncrypt. Part 2 says profile None, which provides no security, "shall be disabled by default".
- The OPC Foundation's reference stack lists Basic256 and Basic128Rsa15 as deprecated (SHA-1) and supports Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss and ECC policies.
- Trust comes from administrator managed trust lists. Auto accepting unknown certificates defeats the model.
- PubSub uses shared keys from a Security Key Service, so every member of a SecurityGroup can both read and publish.
What OPC UA is for, the layer and the standard
The problem it solves
Plants are full of devices from different vendors that must share data with each other and with business systems. OPC Classic solved part of this on Windows using Microsoft COM. The OPC Foundation describes OPC UA, "released in 2008", as a platform independent, service oriented architecture that folds the OPC Classic specifications into one framework, and Part 1 calls it the migration path for COM based OPC products. Part 1 says OPC UA specifies an information model, a message model, a communication model and a conformance model, for everything from sensors up to MES and ERP systems.
How the information model differs from register based protocols
In Modbus, a client reads holding register 40001 and has to know from a separate document that it holds, say, a pump speed in tenths of a percent. OPC UA moves that meaning into the protocol.
A server exposes an AddressSpace made of Nodes. Each Node belongs to a NodeClass (Object, Variable, Method, ObjectType, VariableType, ReferenceType, DataType or View) and has attributes such as an identifier, names and, for variables, a typed value. Nodes are connected by References, which Part 1 defines as "an explicit relationship (a named pointer) from one Node to another". Because servers expose type definitions, a client can discover that a node is a pump, find its speed variable with engineering units and call its start method without vendor documentation. Companion specifications standardise such types for machine tools, robotics and other domains.
For security this matters in two ways. A rich, browsable model helps anyone mapping a plant, which is why the specification lists "server profiling" as a threat. And because methods and writable variables carry real control authority, authorisation has to be designed per node, not just per connection.
Where it sits in the stack
OPC UA is an application layer protocol with its own secure messaging layer. For client and server communication, Part 2 describes three layers: an application layer where Sessions carry user authentication and authorisation, a communication layer where the SecureChannel provides confidentiality, integrity and application authentication, and a transport layer below that. The native mapping is OPC UA Binary encoding inside OPC UA Secure Conversation (UASC) inside the OPC UA Connection Protocol (UACP) over TCP. Part 6 also defines HTTPS and WebSocket mappings and three data encodings: UA Binary, XML and JSON.
Everything in TCP explained: handshake, state machine and hardening about the transport underneath applies to opc.tcp connections.
The defining standards
The OPC Foundation publishes the specification as the OPC 10000 series, and its online reference at reference.opcfoundation.org is the version this post cites. The IEC publishes OPC UA as the IEC 62541 series.
| Part | Title | Current release on the OPC Foundation reference site | Earliest release listed there |
|---|---|---|---|
| OPC 10000-1 | Overview and Concepts | 1.05.06, 22 October 2025 | Not checked |
| OPC 10000-2 | Security Model | 1.05.06, 22 October 2025 | 1.04, 3 August 2018 |
| OPC 10000-4 | Services | 1.05.07, 15 April 2026 | 1.04, 22 November 2017 |
| OPC 10000-6 | Mappings | 1.05.07, 15 April 2026 | 1.04, 22 November 2017 |
| OPC 10000-7 | Profiles | 1.05.02, 1 November 2022 | Not checked |
| OPC 10000-12 | Discovery and Global Services | 1.05.07, 15 April 2026 | Not checked |
| OPC 10000-14 | PubSub | 1.05.06, 22 October 2025 | 1.04, 6 February 2018 |
On the IEC side, the IEC webstore lists IEC TR 62541-1:2020 (edition 3.0, published 18 November 2020) as replaced by IEC 62541-1:2025, with a withdrawal date of 13 January 2026. The reference site states that the official OPC Foundation documents take precedence if the website differs from them.
Two organisational points matter for security. Part 7 says the Profiles, including security policies, "are maintained in an online database" at profiles.opcfoundation.org, so algorithm sets change faster than the documents. And Part 2 says a site's OPC UA security requirements "are specified by the site, not by the OPC UA specification": the standard provides mechanisms, and your security programme decides which to switch on.
How OPC UA works on the wire
Discovery: how a client finds an endpoint
Before connecting, a client needs an endpoint: a URL plus the security settings the server will accept there. Every server implements the Discovery Service Set from Part 4, including GetEndpoints, which returns a list of EndpointDescriptions. Each EndpointDescription carries:
| Field | Meaning |
|---|---|
| endpointUrl | For example opc.tcp://host:4840/path |
| server | The server's ApplicationDescription |
| serverCertificate | The server's application instance certificate |
| securityMode | None, Sign or SignAndEncrypt |
| securityPolicyUri | The algorithm suite, for example http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 |
| userIdentityTokens | Which user token types the server accepts on this endpoint |
| transportProfileUri | Which transport and encoding mapping |
| securityLevel | A byte ranking this endpoint against the server's others. Part 4 says 0 means "not recommended and is only supported for backward compatibility" |
On a single machine, a Local Discovery Server (LDS) can list the servers on that host. Part 6 gives its well known addresses as opc.tcp://localhost:4840/UADiscovery, opc.wss://localhost:443/UADiscovery and opc.https://localhost:443/UADiscovery. Part 12 adds a multicast extension (LDS-ME) that uses mDNS, and a Global Discovery Server (GDS) for whole sites.
UACP: Hello, Acknowledge, Error and ReverseHello
Every UACP message starts with the same 8 byte header, which Part 6 deliberately makes identical to the first 8 bytes of a secure conversation message so the transport layer can pull messages out of the stream without understanding them.
| Field | Size | Contents |
|---|---|---|
| MessageType | 3 bytes, ASCII | HEL Hello, ACK Acknowledge, ERR Error, RHE ReverseHello; the secure layer adds OPN, MSG and CLO |
| Reserved / IsFinal | 1 byte, ASCII | F for UACP messages |
| MessageSize | UInt32 | Length of the whole message including these 8 bytes |
The Hello message adds ProtocolVersion (0 for this version), ReceiveBufferSize, SendBufferSize, MaxMessageSize, MaxChunkCount and the EndpointUrl. Buffer sizes must be at least 8,192 bytes, or 1,024 bytes for ECC policies, and the EndpointUrl must be under 4,096 bytes. Hello and Acknowledge are sent once, and a server must close a connection that sends no Hello within a configurable time whose default does not exceed two minutes.
ReverseHello flips the TCP direction. Part 6 says it "allows Servers behind firewalls with no open ports to connect to a Client", which then sends a normal Hello over that socket. It is the documented way to reach a server in a protected cell without an inbound port.
UASC: the SecureChannel message layout
Once UACP has negotiated buffer sizes, OPC UA Secure Conversation carries everything else. UASC splits each OPC UA message into MessageChunks that fit the negotiated buffer, and Part 6 is explicit that "all security is applied to individual MessageChunks and not the entire OPC UA Message".
| Section | Fields | Notes |
|---|---|---|
| Message header | MessageType (OPN, MSG, CLO), IsFinal (C intermediate, F final, A abort), MessageSize, SecureChannelId | SecureChannelId is assigned by the server |
| Security header, asymmetric (OPN only) | SecurityPolicyUri (up to 255 bytes), SenderCertificate (DER, may include chain), ReceiverCertificateThumbprint (20 byte SHA-1 thumbprint) | Tells the receiver which policy and keys are in use |
| Security header, symmetric (MSG, CLO) | TokenId | Identifies the channel's current SecurityToken |
| Sequence header | SequenceNumber, RequestId | SequenceNumber increases by exactly one per chunk and is used to detect replay |
| Body | UA Binary encoded service request or response | May span several chunks |
| Footer | Padding and signature, or an authenticated encryption tag | Depends on mode and policy |
The OpenSecureChannel request carries RequestType (issue or renew), SecurityMode, a ClientNonce and a RequestedLifetime; the response returns the SecureChannelId, a TokenId, a RevisedLifetime in milliseconds and a ServerNonce. Both sides derive symmetric keys from the nonces, the client renews before the lifetime expires, and a sequence number may never be reused for the same TokenId.
One detail people get wrong: Part 6 says the OpenSecureChannel messages "are signed and encrypted if the SecurityMode is not None (even if the SecurityMode is Sign)". Sign mode only skips encryption for the later symmetric messages.
A connection from start to finish
Client Server (opc.tcp, port 4840)
| |
|---- TCP handshake -------------------------------->|
|---- HEL (protocol version, buffer sizes, URL) --->|
|<--- ACK (agreed buffer sizes, limits) ------------|
| |
|---- OPN OpenSecureChannel request --------------->| asymmetric: client cert,
| (mode, policy URI, client nonce) | signed and encrypted unless None
|<--- OPN OpenSecureChannel response ---------------| server validates client cert
| (channel id, token id, server nonce) | against its trust list
| |
| both sides derive symmetric keys from nonces |
| |
|---- MSG CreateSession (client cert, nonce) ------>|
|<--- MSG CreateSession response -------------------| server signs client cert+nonce;
| (server cert, endpoints, nonce, sig) | client compares endpoints list
|---- MSG ActivateSession (user identity token, --->| user authentication happens here
| client signature) ------------------------|
|<--- MSG ActivateSession response -----------------|
| |
|---- MSG Browse / Read / Write / Call ------------>| steady state
|---- MSG CreateSubscription, Publish ------------->|
|<--- MSG Publish responses (notifications) --------|
| |
|---- OPN renew token before lifetime expires ----->|
| |
|---- MSG CloseSession ---------------------------->|
|---- CLO CloseSecureChannel ---------------------->|
|---- TCP FIN -------------------------------------->|
Sessions and the service sets
A Session lives in the application layer and runs over a SecureChannel. Part 4 says client and server "shall prove possession of their ApplicationInstanceCertificates by signing the Certificates with a nonce appended" during CreateSession, and the client proves its user identity in ActivateSession. Part 2 notes that the binding is flexible: if the SecureChannel breaks, the Session stays valid for a while so the client can reattach it over a new channel, and ActivateSession can change the user that owns a session.
After activation, the client uses the Part 4 service sets: View (Browse), Attribute (Read, Write, HistoryRead), Method (Call), MonitoredItem and Subscription (the server pushes notifications in Publish responses), and NodeManagement (AddNodes, DeleteNodes). Part 4 also defines session-less invocation with an access token per request, which Part 2 restricts to encrypted channels.
Ports, schemes and registrations
| What | Value | Source |
|---|---|---|
| Binary over TCP | opc.tcp://, 4840/tcp (opcua-tcp) | Part 6, IANA |
| TCP over TLS | 4843/tcp (opcua-tls) | IANA |
| WebSockets and HTTPS | opc.wss://, opc.https:// | Part 6 |
| PubSub over UDP | opc.udp://, 4840/udp, discovery multicast 224.0.2.14 | Part 14, IANA |
| PubSub over Ethernet | opc.eth://, EtherType 0xB62C | Part 14 |
| PubSub over MQTT with TLS | mqtts://, default 8883 | Part 14 |
Many products use other TCP ports for their own endpoints, so inventory by scheme and listening process, not only by port 4840.
Versions and history
From OPC Classic to 1.04
OPC Classic tied industrial data exchange to Windows and DCOM. OPC UA, released in 2008 according to the OPC Foundation, replaced that with a platform independent service model and its own security layer. The early specification also defined a SOAP/HTTP mapping based on WS-SecureConversation; Part 6 now marks it "Deprecated in Version 1.03 because WS-SecureConversation has not been widely adopted by industry".
The 1.04 releases are the oldest ones on the online reference site: Parts 4 and 6 are dated 22 November 2017, Part 14 (PubSub) 6 February 2018 and Part 2 3 August 2018. Part 14 is the earliest PubSub document the site lists, and it brought the broker-less UDP and Ethernet mappings, the broker based MQTT and AMQP mappings and the Security Key Service model described below.
The 1.05 line
The 1.05 releases are current: 1.05.06 for Parts 1, 2 and 14 (22 October 2025) and 1.05.07 for Parts 4, 6 and 12 (15 April 2026). Security relevant content in the current text includes:
- ECC policies. Part 6 clause 6.8 defines an ECC handshake with ephemeral keys, and Part 2 says the SecureChannel provides perfect forward secrecy only "when the SecureChannel is used with Elliptic Curve Cryptography (ECC) and the Diffie Hellman Key Exchange".
- Authenticated encryption chunk layouts for AEAD algorithms.
- SecureChannel enhancements. New policy fields add channel bound signatures in CreateSession and ActivateSession and chained key derivation on renewal;
CertificateThumbprintAlgorithmdefaults to SHA-1 when unspecified. - Roles and OAuth2. Standard roles (SecurityAdmin, ConfigureAdmin, Supervisor, Engineer, Operator, Observer, AuthenticatedUser) can be assigned through OAuth2, with JWT access tokens mapped in Part 6.
- Deprecations. The Query service set (1.05.06) and the SoftwareCertificates parameter in CreateSession responses.
What is still deployed
Plants run equipment for decades, so 1.05 servers sit next to older devices that only offer legacy RSA policies, and OPC Classic servers reached through wrappers. The useful question is not which version a vendor claims but which modes and policies each endpoint accepts today.
Security modes and security policies
The three security modes
The MessageSecurityMode enumeration in Part 4 has four values:
| Name | Value | Meaning |
|---|---|---|
| INVALID | 0 | Default, "to avoid an accidental choice of no security"; always rejected |
| NONE | 1 | No security is applied |
| SIGN | 2 | All messages are signed but not encrypted |
| SIGNANDENCRYPT | 3 | All messages are signed and encrypted |
Part 2 adds the rules: mode None can only be used with security profile None, and "Profile None shall be disabled by default". Whether Sign is enough is a site decision; Part 2 says "in some applications where data confidentiality is not required, 'Sign' is sufficient". Sign gives integrity and application authentication but leaves process values readable. Mode None goes further than skipping encryption: Part 6 says nonces are ignored and no certificate exchange secures the channel, so the server has no cryptographic idea which application is talking to it.
What a security policy contains
A security policy is a named, URI identified set of algorithms used together. Part 6 Table 49 lists its contents: symmetric and asymmetric signature and encryption algorithms, minimum and maximum key lengths, key derivation, certificate signature and key algorithms, the ephemeral key algorithm for ECC, nonce and signature lengths, and the newer enhancement flags. Part 2 explains why the list changes: "specific algorithms that are considered as secure today can become insecure in the future", so sites should check during periodic reviews that their selected profiles still meet their objectives.
Which policies are current and which are deprecated
The normative list lives in the online Profiles database, which is a JavaScript application that could not be read directly for this post. The OPC Foundation's UA .NET Standard reference stack documents the following:
| Policy URI suffix | Family | Status in the reference stack documentation |
|---|---|---|
#None | No security | "For testing or isolated networks only" |
#Basic128Rsa15 | RSA, SHA-1, RSA PKCS#1 v1.5 | Deprecated, legacy compatibility only |
#Basic256 | RSA, SHA-1 | Deprecated, legacy compatibility only |
#Basic256Sha256 | RSA, AES-256, RSA-OAEP, HMAC-SHA256, minimum 2048 bit keys | Supported |
#Aes128_Sha256_RsaOaep | RSA, AES-128, RSA-OAEP, HMAC-SHA256 | Supported |
#Aes256_Sha256_RsaPss | RSA, AES-256, RSA-PSS, HMAC-SHA256 | Supported |
#ECC_nistP256, #ECC_nistP384, #ECC_brainpoolP256r1, #ECC_brainpoolP384r1 | ECC | Supported |
#ECC_curve25519, #ECC_curve448 and AES-GCM variants | ECC with AEAD | Supported in the newer stack line |
If a server still offers Basic128Rsa15 or Basic256, a client that accepts them can be steered onto them, which is the "downgrade attack" threat in Part 2.
Application instance certificates and trust lists
What an application certificate is
Every OPC UA application instance, client or server, has its own X.509 v3 certificate, DER encoded and conforming to RFC 5280. Part 6 Table 50 sets the rules:
- Subject must include a Common Name (normally the application name) and an Organization (the organisation that runs the instance, which is "usually not the vendor").
- subjectAltName must contain exactly one URI equal to the application's ApplicationUri. Servers must also include a DNS name or static IP address for the host.
- keyUsage for RSA keys must include digitalSignature, nonRepudiation, keyEncipherment and dataEncipherment; for ECC keys, digitalSignature. Self-signed certificates must also include keyCertSign.
- extendedKeyUsage for RSA profiles must include serverAuth for servers and clientAuth for clients.
- basicConstraints must be present, and the CA flag must be false for application certificates.
Part 4 says the private key "should be stored in a location that can only be accessed by the application". Self-signed certificates created at install are acceptable for "a few Clients connected to one Server"; beyond that Part 4 recommends CA based central management, and every application must let administrators replace its certificate.
How trust is decided
This is the heart of OPC UA security. Part 4 clause 6.1.3 opens with: "Applications shall never communicate with another application that they do not trust." A certificate is trusted only if its chain validates and the certificate, or at least one CA in its chain, is in the application's list of trusted certificates. A second list holds issuer (CA) certificates needed to build chains but not trusted on their own. Part 2 adds that trust lists which include CAs also include CRLs.
Validation follows a fixed order, and each step has its own error and audit event:
| Step | Error | Can it be suppressed? |
|---|---|---|
| Certificate structure | Bad_CertificateInvalid | No |
| Build certificate chain | Bad_CertificateChainIncomplete | No |
| Signature | Bad_CertificateInvalid | No |
| Security policy check (algorithm and key length) | Bad_CertificatePolicyCheckFailed | Yes |
| Trust list check | Bad_CertificateUntrusted | Applies to application certificates |
| Validity period | Bad_CertificateTimeInvalid | Yes |
| Host name (server certificates) | Bad_CertificateHostNameInvalid | Yes |
| Application URI | Bad_CertificateUriInvalid | No |
| Certificate usage | Bad_CertificateUseNotAllowed | Yes, unless marked mandatory |
| Find revocation list | Bad_CertificateRevocationUnknown | Yes |
| Revocation check | Bad_CertificateRevoked | No, if a list is found |
Part 4 says suppressed errors "are always reported via auditing", and that certificates are re-verified every time a SecureChannel's token is renewed. Revocation can be done by removing a certificate from every trust list or by adding it to the issuing CA's CRL.
In the OPC Foundation's .NET stack, this model shows up as directory stores under a pki folder: own for the application's keys, trusted, issuer, and rejected, where certificates that failed validation are copied "as a convenience for the administrator" so they can be reviewed and moved to trusted deliberately. The stack's AutoAcceptUntrustedCertificates setting defaults to false and its documentation says it "should not be used in production".
Global Discovery Server and certificate management (Part 12)
Managing trust lists by hand on every device does not scale. Part 12 defines a CertificateManager, usually combined with the Global Discovery Server, for onboarding, renewal, trust list and CRL updates, and revocation. In pull management the application acts as a client and requests certificates and trust lists itself; in push management it acts as a server and the CertificateManager calls methods such as UpdateCertificate on it.
Access is role based, with roles such as CertificateAuthorityAdmin (request or revoke any certificate, update any trust list), RegistrationAuthorityAdmin and SecurityAdmin. Part 12 warns that a client "shall not provide a secret (e.g. a password) to an untrusted CertificateManager". Automatic device onboarding is defined separately in OPC 10000-21.
Users, roles and the user identity tokens
Each endpoint's UserTokenPolicy lists the token types it accepts, and the client passes one in ActivateSession: ANONYMOUS (no user information), USERNAME (name and password), CERTIFICATE (an X.509 user certificate proven by signature) or ISSUEDTOKEN (a token from an authorization service, such as a JWT).
Passwords are where mode None does the most damage. Part 4 says that under security policy None the password travels as plain UTF-8, which "should not be used unless the network traffic is encrypted in some other manner such as a VPN" because it "would cause the appearance of a secure user access". A server can set a security policy on the UserTokenPolicy itself so the password is encrypted to its certificate even on an unsecured channel.
Authorisation is per node: Part 2 describes Roles mapped to Permissions, restrictable by user, application, security mode or transport. Give Anonymous at most read access to non sensitive nodes, and reserve Write and Call on control nodes for named roles over SignAndEncrypt endpoints.
PubSub (Part 14) and how it is secured
What PubSub is
PubSub lets a Publisher send DataSets to any number of Subscribers without a session; Part 14 says they "often will not even know each other". A DataSetWriter turns a DataSet into DataSetMessages packed into NetworkMessages. Broker-less mappings carry UADP binary messages over UDP (port 4840 by default, ideally within one MTU: 1,472 bytes of message for IPv4) or raw Ethernet with EtherType 0xB62C. Broker based mappings use MQTT (3.1.1 and 5.0) or AMQP with UADP or JSON bodies and topics such as opcua/json/status/FlowController1.
Message security and transport security
Message security is end to end from publisher to subscriber, defined entirely by OPC UA, at one of three levels: none, signing, or signing and encryption. Transport security belongs to the mapping, such as TLS to an MQTT broker. Part 14 warns that transport security "may be hop-by-hop security with some risk of man-in-the-middle attacks" and requires trusting the broker, which can read the messages. For MQTT, end to end security requires UADP binary encoding; JSON bodies rely on the broker. The MQTT 5 deep dive covers securing that broker hop.
Security Key Service and SecurityGroups
A Security Key Service (SKS) creates SecurityGroups, grants roles access to each group, and hands out rotating symmetric keys. Members pull keys with GetSecurityKeys over a secured client and server connection, or a central SKS pushes them with SetSecurityKeys, and Part 14 says key exchange must be retried "at a faster rate than the key lifetime".
Part 2 spells out the trade off: with shared keys "all of the applications in the group have the same rights". Its example is a controller publishing to three HMIs in one group; a compromised HMI can publish messages the others accept as the controller's. The suggested fix is narrower groups, such as one per controller and HMI pair, plus network controls.
Security properties: what OPC UA does and does not guarantee
Part 2 lists the security objectives OPC UA addresses. With a non-None policy and a correctly managed trust list, the SecureChannel provides:
| Property | Provided by | Caveats |
|---|---|---|
| Confidentiality | Symmetric encryption in SignAndEncrypt | Not in Sign or None |
| Integrity | Message signatures or AEAD per chunk | Not in None |
| Application authentication | Certificate exchange and trust list checks | Only as strong as trust list hygiene; HTTPS channels do not provide it |
| User authentication | User identity tokens in ActivateSession | Passwords exposed if sent under policy None without token encryption |
| Authorisation | Roles, permissions, access restrictions | Implementation and configuration specific |
| Replay detection | Sequence numbers, nonces, token lifetimes | Per channel |
| Auditability | Audit events, including certificate failures | Only if a client collects them |
| Perfect forward secrecy | ECC policies with ephemeral Diffie Hellman | Not with RSA only policies |
| Availability | Limits, timeouts, resource rules | Part 2 lists flooding and resource exhaustion as open threats |
OPC UA cannot protect a server whose administrator turned security off, a client that trusts every certificate, or a PubSub group with a compromised member. Germany's BSI commissioned an analysis carried out from January to December 2015; its summary says it found no systematic security flaws in the specification, while the reviewed OPC Foundation reference implementation had, among other findings, a vulnerability exploitable when security functions are switched off.
Weakness classes, explained as concepts
Part 2 clause 4.3 lists the threats, from flooding, eavesdropping, spoofing and replay to malformed messages, server profiling, session hijacking, rogue servers, publishers and discovery servers, credential compromise and downgrade. Most real exposure comes from configuration and implementation, not design.
SecurityMode None in production
A None endpoint is often left in place for an old HMI or for commissioning. Because clients choose among offered endpoints, any client can then open an unauthenticated, unencrypted channel, and with anonymous tokens and writable nodes that is unauthenticated control. Profile None is disabled by default; the risk is someone enabling it and never removing it.
Auto accepting certificates
Options to accept any unseen certificate are convenient during integration but turn application authentication into trust in anyone who can generate a certificate, so a rogue server or interceptor is accepted. Part 4's GetEndpoints guidance assumes the opposite: the client "shall verify that the ServerCertificate in the EndpointDescription is a trusted Certificate before it calls CreateSession".
Anonymous user tokens and weak authorisation
Anonymous is legitimate for read only dashboards, but when the anonymous identity can write variables or call methods, application authentication is the only control left, and with auto accept or mode None there is no control at all. Weakness here is usually in the role mapping, not the protocol.
Downgrade through discovery
Part 2 describes an attacker who modifies a discovery response "to remove security options from the available endpoints" so a client picks a weaker one. The specification's countermeasure is that the client compares the endpoint list from GetEndpoints with the list the server returns in the authenticated CreateSession response. Clients that skip that comparison, or servers that still offer deprecated policies, make the downgrade possible.
Rogue discovery and mDNS
Part 12 says multicast DNS operations "are insecure because of their nature" and should be disabled where an attacker could impersonate another host. A rogue LDS can point clients at the wrong server, hide real ones or make listed servers look less secure. Trust lists limit the damage: a client that only trusts known server certificates will not complete a session with an impostor.
Parser robustness and resource exhaustion
OPC UA has a large nested binary encoding, chunking and embedded certificate chains. Part 2's "malformed messages" threat notes that bad handling can crash an application or, in embedded devices, the whole device, and in the worst case serve as "a pre-step for a multi-level attack". Part 6 limits sizes in several places (SecurityPolicyUri up to 255 bytes, EndpointUrl under 4,096 bytes, negotiated chunk counts and message sizes) and requires receivers to close channels with invalid header lengths. Stacks that skip these limits or do heavy work before authenticating the peer are where denial of service and memory safety bugs live. The OPC Foundation publishes advisories in OASIS CSAF 2.0 format on GitHub, gives SDK vendors advance notice, and notes that many products can only be patched after the SDK they embed is fixed.
Secure configuration, with defender side check commands
Only run the commands below against systems you own or are authorised to test. Each comes from the official documentation or the usage text of the tool named, linked in Sources. Several of them make a real OPC UA connection, so run them from an engineering host that is allowed to reach the server, during a window your operations team agrees to.
1. Find every OPC UA listener
On a Linux host you administer, list listening TCP and UDP sockets with their owning processes (ss options from the ss(8) man page):
# TCP listeners with process names, numeric ports
ss -tlnp | grep -E ':(4840|4843)\b'
# UDP sockets, for PubSub over UDP on 4840
ss -ulnp | grep -E ':4840\b'
Do not stop at 4840; review every listener owned by an OPC UA server process, and note which interfaces each binds to. A server bound to all interfaces on a dual homed gateway may be reachable from a network it was never meant to serve.
2. List each server's endpoints, modes and policies
The open62541 project ships a small command line client in its source tree (tools/ua-cli) whose usage text documents a getendpoints service that prints a server's endpoint descriptions:
# From an authorised engineering host, against a server you run
ua opc.tcp://opcua-gw01.plant.example:4840 getendpoints
The OPC Foundation's UA .NET Standard ConsoleReferenceClient sample does the same job with a session. Its options are listed with the help flag, and it has a "Test All Endpoints" option:
dotnet ConsoleReferenceClient.dll -h
dotnet ConsoleReferenceClient.dll --testall opc.tcp://opcua-gw01.plant.example:4840
# Its options to auto accept certificates ("for testing only") and to
# select a security None endpoint exist for labs. Do not use them
# against production servers.
For each endpoint, record the security mode, the security policy URI, the user token types and the securityLevel. Flag any endpoint with mode None, policy #None, #Basic128Rsa15 or #Basic256, any ANONYMOUS token on an endpoint that also exposes writable nodes, and any endpoint with securityLevel 0.
3. Remove None and deprecated policies
Keep only SignAndEncrypt endpoints (Sign only where the site has decided integrity alone is enough) with Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss or ECC policies. Remove None and the SHA-1 policies. If a legacy client forces an old policy, isolate it on a separate endpoint, firewall it to that client and give it a retirement date. Re-run step 2 after every change and firmware update.
4. Inspect the certificates you trust and serve
OPC UA certificates are DER files. The openssl x509 command (options from the OpenSSL x509 manual) shows whether a certificate meets Part 6's rules:
openssl x509 -inform DER -in server_cert.der -noout -subject -issuer -enddate \
-ext subjectAltName,keyUsage,extendedKeyUsage,basicConstraints
# Exit status is non-zero if the certificate expires within 30 days
openssl x509 -inform DER -in server_cert.der -noout -checkend 2592000
# SHA-1 fingerprint, to compare with the thumbprint a client shows you
openssl x509 -inform DER -in server_cert.der -noout -fingerprint -sha1
Check that subjectAltName holds exactly one URI matching the ApplicationUri plus the right host names, that the key is at least 2,048 bits for RSA, that the signature algorithm is not SHA-1, and that basicConstraints marks it as not a CA. Then review the trusted store itself: every entry should map to an application you can name, and CA entries should come with current CRLs.
5. Turn off auto accept and review rejections
Set auto accept of untrusted certificates to off on every client and server; in the .NET stack this is AutoAcceptUntrustedCertificates, default false. Keep SHA-1 signed certificates rejected (RejectSHA1SignedCertificates, default true in that stack) and set a minimum key size (MinimumCertificateKeySize, default 2048). Decide deliberately whether certificates with unknown revocation status should be rejected (RejectUnknownRevocationStatus, default false); on isolated networks that requires distributing CRLs locally, which Part 4 explicitly allows. Treat the rejected store as an approval queue: move a certificate to trusted only after confirming its fingerprint with the owner of the application.
6. Fix user authentication and authorisation
Disable Anonymous on any endpoint that exposes writes or method calls. Prefer X.509 user certificates or issued tokens from a central identity provider over local passwords. If passwords remain, make sure they are only accepted over encrypted channels, or that the UserTokenPolicy specifies a security policy so the password is encrypted to the server. Map users to the standard roles and grant Write and Call only where an operator or engineer actually needs them.
7. Centralise certificates, discovery and keys
Use Part 12 push or pull management so renewal and trust list updates are routine rather than a site visit, and protect the CertificateManager and any PubSub SKS as tier zero infrastructure with CertificateAuthorityAdmin and SecurityAdmin roles held by a small group. Turn off LDS-ME multicast where clients can be given explicit server URLs. For PubSub, use message level signing and encryption (UADP binary over MQTT), small SecurityGroups, and multicast confined to the VLANs that need it.
8. Segment, limit and watch
NIST SP 800-82 Rev. 3, Guide to Operational Technology Security (September 2023, superseding Rev. 2 from 2015), recommends defence in depth including a DMZ that prevents direct traffic between corporate and OT networks, and MFA for remote access. CISA's joint guidance "Primary Mitigations to Reduce Cyber Threats to Operational Technology" (May 2025) says to remove OT connections to the public internet, change default passwords, secure remote access and segment IT from OT. For OPC UA: no endpoint reachable from the internet (use reverse connect or a DMZ server), firewall 4840 and 4843 to named clients, collect audit events and alert on new certificates in rejected stores, and set session and subscription limits.
The ISA/IEC 62443 series, whose ISA page describes it as requirements and processes for "electronically secure industrial automation and control systems", is the usual framework for deciding zones, conduits and required security levels around these servers. See IEC 62443 roles, zones, conduits and safety and IT vs OT security differences in NIST SP 800-82. The operating system under the gateway matters too; the Civil Infrastructure Platform industrial Linux explainer covers long term kernel and base system maintenance for these devices.
When to use OPC UA versus the alternatives
| Use case | OPC UA client/server | OPC UA PubSub over MQTT | Plain MQTT | Modbus TCP |
|---|---|---|---|---|
| Typical role | Structured access to device and system data, commands and methods | Fan out of OPC UA modelled data to many consumers, often to cloud | Lightweight telemetry from many devices through a broker | Simple register reads and writes to PLCs and drives |
| Data model | Rich, typed, browsable address space with companion specifications | OPC UA DataSets with metadata | None; payload format is up to you | Numbered coils and registers |
| Built in security | Application certificates, user tokens, Sign or SignAndEncrypt, roles | End to end signing and encryption with SKS keys, plus broker TLS | None in the protocol; relies on TLS and broker auth | None in classic Modbus TCP |
| Authentication of peers | Mutual, per application, via trust lists | Group membership via SKS; broker credentials | Broker credentials, optional client certificates | None |
| Operational cost | Certificate lifecycle, trust list management, policy review | SKS and broker operations plus group design | Broker operations, ACLs | Low, but needs strong network isolation |
| Good fit when | Engineering tools, SCADA, MES and gateways need meaning and control | Many subscribers, intermittent connectivity, IT and cloud integration | Constrained devices, simple telemetry | Legacy equipment that will not change |
OPC UA PubSub over MQTT is not "OPC UA versus MQTT"; it is OPC UA's data model and optional end to end security riding on an MQTT broker. Choose it when consumers need OPC UA semantics but the network shape suits a broker. Modbus remains common because it is simple and universally supported, but it gives you no authentication; put it behind an OPC UA or other authenticated gateway when data leaves the cell.
Common mistakes
- Leaving a None endpoint "for compatibility". One unsecured endpoint undoes the security of every secured endpoint on the same server, because clients choose.
- Turning on auto accept during commissioning and never turning it off. The plant then trusts any certificate. Use the rejected store as an approval queue instead.
- Treating Sign as encrypted. Sign protects integrity only; process values and recipes stay readable.
- Trusting a whole CA without thinking. Trusting a CA trusts every application it ever issued to, so scope CAs carefully.
- Cloning one certificate and key onto every device from a golden image. Each instance needs its own key pair and ApplicationUri, or revocation means touching every device.
- Allowing Anonymous with write access. Read only dashboards can be anonymous; control paths cannot.
- Sending passwords over policy None. Part 4 calls this "a serious security fault" unless another layer encrypts the traffic.
- Forgetting certificate expiry. An expired self-signed server certificate stops production traffic. Monitor end dates.
- Exposing OPC UA to the internet for remote support. Use reverse connect, a DMZ server or a VPN with MFA instead.
- Patching the server but not the SDK inside it. Many products embed a third party or open source stack, and the fix often has to come through that SDK first.
FAQ
What port does OPC UA use?
IANA registers TCP 4840 (opcua-tcp) for the OPC UA Connection Protocol, UDP 4840 (opcua-udp) for multicast datagrams, and TCP 4843 (opcua-tls) for OPC UA over TLS. The local discovery server's well known address is opc.tcp://localhost:4840/UADiscovery. Many servers also use vendor chosen ports, so check the endpoint URLs they advertise.
Is OPC UA encrypted?
Only if the endpoint uses the SignAndEncrypt security mode with a real security policy. Sign mode signs but does not encrypt later messages, and None applies no security at all. Check each endpoint's mode and policy with GetEndpoints.
What are OPC UA security modes?
None, Sign and SignAndEncrypt. None applies no security, Sign adds message signatures for integrity and application authentication, and SignAndEncrypt adds confidentiality. A fourth enumeration value, Invalid, exists so that an unset field is never mistaken for None.
Which OPC UA security policies are deprecated?
The OPC Foundation's reference stack documentation lists Basic128Rsa15 and Basic256 as deprecated because they use SHA-1, and keeps them only for legacy compatibility. Current choices include Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss and the ECC policies. The authoritative list is the OPC Foundation Profiles database.
What is an OPC UA application instance certificate?
An X.509 v3 certificate that identifies one installed instance of a client or server. Its subjectAltName carries the application's URI and, for servers, host names. Peers accept it only if it, or a CA in its chain, is in their trust list.
What does "certificate untrusted" mean in OPC UA?
The certificate passed structural and signature checks, but neither it nor any CA in its chain is in the receiving application's trusted list. The fix is for an administrator to verify the certificate and add it, or its CA, to the trust list, not to enable auto accept.
OPC UA vs MQTT: which should I use?
They solve different problems and often work together. OPC UA gives a typed information model and built in application authentication; MQTT gives lightweight brokered messaging. OPC UA PubSub can run over MQTT, and for end to end security there it must use UADP binary encoding.
OPC UA vs Modbus: what is the difference?
Modbus reads and writes numbered registers with no built in authentication or encryption. OPC UA exposes a browsable, typed model with methods, events and history, and has certificates, user authentication and encryption in the protocol.
Is OPC UA secure by default?
The specification requires the None profile to be disabled by default and defines strong mechanisms, but real security depends on configuration: secured endpoints only, managed trust lists, no auto accept, sensible user tokens and current policies. BSI's 2015 analysis found no systematic flaws in the specification itself.
Fix it without waiting for upstream
OPC UA security problems that are not configuration usually live in code you ship: the OPC UA SDK compiled into a gateway service, the open source stack inside an edge container, the client library in a historian connector, or the TLS and crypto libraries those stacks depend on. Safeguard's software composition analysis, generally available, inventories those libraries with their full transitive dependencies, alongside SBOM generation in SPDX and CycloneDX and container image scanning; vulnerability findings are enriched with EPSS and CISA KEV data and ranked with reachability analysis, all generally available. Safeguard does not inspect, filter or block OPC UA traffic, and it does not manage OPC UA certificates or trust lists. What it does is tell you which OPC UA stack versions you build and ship, and help you replace the vulnerable ones quickly.
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
These demos show dependency, SBOM and remediation workflows, not OPC UA traffic monitoring or certificate management. You can download Safeguard and follow the CLI docs to try them on your own projects.
This demo sets up the Safeguard runner on your own machine, approves it with its device code and then scans from the terminal. Pointed at the container image for an edge gateway, or at the repository of a service that talks to OPC UA servers, the same scan lists the OPC UA SDK and crypto libraries inside with their versions and any known vulnerabilities.
Click through it at your own pace, or open it full screen.
This demo is a real CLI session: install, open the interactive terminal, ask it to fix the lodash CVE in a repository, and watch it read the finding and advisory, ask before each command, move lodash to 4.17.21, run npm install and npm test with approval, and print a summary without pushing anything. The same approve each step flow applies when the dependency to bump is an OPC UA client or server library pinned in a gateway service's manifest.
Click through it at your own pace, or open it full screen.
This demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. Once connected, you can ask in plain language which of your projects include a particular OPC UA stack version after an OPC Foundation advisory, and get the answer from your own scan data rather than from memory.
Click through it at your own pace, or open it full screen.
Quick check
A server offers a SignAndEncrypt endpoint with Basic256Sha256 and a None endpoint for an old HMI. Is the server secure?
No. Clients choose among offered endpoints, so any client can use the None endpoint and get an unauthenticated, unencrypted channel. Part 2 says profile None should be disabled, and Part 2 also lists downgrade to weaker endpoints as a threat. Remove the None endpoint or isolate it on a separate, firewalled listener with a retirement date.
Why does a PubSub SecurityGroup containing one controller and ten HMIs worry a security reviewer?
Because SecurityGroup keys are shared and symmetric. Every member can decrypt and every member can publish, so if any one HMI is compromised it can send messages the others will accept as coming from the controller. Part 2 suggests smaller groups, such as one per controller and HMI pair, plus network level controls.
Sources
- OPC Foundation: OPC 10000-1, Part 1 Overview and Concepts, 1.05.06
- OPC Foundation: OPC 10000-2, Part 2 Security Model, 1.05.06, 22 October 2025
- OPC Foundation: OPC 10000-4, Part 4 Services, 1.05.07, 15 April 2026
- OPC Foundation: OPC 10000-6, Part 6 Mappings, 1.05.07, 15 April 2026
- OPC Foundation: OPC 10000-7, Part 7 Profiles, 1.05.02
- OPC Foundation: OPC 10000-12, Part 12 Discovery and Global Services, 1.05.07
- OPC Foundation: OPC 10000-14, Part 14 PubSub, 1.05.06
- OPC Foundation: Unified Architecture landing page
- OPC Foundation: Security advisories (CSAF) repository
- OPC Foundation UA .NET Standard: Security profiles documentation
- OPC Foundation UA .NET Standard: Certificates documentation
- OPC Foundation UA .NET Standard: ConsoleReferenceClient README
- OPC Foundation UA .NET Standard: ConsoleReferenceClient options (Program.cs)
- open62541: ua command line client usage (tools/ua-cli)
- IEC: IEC TR 62541-1:2020, OPC Unified Architecture Part 1
- IANA: Service Name and Transport Protocol Port Number Registry
- BSI: Sicherheitsanalyse OPC UA (security analysis summary)
- NIST SP 800-82 Rev. 3: Guide to Operational Technology (OT) Security, September 2023
- CISA: Primary Mitigations to Reduce Cyber Threats to Operational Technology
- ISA: ISA/IEC 62443 Series of Standards
- OpenSSL: openssl-x509 manual
- man7.org: ss(8)
Last reviewed: 23 October 2026. OPC UA security policies are maintained in the OPC Foundation's online Profiles database and change between releases; check it and your SDK's documentation for the versions you run.