The OPC UA ApplicationUri: the identity your security depends on

TL;DR

  • The ApplicationUri is the name an OPC UA application is known by. It is written into its certificate, and every trust decision hangs on it.
  • The specification requires it to be globally unique, for every running instance, and stable for the life of the application.
  • Many products ship with a default derived from the host name. Left unchanged, two instances or two sites can end up sharing one identity.
  • Choosing a good ApplicationUri takes five minutes at design time. Fixing a bad one later means reissuing certificates and updating every trust relationship.

A name that carries the trust

An OPC UA certificate does not just say "this is a key". It says "this key belongs to this application", and the application is named by its ApplicationUri: a URI such as

urn:acme:plant-lyon:packaging:line3:filler

That single string does a lot of work:

  • In the certificate. The ApplicationUri is stored in the certificate's Subject Alternative Name, next to the host names. It is part of what the certificate authority signs.
  • In the server's description. The server reports the same URI in its endpoint description and in its ServerArray.
  • In the handshake. When a client connects, it compares the URI the server reports with the one in the certificate. If they differ, the certificate does not belong to this application, and the connection is refused.
  • In every decision made about that application afterwards. Which trust list it appears in, which roles it is granted, which entries in a log are attributed to it, which certificate revocation applies to it.

In OPC UA, the certificate proves that someone holds a private key. The ApplicationUri says whose it is. Together they are the identity of an application.

ApplicationUri, ProductUri and the host name

Three names show up in an OPC UA application, and they answer different questions:

NameQuestion it answersShared between instances?
ApplicationUriWhich running application is this?Never
ProductUriWhich product is this, and who makes it?Always, by design
Host name / IPWhere can I reach it right now?Changes when the machine moves

The ProductUri identifies the software, so every copy of a product carries the same one. The ApplicationUri identifies the instance: this filler on this line in this plant. Network addresses change; the ApplicationUri is what stays.

A frequent mistake is to treat the ApplicationUri as a technical detail of the software rather than as a name that belongs to the installation. The software can propose a default. Only the person deploying it knows which application it actually is.

What the specification asks for

The requirement is short. An ApplicationUri must be globally unique, and unique for every running instance, including two instances on the same machine (OPC 10000-2 §3.1.3, OPC 10000-4 §7.2). It is also expected to stay stable: it identifies the application across restarts, upgrades and moves to new hardware.

Two consequences are worth stating plainly:

  1. Uniqueness is a property of the whole world, not of your site. A URI that is unique in your plant but reused in another of your plants, or by a supplier's machine, is not globally unique. Anything that ever exchanges certificates or trust lists between those places will confuse them.
  2. Changing it creates a new application. The certificate carries the old URI, so a changed URI needs a new certificate, and every trust list, role mapping and audit record that referred to the old identity no longer applies.

Why uniqueness matters for security

An OPC UA deployment turns identity into decisions. Each of them assumes the identity is unambiguous.

Trust. A server admits a client because that client's certificate is in its trust list. If two applications share a URI, a trust decision made for one silently covers the other.

Authorization. Role-based security (OPC 10000-18) can grant roles based on the application a session comes from. A role granted to "the maintenance tool" is only as strict as your ability to say which application that is.

Revocation. When a device is compromised or retired, you revoke its certificate. If another application shares the identity, it is hard to say which one you meant, and easy to cut off the wrong one.

Audit. After an incident, the question is "which application did this?". Logs that record the ApplicationUri can only answer that if the URI points to exactly one thing.

Impersonation. An OPC UA server can announce any ApplicationUri it likes. What stops it from posing as someone else is that the URI must match a certificate signed by a CA you trust. If your naming is predictable, ambiguous or copied from a default, that protection weakens. Anyone who can guess a URI that already has meaning in your plant is one step closer to claiming it.

Unique, stable names do not replace certificates and trust lists. They are the input that makes both of them mean something.

Where defaults go wrong

Most stacks are able to generate an ApplicationUri when you do not set one. A common default is built from the host name and a fixed application name. That is fine for a single test server on a laptop. It fails quietly in practice:

  • A cloned virtual machine or container image starts with the same URI as its source.
  • Two instances of one server on the same machine, differing only by port, share a default URI.
  • Identical devices from one manufacturer ship with the same URI in their firmware if the factory sets it once.
  • A moved or renamed host changes a URI that was meant to be stable, and invalidates certificates that used it.

None of these produces an immediate error. OPC UA sessions still open, because the client only checks that the URI matches the certificate the server presents, and each server's own certificate matches itself. The problem appears later, in the moment that something needs to tell the two apart: a trust decision, a revocation, a certificate rotation, an investigation.

How to choose a good ApplicationUri

Use a URN or a URL you control. Base it on a domain name or an identifier your organization owns, so that it is unique across organizations: urn:acme:... or http://acme.example/opcua/.... A name that begins with your own namespace cannot collide with someone else's.

Name the application, not the machine. urn:acme:plant-lyon:line3:filler is still correct when the filler moves to new hardware. urn:server-a1b2c3:NodeOPCUA-Server is not.

Give each instance its own. If you run two copies of a server, they are two applications. Give each its own URI, and its own certificate store.

Set it explicitly in production, and write it down. Treat it like a serial number: assign it once, record it in your asset inventory, and configure it rather than letting the software derive it.

Keep it stable. Choose a structure that survives reorganization. Avoid embedding things that will change: an IP address, a person, a project code.

Keep it in sync with the certificate. When a certificate is issued, it must carry the same URI the application reports. Whoever issues the certificate should check it, rather than copy what the application asserts.

A simple convention scales well:

urn:<organization>:<site>:<area or line>:<function>[:<instance>]

Unique and memorable at the same time

Unique and memorable pull in opposite directions. A random UUID is unique and impossible to remember; urn:acme:filler is easy to remember and will collide the day you buy a second filler. The way out is not to pick one, but to build the name from parts, each doing one job.

1. A namespace you own gives global uniqueness. The prefix (urn:acme: or a domain name you control) is what guarantees nobody else uses your names. Once that is settled, you only need uniqueness inside your own organization, which is a much easier problem.

2. A hierarchy gives memorability. People remember places and functions: site, line, machine. urn:acme:lyon:packaging:line3:filler reads like an address and can be guessed by anyone who knows the plant. Order the segments from the most stable to the most specific, so that names sort and group naturally in a directory.

3. A short identifier gives uniqueness where the hierarchy does not. When several machines share a role, end with something that is unique by construction and already exists: the asset tag from your inventory, a serial number, or a counter (filler-01, filler-02). For example urn:acme:lyon:packaging:line3:filler:AT-40217. Reusing an identifier you already track means the URI needs no extra bookkeeping.

4. Use a random identifier only as a last resort, and keep it beside a readable one. If you cannot rely on any existing identifier, add a UUID or a short random suffix at the end. Do not make it the whole name. Keep the readable part first, so the URI still tells a person what it is in a log line or a trust list.

5. Generate it from a template, at deployment. People are bad at keeping names unique by hand, and good at recognizing a pattern. Define the template once, then fill it in at deployment from data you already have: the site and line from your configuration, the tag from your asset register. In a container or image workflow, pass the URI in as an environment variable or configuration value, rather than baking it into the image. That is what stops a cloned image from carrying its parent's identity.

6. Keep a register, and check for collisions before you deploy. A spreadsheet or an inventory field is enough: one row per application, with its URI and its certificate thumbprint. Before assigning a new name, search the register. A collision found in a spreadsheet costs a minute; the same one found in production costs a maintenance window.

7. Separate the identity from the description. Put changing facts (the current owner, the project, the IP address) in the application's name and description, not in the URI. The URI stays the same when the humans' vocabulary changes.

Some patterns to avoid, with the reason:

PatternWhy it fails
urn:server:opcuaNot globally unique, and identical on every install
urn:<hostname>:NodeOPCUA-ServerChanges when the machine is renamed, and repeats on every instance on that host
urn:acme:project-atlas:...A project code that ends, and a name nobody recognizes later
urn:acme:10.0.4.17:...An address that changes, and one that is reused elsewhere
a bare UUIDUnique, but says nothing to the person reading the log

Readable for the people who operate the plant, unique for the certificate authority that signs the name: both come from splitting the URI into a namespace, a place, and a tag.

A short checklist

Before you roll out a fleet, check that:

  1. Every application has an ApplicationUri you chose, not a software default.
  2. No two running instances share one, on any machine, at any site.
  3. The URI is recorded in your inventory, next to the certificate's thumbprint.
  4. Your build or image process gives each new instance its own URI at deployment time.
  5. Your certificate issuing process verifies the URI rather than trusting the request.
  6. Replacing a device with a spare gets a planned decision: same identity, with a new certificate, or a new identity.

Where a GDS fits

A Global Discovery Server uses the ApplicationUri as the key of its application directory, and issues, renews and revokes certificates against it, so it is where a weak naming scheme shows up first. A well-built GDS therefore checks a server's identity when registering it and when issuing certificates, instead of accepting the URI it announces. See What is an OPC UA GDS? and GDS Push Management and Reverse Connect.

That check is a safety net, not a substitute for good names. The cheapest protection is still the one you put in place before the first certificate is issued.

Key takeaways

  1. The ApplicationUri names an application, and the certificate binds a key to that name.
  2. It must be globally unique for every running instance, and stable for its life (OPC 10000-2 §3.1.3, OPC 10000-4 §7.2).
  3. Trust, roles, revocation, audit and protection against impersonation all assume it is unambiguous.
  4. Software defaults are for laptops. Set the URI explicitly in production.
  5. Choose names from a namespace you own, name the application rather than the machine, and record them.
  6. To be unique and memorable, build the URI from parts: a namespace you own, a readable place and function, and a short tag that already exists in your inventory. Generate it from a template at deployment.

References

  1. OPC Foundation, OPC UA Part 2: Security Model, §3.1.3. opcfoundation.org
  2. OPC Foundation, OPC UA Part 4: Services, §7.2 ApplicationDescription. opcfoundation.org
  3. OPC Foundation, OPC UA Part 18: Role-Based Security. opcfoundation.org

Sterfive builds OPC UA GDS, a Global Discovery Server that treats identity as something to prove. If you are planning a certificate rollout across many similar devices, talk to our engineers.