Files
UA-.NETStandard/docs/Profiles.md
T
0f85a9f719 AutoID: the OPC UA for AutoID Devices companion SDK (OPC 30010) (#4825)
# Description

This completes the AutoID contribution proposed in #4824: the model
package for [OPC 30010 OPC UA for AutoID
Devices](https://reference.opcfoundation.org/AutoID/v101/docs/) (1.01)
plus the server, the client, an MCP profile and a sample pair, in one
PR. It follows the newest companion pattern (GMS #4765, MachineTool,
CranesHoists, MachineVision).

## Commits

1. `fix(sourcegen)`: a structure property whose DataType a subtype
refines is redeclared with its own field (the NodeSet needs it;
unchanged from the first slice).
2. `feat(autoid)` model package `Opc.Ua.AutoID` (unchanged from the
first slice). Adds only `AutoIdReaderKind`.
3. `feat(autoid)` server package `Opc.Ua.AutoID.Server`.
4. `feat(autoid)` client package `Opc.Ua.AutoID.Client`.
5. `feat(autoid)` MCP profile `Opc.Ua.Mcp.AutoID`.
6. `feat(autoid)` samples `samples/AutoID`.
7. `build(autoid)` solution, package list and package validation tests.
8. `fix(autoid)` x3, `docs(autoid)` and `test(autoid)`: review fixes,
net48 compatibility, documentation, the native AOT test.
9. `fix(autoid)` x3 and `feat(autoid-client)`: `GetLocation` location
types, the `Client` of access events, the default scan cycle of the
simulated readers, and NodeIds and methods in the device snapshot
(details below).
10. `feat(autoid)`, `test(autoid)`, `docs(autoid)` (`afdd7858b`,
`22bc3b26e`, `ed25fe4ae`, on top of the master merge `1c7948f65`):
AutoID composes into an existing Device Integration owner like Pumps and
Scales (review feedback; see "Composition with other DI-based
companions").
11. `1458af9e9` (marcschier): the `AutoIdReadOptions` remarks state that
`StatusOnly` limits the values read and that each call still browses
(Copilot review).
12. `fix(autoid)` `3ef2f1507`: `GetDeviceLocation` answers with the same
status codes as `GetLocation`; `feat(autoid-mcp)` `f6405152f`:
`autoid_read_device` shows the new snapshot NodeIds and methods (details
below).

## Server: `Opc.Ua.AutoID.Server`

- Reader devices (RFID, OCR, optical, optical verifier, RTLS) on the DI
device model, created by a fluent builder (`AutoIdRuntime.Reader(name,
provider)`) and hosted with `AddAutoId` / `ConfigureAutoId` on
`IServiceCollection`.
- Hardware is behind provider interfaces: `IAutoIdReaderProvider`,
`IAutoIdScanProvider` (Scan), `IAutoIdAsyncScanProvider`
(ScanStart/ScanStop), `IAutoIdRfidProvider` (ReadTag, WriteTag,
WriteTagID, KillTag, LockTag, SetTagPassword, each opt-in by flag),
`IAutoIdRtlsProvider`. Providers push scans, presence, log entries and
access events through `IAutoIdReaderSink`. In-memory providers (an EPC
Gen2 tag model with banks, passwords, locks and kill) are included for
tests and samples.
- Optional children (methods, `LastScanData`, `DeviceLocation`,
`AntennaNames`, location methods) exist only when the provider supports
them. Facet profiles and conformance units are advertised only for what
is implemented (`IConformanceContributor`); the Full facet is withheld.
- `GetLocation` (OPC 30010 6.6.3.2) returns the location in the
requested `LocationType`. An unsupported type is `Bad_InvalidArgument`,
an unknown object `Bad_NotFound`, and a supported type the object's
location is not available in `Bad_InvalidState` (6.6.3.2: "not available
or not allowed e.g. due to special configuration"); a provider result of
another type never reaches the client. `InMemoryRtlsProvider` takes an
optional location converter, for example from the configured local
coordinate system (9.3.4) into WGS84.
- `GetDeviceLocation` (6.1.3.7) uses the same mapping: an undefined
location type is `Bad_InvalidArgument`, a device location that is not
available in the requested type `Bad_InvalidState` (it answered
`Bad_NotSupported` before). 6.1.3.7 lists only "Standard OPC UA status
codes defined for the Call Service in OPC 10000-4"; there
`Bad_NotSupported` means "The Method is not supported for the Object
instance", which is wrong for a published method, and OPC 10000-4
5.12.2.4 allows reusing an existing status code with the same canonical
meaning, so the method follows 6.6.3.2.
- Access events (7.10, 7.11): `Client` is "the name of the client
application which was the originator of the command", so it is the
application name of the session's client description (else its
application URI), not the user identity. The results of a `ScanStart`
scan name the client that started it; scans the device reports on its
own name the device.
- The simulated readers default to one scan cycle per second
(`CycleInterval`, configurable per provider; the length of a cycle is
device specific in OPC 30010), so an unbounded `ScanStart` raises at
most one scan event per second.
- Behaviour: one scan at a time with a generation counter;
ScanStart/ScanStop serialised; a scan started by a session stops when
that session closes; the maximum scan duration, tag read length and
result count are limited by `AutoIdServerOptions`; device status changes
and events are raised outside locks; registration is rolled back on
failure; readers, providers and the runtime are disposed in order and
in-flight operations are drained.

## Composition with other DI-based companions

A server has one Device Integration owner, and AutoID now uses the
existing harmonized composition instead of requiring its own node
manager:

- `AutoIdMachineryModelProvider` adds the AutoID model to the Machinery
owner's model-provider pipeline (dependency-ordered, `Order` 200) and
keeps the DI nodes the owner loaded, so DI and `DeviceSet` exist once.
- `AddAutoIdToMachinery` (after `AddMachinery`) registers it;
`ConfigureAutoIdFor<TNodeManager>` creates readers on any
`DiNodeManager` owner, successive delegates share one `AutoIdRuntime`;
`owner.CreateAutoIdRuntime()` is the path without DI hosting. The owner
disposes the runtime on shutdown.
- Readers are registered in the owner below its `DeviceSet`, NodeIds in
the owner's instance namespace (`AutoIdRuntime.InstanceNamespaceIndex`),
not in the `Machines` folder; the AutoID conformance units and facets
are published by the owner next to the DI and Machinery ones.
- `AddAutoId` remains for the "AutoID is the only DI-based companion"
case and is built from the same provider. Next to another DI owner it is
still rejected; the message names the composition API. (Bypassing that
check gives two `DeviceSet` copies; the server routes `DeviceSet` to the
first owner and readers in the second are not browsable, checked
locally.)
- `Opc.Ua.AutoID.Server` now references `Opc.Ua.Machinery.Server` (a
stable package), as Vision does; a stand-alone server still loads only
DI and AutoID.

## Client: `Opc.Ua.AutoID.Client`

Reader discovery (a failed browse propagates), typed calls for every
published method, a device snapshot with documented `AutoIdReadOptions`,
and an async event stream (`ObserveScan/Access/Presence/LogEntries`) on
`IStreamingSubscription`. Cancellation is honoured throughout.
`AddAutoIdClient` registers it for DI. Because most children of a device
are optional (6.1, 6.5.3, 6.6.3), the snapshot also carries the NodeIds
of `DeviceStatus`, `LastScanData`, `LastScanTimestamp` and
`DeviceLocation` and the browse names of the published methods
(`Methods`, `HasMethod`), taken from the same browse whatever the read
options, so a client can monitor the device and knows what it may call
without browsing again.

## MCP profile: `Opc.Ua.Mcp.AutoID`

`McpToolProfile.AutoId` with nine tools: list readers, read device,
scan, scan start/stop, observe scan events, read tag, get supported
location types, get location. `autoid_read_device` also returns
`deviceStatusId`, `lastScanDataId`, `lastScanTimestampId` and
`deviceLocationId` (NodeId strings, null when the device does not
publish the variable) and `methods` (the browse names of the published
methods), built explicitly without reflection. Registered in the host
builder, the profile switches of the other profiles,
`Test-McpGrade.ps1`, `McpREADME.md` and `.mcp/server.json`.

## Samples

`samples/AutoID/AutoIdServer` (a dock-door reader with a simulated
pallet) and `AutoIdClient` with a README and
`Test-AutoIdSamplePair.ps1`. The default port is not a common one; tests
use port 0.

## Other changes

- `Opc.Ua.Di.Server` gets `InternalsVisibleTo` for
`Opc.Ua.AutoID.Server` (`RegisterRootNotifierAsync`).
- `UA.slnx`, `.azurepipelines/expected-packages.txt`,
`PackageVersionPolicyTests`, `NuGetPackageSetValidationTests`.
- Docs: `docs/AutoID.md`, `docs/McpServer.md`, `docs/Profiles.md`,
`docs/Samples.md`, `docs/DeveloperGuide.md`, `docs/README.md`,
`docs/WhatsNewIn2.0.md`, `README.md`, NugetREADMEs. The "model package
only" statements are removed.
- All packages follow the root version (no preview override).

## Specification notes and questions for the maintainers

- The model is 1.01, published 2020-06-18 (the NodeSet header). OPC
30010 6.1.3.16 prescribes the `AutoIdModelVersion` string `"1.00"`,
which is what the NodeSet carries and what the server publishes.
- **Question:** the NodeSet's optical verifier `Scan` method returns
`WGS84Coordinate`, which looks like a model error. It is not published,
and providers that implement `IAutoIdScanProvider` for a verifier are
rejected. Is that the behaviour you want?
- The stack answers a call to an unpublished optional method with
`BadNotImplemented`.

## Design choices reviewers may want changed

- `Opc.Ua.Di.Server` gets `InternalsVisibleTo` for
`Opc.Ua.AutoID.Server`, so the server can call
`RegisterRootNotifierAsync`.
- `AutoIdReaderKind` (and `AutoIdReaderKinds.TypeIdOf`) lives in the
model package `Opc.Ua.AutoID`, not in the server package, so the client
and the MCP tools share it.
- The MCP profile is read-only/safe: no tools that write, kill or lock
tags.

## Tests

`tests/Opc.Ua.AutoID.Tests` has 306 tests (116 of the model slice, 190
new): reader lifecycle, scan semantics, tag access handlers, limits,
conformance, in-memory providers, hosting, and over-the-wire
client/server tests with result codes, events, concurrency and dispose.
`tests/Opc.Ua.Tools.Tests` has 13 AutoID MCP tests plus the updated
profile-count tests. New behaviour tests fail without the code (for
example a provider's own cancellation, a synchronous scan while a scan
stop is in progress; for the last round: `GetLocation` of a supported
type the object is not located in answered `Bad_NotFound`, access events
named the user "Anonymous" and attributed `ScanStart` results to the
device, and an unbounded `ScanStart` on a default simulated reader
reported 20 times in 400 ms). Composition: `AutoIdCompositionTests`
(stock Machinery owner, providers out of order, DI loaded once, instance
ownership, rollback, cancellation, runtime disposal, an
application-owned DI owner, a second DI owner rejected) and
`AutoIdMachineryCompositionEndToEndTests` (Machinery + Pumps + AutoID in
one hosted server, read back by the AutoID, Machinery and Pumps clients,
including a scan and the published profiles and conformance units).
Mutating the change (no lifetime registration, the DI instance namespace
for browse names, the old ownership message) fails three of them. The
sample pair script passes. `tests/Opc.Ua.Aot.Tests.Mcp` has an AutoID
profile test (`AutoIdMcpAotTests`); the project was published with
Native AOT on osx-arm64 and all 64 tests passed. Publishing it also
found two `JsonArray.Add<T>` uses in the MCP tools (IL2026/IL3050), now
fixed.

## Verification (local, macOS arm64, SDK pinned in `global.json`)

The branch contains the master merges `fc556be7e`, `1c7948f65` and
`af7feb886`; the three composition commits sit between the last two (the
latest merge touches no AutoID, DI or Machinery file). `1458af9e9`
(marcschier) and the two commits of the last round follow `af7feb886`.

- **Last round (`3ef2f1507`, `f6405152f`).** Builds with `-m:2
-nodeReuse:false -p:UseSharedCompilation=false`: `Opc.Ua.AutoID.Tests`
on all target frameworks and with `-p:CustomTestTarget=net48`,
`Opc.Ua.Mcp.AutoID` on net8.0/net9.0/net10.0, `Opc.Ua.Tools.Tests` on
net10.0: 0 warnings, 0 errors. `Opc.Ua.AutoID.Tests` 306/306 on net10.0;
`Opc.Ua.Tools.Tests` AutoID tests 60/60, and the profile, catalogue,
composition and package tests that reference AutoID (2241) pass. The
changed tests fail without the code: `GetDeviceLocation` answered
`Bad_NotSupported` for both cases, and `autoid_read_device` had no
`deviceStatusId`. `tests/Opc.Ua.Aot.Tests.Mcp` published with Native AOT
on osx-arm64 (no IL2026/IL3050 warning): 64/64 passed. `dotnet format`
whitespace, style and analyzers `--verify-no-changes` on the changed
files: no finding on a changed line (line endings aside, which the LF
checkout on macOS reports for every file).

- **Build (composition round).** `Opc.Ua.AutoID.Server` on all target
frameworks, `Opc.Ua.AutoID.Tests` on net10.0 and with
`-p:CustomTestTarget=net48`, and the AutoID server sample: 0 warnings, 0
errors. MCP tools and JSON unchanged, so the native AOT test was not
republished.
- **Build (earlier rounds).** The AutoID packages and
`Opc.Ua.AutoID.Tests` on net10.0 and, with `-p:CustomTestTarget=net48`,
on net48/net8.0/net9.0/net10.0; `Opc.Ua.Tools.Tests` and
`Opc.Ua.SourceGeneration.Core.Tests` on net10.0 (`-m:2 -nodeReuse:false
-p:UseSharedCompilation=false`): 0 warnings, 0 errors.
- **Tests.** `Opc.Ua.AutoID.Tests` 306/306 on net10.0 (composition
round; earlier round 288/288); `Opc.Ua.Tools.Tests` (AutoID, host
builder, profile and package tests) 2438/2438 on net10.0;
`Opc.Ua.SourceGeneration.Core.Tests` 4358 passed, 8 skipped, after the
master merge touched `NodeStateGenerator.cs`. net48 was built, not run
(no Mono on macOS); the fork CI runs it. The MCP tools and their JSON
are unchanged in the last round, so the native AOT test was not
republished.
- **Coverage.** Composition round: the local coverlet collector recorded
zero hits for every module in this environment (also for unchanged
code), so no new local number; the new paths are exercised by the 18
composition tests listed above and the fork CI uploads coverage. Earlier
round: cobertura from the AutoID tests: `Opc.Ua.AutoID.Server` 92.0 %
lines / 86.8 % branches, `Opc.Ua.AutoID.Client` 89.9 % / 80 %; 110 of
the 112 coverable changed lines of the last round are covered (the two
missed lines skip a browse result without NodeId or name). The generated
code of the model package is excluded as in the other model packages.
- **Format.** `dotnet format` whitespace, style and analyzers
(`--severity info`) `--verify-no-changes` on the changed files: clean.

Fork CI (full matrix including macOS): [run
39162077465](https://github.com/biancode/UA-.NETStandard/actions/runs/39162077465)
on `f6405152f`: green. (Previous round: run 39130154771 on `ed25fe4ae`,
90/90 jobs green; the upstream checks on the merge `af7feb886` green,
108 passed, 5 skipped.)
CodeQL: [run
39162079826](https://github.com/biancode/UA-.NETStandard/actions/runs/39162079826)
on `f6405152f`: green, no alert in a file this PR touches. (Previous
round: run 39130156598 on `ed25fe4ae`, green.)

## Related Issues

- Part of #4824 (tracking issue: AutoID companion SDK).

## Checklist

- [x] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce (new) build or
analyzer warnings.
- [x] I ran **all** tests locally using the **UA.slnx** solution against
at least .net **framework** and .net **10**, and all passed. (The
solution builds on all TFMs; the AutoID test projects ran on net10.0
locally, net48 runs in the fork CI.)
- [x] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [x] I have addressed **all** PR feedback received.

---------

Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-10-19 12:30:33 +02:00

44 KiB

OPC UA Profiles and Facets Support

This document describes which OPC UA Profiles and Facets are implemented in the OPC UA .NET Standard Stack, and where in the codebase / documentation each one lives.

Overview

The OPC UA .NET Standard Stack is a reference implementation that targets OPC UA specification version 1.05.07. Historical reference-server certification does not certify every current SDK feature, companion model or application. Use the implementation and provider limits below, the exact product's advertised capabilities, and its version-specific certification scope.

The SDK ships implementations and helpers for:

  • Part 1 (Overview and Concepts)
  • Part 2 (Security Model)
  • Part 3 (Address Space Model)
  • Part 4 (Services)
  • Part 5 (Information Model)
  • Part 6 (Mappings)
  • Part 7 (Profiles)
  • Part 8 (Data Access)
  • Part 9 (Alarms & Conditions)
  • Part 10 (Programs)
  • Part 11 (Historical Access)
  • Part 12 (Discovery and Global Services, including LDS/GDS)
  • Part 13 (Aggregates)
  • Part 14 (PubSub)
  • Part 16 (State Machines)
  • Part 17 (Alias Names)
  • Part 18 (Role Management)
  • Part 20 (File Transfer)
  • Part 21 registrar ticket administration (not a complete device-onboarding state machine)
  • Part 100 (Device Integration / Software Update)
  • OPC 10100-1 (WoT Connectivity)
  • OPC 10000-200 (Industrial Automation)
  • OPC 10000-110 (Asset Management Basics)
  • OPC 40001-1/-2/-3/-4/-101 (Machinery)
  • OPC 40010-1 (Robotics)
  • OPC 40100-1/-2 (Machine Vision)
  • OPC 40200 (Weighing Technology), OPC 40223 (Pumps and Vacuum Pumps)
  • OPC 40501-1 (MachineTool), with OPC 40505 (Wireless Machine Tool Peripherals)
  • OPC 40210 (Geometric Measurement Systems), with the Production-facet exception below
  • OPC 40020-1 (Cranes and Hoists)

See What's New in 2.0 for the broader change narrative.

The canonical list of OPC UA profile and facet URIs is maintained by the OPC Foundation at https://profiles.opcfoundation.org/. Listing an interface or URI here does not mean every reference-server configuration advertises it. Inspect the actual endpoint descriptions, ServerProfileArray and contributed conformance units. Do not derive a profile URI from a package or feature name.

Contents

Server Profiles

The reference server (samples/Reference/ConsoleReferenceServer) advertises the following profiles in its ServerProfileArray:

Core Server Profiles

  • Standard UA Server Profile (2017) — The core OPC UA Server profile that includes:
    • Basic server capabilities
    • Discovery services
    • Session management
    • Subscription management
    • MonitoredItem services
    • View services (Browse, BrowseNext, TranslateBrowsePathsToNodeIds)
    • Attribute services (Read, Write, HistoryRead, HistoryUpdate)
    • Query services

Functional Facets

Local Discovery Server (LDS) Profile

The Opc.Ua.Lds.Server library plus the ConsoleLdsServer reference application implement the Local Discovery Server. The LDS application advertises the Local Discovery Server 2017 Facet (see samples/Lds/ConsoleLdsServer/Lds.Server.Config.xml).

Additional facets supported by the implementation (beyond the default advertised set)

Beyond the default profiles advertised in the reference server's ServerProfileArray, the master branch implements the following facets in the SDK. They can be enabled per-application by registering the corresponding NodeManager and, where applicable, adding the matching URI to ServerProfileArray (consult https://profiles.opcfoundation.org/ for the canonical URI string before claiming a facet):

  • Alarms and Conditions (Part 9) — Full server-side implementation with latched / silenced / out-of-service alarms, alarm groups, a suppression engine, and rate metrics. The reference server's AlarmNodeManager exposes a working sample. See Alarms and Conditions.
  • State Machine (Part 16) — StateMachineBuilder and the FluentFiniteStateMachineState extensibility in src/Opc.Ua.Server/StateMachines/. The reference server's BoilerStateMachineState is an end-to-end sample. See State Machines.
  • File Access (Part 20) — Server-side FileSystemNodeManager + IFileSystemProvider in src/Opc.Ua.Server/FileSystem/. The reference server enables it via the EnableFileSystemNodeManager option. The matching System.IO-style client lives in FileSystemClient.
  • Node Management (Part 4 service set) — INodeManagementAsyncNodeManager opt-in plus a per-NodeManager AllowNodeManagement gate for AddNodes / DeleteNodes / AddReferences / DeleteReferences. See Node Management.
  • Alias Names (Part 17) — AliasNameStore and the optional AliasNameNodeManager for AliasNameCategory / FindAlias / FindAliasVerbose / AddAliasesToCategory / DeleteAliasesFromCategory / LastChange. The reference server wires the standard Aliases and Topics nodes via ConfigureAliasNameStore. See Alias Names.
  • WoT Connectivity (OPC 10100-1) — Opc.Ua.WotCon / Opc.Ua.WotCon.Server / Opc.Ua.WotCon.Client library trio for surfacing OPC UA servers as Web-of-Things Thing Descriptions. See WoT Connectivity.
  • Device Integration (Part 100) — Opc.Ua.Di / Opc.Ua.Di.Server / Opc.Ua.Di.Client library trio, including the lock service and the software-update package store. See Device Integration and Software Update.
  • Relative Spatial Location and Global Positioning (Parts 210 and 211) — Opc.Ua.Positioning / Opc.Ua.Positioning.Server / Opc.Ua.Positioning.Client implement the released RSL and GPOS models, including RSL spatial lists and model changes plus the GPOS GlobalPosition, GlobalLocation, and Zones conformance units. See Positioning.
  • Robotics (OPC 40010-1) over Industrial Automation (OPC 10000-200) — Opc.Ua.Robotics / Opc.Ua.Robotics.Server / Opc.Ua.Robotics.Client library trio implementing the released Robotics 1.02 model over IA and Device Integration, with validated fluent topology builders for motion device systems, controllers, motion devices, axes, power trains, motors, gears, drives, safety states, and task controls. See Robotics.
  • Role Management (Part 18) — Server-side role administration plus a pluggable identity-provider model for anonymous, username, X.509, and token-issuer flows. The server automatically assigns the OPC UA Part 3 §4.9 TrustedApplication role; see also Role-Based User Management.
  • Auditing — The server raises audit events for security-relevant service calls (channel/secure-channel/session/activate/cancel). The audit and redaction APIs are provided by Opc.Ua.Server.
  • Model Change Tracking — Server-side ModelChangeAggregator with auto-emitted GeneralModelChangeEvent from CustomNodeManager; client-side per-node INodeCache.InvalidateNode. See Model Change Tracking.
  • Durable Subscriptions — Subscriptions that persist across reconnects. See Durable Subscriptions.
  • Complex Types — Custom structures and enumerations; see Complex Types.
  • Async server NodeManagers — TAP-based AsyncCustomNodeManager is the recommended base for new NodeManagers, and every NodeManager shipped with the stack has migrated to it. See Async Server Support.
  • Session-less invocation (Part 4 §6.3) - opt-in invocation of the permitted service sets through the existing identity/authorization pipeline; this does not enable session-less subscriptions. See Session-less invocation.
  • Final-value publication before node removal - a node manager can await inclusion of final values in server Publish responses before retiring dynamic nodes. This is an SDK lifecycle facility, not a separately certified profile or transport-acknowledgment guarantee. See Node managers.
  • Server redundancy (Part 4 §6.6) — AddServerRedundancy(...) publishes the Server.ServerRedundancy object, drives Server.ServiceLevel, and supports every RedundancySupport mode (None / Cold / Warm / Hot / HotAndMirrored / Transparent). Non-transparent modes advertise the NTRS discovery capability and return the peer set from FindServers; RequestServerStateChange supports administrator-driven Maintenance / NoData failover. Opt-in distributed high availability — address-space, session, and subscription mirroring over an in-package CRDT (eventual) or Raft (strong) shared store, plus a Kubernetes deployment — is provided by the Opc.Ua.Redundancy, .Server, .Client, and .Kubernetes packages. See High Availability.

Companion and extension models

This is the SDK implementation catalogue, not a list of facets enabled in every server. Generated model coverage, provider-backed runtime behavior, advertised conformance and external certification are different claims. Use each guide's limitations and the actual configured instance before claiming a facet.

Model or family Implemented support Conditions and limits
Device Integration, OPC 10000-100 Device composition, locking and software-update server/client interfaces Equipment and storage behavior use application providers
Asset Management Basics, OPC 10000-110 Asset discovery/identity, health, maintenance, documentation and location Sidecar registry composes with the asset's existing namespace owner
Industrial Automation, OPC 10000-200 Shared generated IA model used by companion builders Loading the model does not by itself implement every IA facet
Machinery, OPC 40001-1/-2/-3/-4/-101 Building blocks, process values, jobs, energy and result-transfer runtime/client interfaces Select capabilities and providers; durable result storage is application-supplied
MachineTool and WMTP, OPC 40501-1 and OPC 40505 Native monitoring, tools, retained/modern production, files, peripheral measurements/configuration/records and typed clients/MCP WMTP is bundled but independently modeled; no included Bluetooth driver or physical CNC executor
GMS, OPC 40210 Native systems, sensors/qualification, calibration observations, jobs/parts and Machinery-backed results Full GMS Production facet is withheld because its required GMS_ProductionStatisticsType is undefined upstream; no invented acquisition/calibration-control methods
Cranes and Hoists, OPC 40020-1 Robotics-derived topology, load/protection observations and provider-authorized limit requests Preview-only packages; not a motion or safety controller
Pumps, OPC 40223 Released model, fluent device builders and typed clients Actual equipment observations and effects require providers
AutoID Devices, OPC 30010 Released model, DI-based reader hosting with hardware providers, Scan/ScanStart/ScanStop, RFID tag access, RTLS location methods, scan/access/presence/log events, typed client and MCP tools The Full AutoID facet is withheld (no ScanActive control, no RuntimeParameters); actual readers require a provider; the optical verifier Scan method is not published because the NodeSet types its results as WGS84Coordinate
Scales, OPC 40200 Weighing, zero/tare, products, statistics, recipes, PackML and typed clients Stock runtime withholds Catchweigher, AutomaticWeightPriceLabeler and TotalizingHopper kind facets; application recipe execution/parser remains explicit
ISA-95, OPC 10030 and OPC 10031-4 Common resource model and Job Control V1/V2 providers, server bindings and clients Providers supply actual execution, catalogs and responses
Positioning, OPC 10000-210/-211 Released RSL/GPOS models, spatial lists, model changes, position/location/zones interfaces Positioning packages remain preview-only; do not infer GNSS hardware support
Robotics, OPC 40010-1 Released motion-device topology and supported controller/program interfaces Preview-only package policy is independent from the released Robotics model
Machine Vision, OPC 40100-1/-2 Released control/configuration/recipe/result and asset/condition-monitoring interfaces, clients and MCP Providers supply acquisition and equipment behavior; separate from Perception
Perception and Robot Intent Perception/media/inference/feedback and robot task-intent implementations Draft models with provisional identifiers, not released-companion conformance claims
AI, xRegistry, OpenUSD Model/deployment/inference services, registry/version/federation and scene/address-space integration Draft extension models; preview-only families, with provider/backend-specific limits
WoT Connectivity OPC 10100-1 interfaces and WoT conversion/binding implementations Preview package policy; registry extensions and transport-specific bindings have separate scope
PA-DIM/ECM and PackML Shared generated dependency models and the behavior bound by Machinery/Scales Not a blanket standalone device or all-facet implementation claim

Package preview status is governed by the release policy, not by a specification's publication date. The MachineTool/GMS and released Vision package families follow the root version; CranesHoists remains preview-only. Draft identifiers are not promoted to standard identifiers by shipping a package.

Client Profiles

The client (Opc.Ua.Client) supports the standard UA Client functionality through two coexisting paths:

  • Classic Session — the lowest-level OPC UA session primitive, paired with SessionReconnectHandler for caller-driven reconnect.
  • ManagedSession — recommended for new code. Encapsulates the connection state machine, reconnect policy, and pluggable subscription engine behind a fluent builder. See Sessions, Reconnection, and Subscription Engines.

Client-side feature coverage:

  • Subscriptions and monitored items — Both the classic publish engine and the V2 subscription engine (ISubscriptionManager / DefaultSubscriptionEngine) are supported and selectable per session. The V2 surface includes a declarative + imperative SetTriggering API with N:M support and automatic replay on recreate / reconnect, plus an IStreamingSubscription (IAsyncEnumerable-based) facade for state-machine waits and short-lived monitoring (ManagedSession.DefaultStreaming, TakeUntilAsync / WithTimeoutAsync helpers). See Subscriptions and Monitored Items.
  • Transfer Subscriptions — Subscription transfer between servers; see Transfer Subscriptions. An opt-in SubscriptionRecoveryPolicy lets the client tolerate Good_SubscriptionTransferred notifications from the server.
  • Reverse Connect — Client can accept connections initiated by the server; see Reverse Connect.
  • Model Change Tracking — Client-side per-node cache invalidation driven by server-emitted model-change events; see Model Change Tracking.
  • File System Operations — Async, System.IO-style client over OPC UA file methods; see FileSystemClient.
  • Alarms and Conditions — Typed AlarmClient event records, fluent AlarmEventFilterBuilder, and IAsyncEnumerable alarm streaming via AlarmStreamExtensions; see Alarms and Conditions.
  • Historical Access — HistoryClient (session.Historian()) for raw, modified (including ModificationInfo), at-time, processed (aggregate), annotation, and event history reads / updates; see Historical Access.
  • State Machines — Streaming and read helpers (GetCurrentFiniteStateAsync, ObserveFiniteTransitionsAsync, WaitForStateAsync) on the source-generated *TypeClient proxies; see State Machines.
  • NodeSet Export — Extract a server's address space to NodeSet2 XML; see NodeSet Export.
  • Source-generated typed proxies — *TypeClient proxies for ObjectTypes inside loaded models give strongly-typed method-call signatures; see Source-Generated NodeManagers.
  • Complex types — Decode and consume server-defined structures and enumerations on the client; see Complex Types.
  • Generation-bound session clients - capture a transport/session generation and namespace mappings; invalidated bindings reject requests instead of retargeting them after reconnect. This is an additive SDK capability, not a separate conformance profile. See Session bindings.
  • Typed companion workflows - the model families above include their documented discovery, read, operation and observation helpers. Companion and general stack workflows are also exposed through bounded MCP profiles, with separate host grants for privileged/live execution. MCP catalogue selection is neither an execution grant nor an OPC UA Client conformance profile.

Transport Profiles

The stack implements the following transport profiles:

Client and server transports

  • UA TCP Transport (opc.tcp://) — Primary OPC UA binary transport over TCP.

    • Full UA Secure Conversation (UASC)
    • Binary encoding
    • Reverse-connect capability
  • HTTPS Binary Transport (opc.https:// and https://) — OPC UA binary protocol over HTTPS with TLS.

  • HTTPS JSON Transport (opc.https:// and https://) - OPC UA JSON (compact / reversible) over HTTPS (OPC UA Part 6 §7.4.5)

    • Compact JSON encoding (application/opcua+uajson)
    • TLS/SSL encryption only — no UA SecureChannel layer
    • Restricted to MessageSecurityMode.None; transport security is provided exclusively by TLS
  • WebSocket Secure (UA Binary) (opc.wss:// and wss://) - UA Binary + UASC over secure WebSockets (OPC UA Part 6 §7.5.2, sub-protocol opcua+uacp)

    • Same UASC SecureChannel pipeline as opc.tcp carried over WebSocket binary frames (one frame per MessageChunk)
    • Supports all security modes (None / Sign / SignAndEncrypt)
    • TLS/SSL encryption at the WebSocket layer
  • WebSocket Secure (JSON) (opc.wss:// and wss://) - OPC UA JSON over secure WebSockets (Part 6 §7.5.2, sub-protocol opcua+uajson)

    • Compact JSON encoding per WebSocket text frame
    • TLS/SSL encryption only — no UA SecureChannel layer
    • Restricted to MessageSecurityMode.None
  • HTTPS OpenAPI (opc.https:// and https://) - OPC UA OpenAPI Mapping (Part 6 §G.3) — official OPC Foundation profile/2338, URI http://opcfoundation.org/UA-Profile/Transport/https-uajson-openapi

    • Path-routed REST surface: POST /<service> (e.g. /read, /browse, /createsubscription)
    • Body is the bare <Service>Request / <Service>Response — no {UaTypeId, UaBody} envelope at the HTTPS layer
    • Compact (default, mandatory per §5.4.9) and Verbose JSON flavours selected via the application/json; encoding=compact|verbose media-type parameter
    • TLS/SSL encryption only — no UA SecureChannel layer
    • Restricted to MessageSecurityMode.None
    • Authentication via Anonymous, Bearer JWT, HTTP Basic, or Mutual TLS (see WebApi.md)
    • Server-side discovery emission: HttpsServiceHost emits this sub-profile as a discovery-only twin alongside each SecurityMode.None HTTPS-binary endpoint, so discovery-driven clients can find the OpenAPI endpoint without hard-coding the URL.
    • Shipped as part of the OPCFoundation.NetStandard.Opc.Ua.Bindings.Https package (net8+ only)
    • Surfaced via Profiles.HttpsOpenApiTransport
  • WSS OpenAPI (opc.wss:// and wss://) - OPC UA OpenAPI Mapping over secure WebSockets (Part 6 §7.5.2, sub-protocol opcua+openapi / opcua+openapi+<accesstoken>) — official OPC Foundation profile/2339, URI http://opcfoundation.org/UA-Profile/Transport/wss-uajson-openapi

    • Same on-wire {TypeId, Body} OPC UA JSON envelope as opcua+uajson, multiplexed over WebSocket text frames; distinguished by the negotiated sub-protocol and the advertised TransportProfileUri
    • Bearer-token variant negotiates the access token in the sub-protocol name (no Authorization header — required for browser fetch compatibility); the server extracts the token from the sub-protocol name and feeds it through the standard ISessionlessIdentityProvider pipeline
    • Server-side discovery emission: the WSS factories emit this sub-profile as a discovery-only twin alongside each SecurityMode.None WSS binary endpoint, mirroring the HTTPS OpenAPI emission.
    • Client surface: src/Opc.Ua.Client/WebApi/WebApiWssTransportChannel.cs; fluent shortcut ManagedSessionBuilder.UseWssOpenApiEndpoint(url); DI registration via services.AddWebApiTransportChannel() (registers both HTTPS and WSS WebApi channel factories).
    • Surfaced via Profiles.WssOpenApiTransport

PubSub transports

The PubSub library supports the following PubSub transport facets (URIs surfaced by Profiles.PubSub*Transport constants in src/Opc.Ua.Core/Security/Constants/SecurityConstants.cs). Facet machinery and conformance unit semantics are defined by Part 7 §4.3.

  • PubSub UDP UADP — UDP transport with UADP message encoding.
  • PubSub Ethernet UADP — Ethernet (Layer 2) transport with UADP message encoding (see PubSub transports).
  • PubSub MQTT UADP — MQTT transport with UADP message encoding.
  • PubSub MQTT JSON — MQTT transport with JSON message encoding.
  • PubSub Kafka UADP and PubSub Kafka JSON - Part 14 Annex B.2 broker mapping through Opc.Ua.PubSub.Kafka; see Kafka transport and backend limits.
  • DTLS over UDP - supported registered profiles use the UDP transport's platform/cryptographic capabilities; Curve25519/Curve448 DTLS profiles are not registered. See PubSub security limits.
  • Datagram-v2 connection profile — DatagramConnectionTransport2DataType (Part 14 §6.4.1.4) is honoured for UDP transports. The DiscoveryAnnounceRate, DiscoveryMaxMessageSize, and QosCategory fields drive discovery cadence and the IP DSCP TOS byte.
  • PubSub SKS pull / push — Part 14 §8.5.1 / §8.5.2: the AddPubSubSecurityKeyServiceClient extension implements the pull client (calls GetSecurityKeys on a remote SKS), and AddPubSubSecurityKeyServiceServer hosts the in-memory SKS with Get/SetSecurityKeys and AddSecurityGroup methods bound on the address space.
  • AES-128-CTR / AES-256-CTR with HMAC-SHA-256 — Part 14 §8.4.3 message security. Profiles registered as PubSubAes128CtrPolicy / PubSubAes256CtrPolicy; conformance to NIST SP 800-38A F.5.1 / F.5.5 is asserted by the test suite.
  • Anonymous certificate-based MQTT auth — the MQTT transport exposes the MqttClientAuthenticationOptions with the certificate-based variant from Part 14 §6.4.2.2.4.

PubSub additionally supports certificate-based MQTT authentication and considers WriterGroups in MQTT keep-alive calculations.

All transport profiles defined in OPC UA Part 6 §7.4 (HTTPS) and §7.5 (WebSockets) are supported, including the opcua+openapi and opcua+openapi+<accesstoken> WebSocket sub-protocols (Part 6 §7.5.2 Table 81).

Security Profiles

The stack supports the following security profiles for secure communication. The canonical set is defined in src/Opc.Ua.Core/Security/Constants/SecurityPolicies.cs.

RSA-based security policies

  • Basic256Sha256
    • 256-bit AES encryption
    • RSA-OAEP for key encryption
    • HMAC-SHA256 for message authentication
    • Minimum key size: 2048 bits
  • Aes128_Sha256_RsaOaep
    • 128-bit AES encryption
    • RSA-OAEP for key encryption
    • HMAC-SHA256 for message authentication
  • Aes256_Sha256_RsaPss
    • 256-bit AES encryption
    • RSA-PSS signatures
    • HMAC-SHA256 for message authentication

ECC-based security policies

ECC support is documented in detail in ECC Profiles.

Traditional ECC curves

Modern ECC curves (v2.0)

AES-GCM and ChaCha20-Poly1305 variants (v2.0)

Modern AEAD cipher alternatives for traditional ECC curves:

  • ECC_nistP256_AesGcm, ECC_nistP256_ChaChaPoly
  • ECC_nistP384_AesGcm, ECC_nistP384_ChaChaPoly
  • ECC_brainpoolP256r1_AesGcm, ECC_brainpoolP256r1_ChaChaPoly
  • ECC_brainpoolP384r1_AesGcm, ECC_brainpoolP384r1_ChaChaPoly

RSA Diffie-Hellman (v2.0)

  • RSA_DH_AesGcm — RSA Diffie-Hellman key agreement with AES-GCM
  • RSA_DH_ChaChaPoly — RSA Diffie-Hellman key agreement with ChaCha20-Poly1305

Platform requirements for ECC. Certificate creation, storage, and validation are distinct from ECC SecureChannel and user-token security policies. On .NET 8.0 or later those policies use the platform's raw ECDH agreement and authenticated ciphers; on .NET Framework the agreement and the AES-GCM and ChaCha20-Poly1305 ciphers run in the managed BouncyCastle implementation. Curve and cipher availability also depends on the OS and, on .NET 8+, the runtime probes (AesGcm.IsSupported / ChaCha20Poly1305.IsSupported). See the ECC platform limitations for the certificate-operation and channel-policy boundaries. PubSub has its own transport security limits.

Deprecated security policies

The following security policies are deprecated but still supported for backward compatibility:

Note. SHA-1 signed certificates are rejected by default (RejectSHA1SignedCertificates configuration option). These deprecated policies should only be enabled for compatibility with legacy systems.

Security policy None

  • None — No security.
    • For testing or isolated networks only.
    • Not recommended for production environments.

User Authentication

The stack supports the following user authentication mechanisms:

  • Anonymous — No user authentication.
  • Username / Password — User credentials encrypted using the active security policy.
  • X.509 Certificate — User authentication via X.509 certificates.
  • Issued Token — Includes JSON Web Tokens (JWT) and other IssuerEndpointUrl-driven flows (OAuth2 / OIDC / Entra). The Identity Providers pluggable model (IClientIdentityProvider, IUserTokenAuthenticator, IAccessTokenProvider, ITokenIssuer, IIdentityClaims) is the recommended way to wire these in.

Certificate Types

The stack supports the following certificate types for application authentication:

RSA certificates

  • RsaSha256ApplicationCertificateType — RSA with SHA-256 signatures
    • Default minimum key size: 2048 bits
    • Recommended for production use

ECC certificates

  • EccNistP256ApplicationCertificateType
  • EccNistP384ApplicationCertificateType
  • EccBrainpoolP256r1ApplicationCertificateType
  • EccBrainpoolP384r1ApplicationCertificateType

The RejectSHA1SignedCertificates configuration option (on by default) prevents SHA-1 signed certificates from being accepted. See Certificates and Certificate Manager for storage, ref-counted lifetime, and the segregated-interface design.

Global Discovery Server (GDS)

The stack ships a Global Discovery Server implementation covering the following OPC UA Part 12 areas:

  • Application registration and discovery.
  • Pull and Push certificate-management models, including pushing to arbitrary certificate groups and custom certificate groups on the GDS itself.
  • Sub-CA revocation without auto-creating an empty CRL.
  • Support for both RSA and ECC certificate types and CRLs.
  • AuthorizationService (OPC 10000-12 §9) — OAuth2-style StartRequestToken / FinishRequestToken issuance with a pluggable IAccessTokenProvider / ITokenIssuer.
  • KeyCredentialService (OPC 10000-12 §8) — Credential issuance for non-OPC UA services such as MQTT brokers and REST APIs, backed by IKeyCredentialRequestStore / ISecretStore.
  • Registrar ticket administration (OPC 10000-21) - OnboardingClient, ITicketStore and the declared registrar methods. This is not the complete device-facing onboarding state machine; see the implemented scope.

See the GDS Developer Guide for the implemented facets, provider-dependent features, partial support, and hosting integration. This is not a claim that every optional Part 12 function is implemented or certified. The Local Discovery Server is a separate library (Opc.Ua.Lds.Server) and reference application (ConsoleLdsServer) that advertises the Local Discovery Server 2017 facet.

Message Encoding

The stack supports the following message encoding formats:

  • UA Binary — OPC UA binary encoding (primary for UA-TCP and HTTPS).
  • UA XML — OPC UA XML encoding (for configuration import / export and PubSub Dataset XML).
  • UA JSON — OPC UA JSON encoding for PubSub MQTT.
  • UADP — UA Data Protocol for PubSub.

The 2.0 release ships a new JSON decoder / encoder, array / matrix abstractions, and a first-class ByteString type. See the 2.0 migration guide — Encoders and Complex Types for the encoder/decoder migration details and Complex Types for client-side decode of server-defined types.

Specification Compliance

  • OPC UA Specification: Version 1.05.07.
  • Certification: Historical reference-server certification does not establish certification of the current release or of an application built with the SDK. Verify the certificate and tested profile scope for the exact product version.
  • Testing: Automated repository tests provide implementation evidence, not a substitute for certification. The GDS conformance matrix explicitly distinguishes its test evidence from CTT results.
  • Companions and extensions: The catalogue above records implemented interfaces and explicit gaps, not automatic whole-specification conformance. Selected instances, providers, endpoint security and actual advertised CUs determine an application's claim; package channel is a separate policy.
  • Redundancy (Part 4 §6.6): Server and client redundancy are implemented (opt-in) — RedundancySupport, Server.ServiceLevel, non-transparent (ServerUriArray / RedundantServerArray) and transparent (CurrentServerId) modes, RequestServerStateChange, and client-side transparent failover via ManagedSession.WithServerRedundancy(); see High Availability.

Configuration

Server profile configuration

Server profiles are configured in the server configuration file using the ServerProfileArray element. The reference server's default array is:

<ServerConfiguration>
  <!-- see https://profiles.opcfoundation.org/ for the canonical list of profile and facet URIs -->
  <ServerProfileArray>
    <ua:String>http://opcfoundation.org/UA-Profile/Server/StandardUA2017</ua:String>
    <ua:String>http://opcfoundation.org/UA-Profile/Server/DataAccess</ua:String>
    <ua:String>http://opcfoundation.org/UA-Profile/Server/Methods</ua:String>
    <ua:String>http://opcfoundation.org/UA-Profile/Server/ReverseConnect</ua:String>
    <ua:String>http://opcfoundation.org/UA-Profile/Server/ClientRedundancy</ua:String>
  </ServerProfileArray>
</ServerConfiguration>

To advertise additional facets (Historical Access, Aggregates, Alarms & Conditions, File Access, Auditing, NodeManagement, State Machine, etc.) look up the canonical URI for the facet on https://profiles.opcfoundation.org/ and add it to ServerProfileArray. Only advertise a facet that the application genuinely implements — the Compliance Test Tool will exercise every claimed facet. Bringing the reference-server and CTT configs in line with the facets the stack actually implements is tracked in #3875.

Contributed profiles and conformance units

Node managers that implement IConformanceContributor, such as the companion node managers, contribute the facets and conformance units they actually wire. At startup the server registers them with the ConformanceUnitsManager and publishes the aggregate to Server/ServerCapabilities/ConformanceUnits and ServerProfileArray. The startup lifecycle republishes after the actual endpoint descriptions are installed, so security-dependent companion claims are evaluated against real endpoint policies rather than a placeholder registry.

The manager keeps the registered contributors and reads them again on every PublishAsync, because the ServerCapabilities describe the current configuration of the server (OPC 10000-5 §6.3.2). A contributor whose support changes at runtime calls PublishAsync afterwards (the manager is ServerInternalData.ConformanceUnitsManager); a unit or profile that no contributor reports any more is withdrawn. Unregister removes a contributor. The profiles from the ServerProfileArray configuration are always kept.

Security policy configuration

Security policies are configured in the SecurityPolicies section:

<SecurityPolicies>
  <ServerSecurityPolicy>
    <SecurityMode>SignAndEncrypt_3</SecurityMode>
    <SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256</SecurityPolicyUri>
  </ServerSecurityPolicy>
  <ServerSecurityPolicy>
    <SecurityMode>SignAndEncrypt_3</SecurityMode>
    <SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep</SecurityPolicyUri>
  </ServerSecurityPolicy>
  <!-- ECC security policies -->
  <ServerSecurityPolicy>
    <SecurityMode>SignAndEncrypt_3</SecurityMode>
    <SecurityPolicyUri>http://opcfoundation.org/UA/SecurityPolicy#ECC_nistP256</SecurityPolicyUri>
  </ServerSecurityPolicy>
</SecurityPolicies>

See the reference server configuration file for a complete example, or the CTT configuration file for the variant selected by --ctt.

  • What's New in 2.0 — Narrative tour of the 1.5.378 → 2.0 changes, grouped by theme and layer.
  • Migration Guide — Prescriptive, per-API migration reference.
  • Subscriptions and Monitored Items — V2 ISubscriptionManager, declarative + imperative SetTriggering (N:M, replay on recreate / reconnect), and IStreamingSubscription.
  • Async Server Support — TAP-based AsyncCustomNodeManager and the IAsyncNodeManager family.
  • Dependency Injection — services.AddOpcUa() and the IOpcUaBuilder hosting surface.
  • Native AOT — AOT publishing, AOT-clean source generators, and the AOT test matrix.

References