Files
Marc Schier 397db603db Add OPC UA for Asset Administration Shell: the published OPC 30270 and v3 draft (#4244)
# Description

Implements the **Asset Administration Shell** companion specifications
on top of `marcschier/wot-type-binding`, in two halves that a Server
chooses between:

* **AAS V3** — the
[draft](https://github.com/marcschier/opcua-drafts/tree/main/companion-specs/AAS)
(`http://opcfoundation.org/UA/I4AAS/v3/`), all sixteen conformance
units: the metamodel, the registry built on the abstract xRegistry base,
generational materialization, federation, packages with digest-bound
integrity, the Digital Product Passport vocabulary, and the Annex F
bridge to WoT Thing Descriptions.
* **AAS V2** — the published [OPC
30270](https://reference.opcfoundation.org/specs/OPC-30270/full)
(`http://opcfoundation.org/UA/I4AAS/`), which maps the AAS V2.0.1
metamodel: object model, ingestion of XML, JSON and AASX,
materialization, server and client.

The two are different metamodel generations rather than two revisions of
one model — V2 keeps `Asset` as a first-class Identifiable,
`identification.idType`, Views and ordered collections, none of which
survive into V3 — so they are **alternatives**. A Server hosts one or
the other; this is documented rather than enforced at startup. Each is
named for the generation it maps (`Opc.Ua.Aas.V2`, `Opc.Ua.Aas.V3`,
`AddAasV2Server`, `AddAasV3Server`), and what genuinely serves both
carries no marker and sits at the root of `Opc.Ua.Aas`: the
deterministic NodeId encoding and idShortPath conventions,
`AasOptional<T>`, the digest rule, the materialization diagnostics, the
AASX container walk, and the value and operation providers, which are
keyed on `NodeId` and `Variant` and so carry no version at all.

## What is in here

**New libraries**: `Opc.Ua.Aas`, `Opc.Ua.Aas.Server`,
`Opc.Ua.Aas.Client`, `Opc.Ua.Aas.WoT`, plus `samples/Aas` and
`docs/Aas.md`.

**Enabling changes to existing code**, each needed by the above:

* The OPC UA `Decimal` DataType added to `Opc.Ua.Types`, with its Part 6
§5.1.10 wire encoding. `BinaryDecoder` gained one internal member,
`TryReadRemainingBodyBytes`, because a trailing field with no
self-describing length cannot otherwise be read; `Decimal.Decode` is its
only caller. Part 6 Table 3 types the unscaled `Value` as an
**OctetString whose byte count is `Length` − 2**, not a length-prefixed
`ByteString`, so it carries no length of its own —
`DecimalEncodingTests` pins the body byte-for-byte against that mistake,
and against the `Length ≤ 2` values the same table calls invalid.
* The xRegistry projection engine extracted into
`Opc.Ua.XRegistry.Server` and `Opc.Ua.WotCon.Server` migrated onto it
(−848/+387 lines), with the WoT Connectivity tests passing **unedited**.
* Two source-generator fixes, both of which made a model impossible to
build (see below).

## Defects found and fixed along the way

Running the stack end to end, rather than trusting per-area test suites,
surfaced defects that no unit test caught. The ones worth a maintainer's
attention:

* **The generator emitted non-terminating constructors.** A structure
field with no declared default was initialized with `new T()`, so a
self-referential DataType (`AASReferenceDataType.referredSemanticId`)
recursed until the stack overflowed and `AddOpcUaAas` could not load the
model at all. The test host *died* rather than failing. Only the field
that closes a cycle is now left null.
* **The generator omitted `new` on a redeclared placeholder.**
`AASOrderedSubmodelElementCollectionType` redeclares the
`SubmodelElement` slot of its base type, and the generated `Add` method
hid the base one without saying so, so the V2 model would not compile.
No existing model could have hit either defect — both are build
failures, so anything that builds today is unaffected.
* **The metamodel half had never worked outside its unit tests**: the
emitted NodeSet declared no reference-type aliases and was rejected by
the loader; the Mandatory `Invoke` Method was never emitted, because a
NodeSet is imported as written rather than instantiated from its type;
the runtime bound at the authored namespace index instead of the one the
Server assigns; and `MethodDeclarationId` was addressed in the wrong
namespace. Every materializer test inspected the in-memory object graph,
which cannot see whether the graph is loadable — two tests now import it
exactly as `RuntimeNodeSetNodeManager` does.
* **The client could not see any Property member.** It browsed
`HasComponent` with subtypes, but `HasProperty` is a sibling under
`Aggregates`, so reading a value failed and invoking failed argument
validation.
* **Every repeated registry write forked a duplicate group and
resource** instead of adding a version, because the identifier was
re-derived against a sibling set that already contained the entity
itself. This also made the persistence bounds unreachable.
* `.gitignore`'s `**/packages/*` silently swallowed the whole
package-integrity implementation and its tests, which would have
vanished on a fresh clone.

## Specification findings

Nine findings against the V3 draft are fixed in
[marcschier/opcua-drafts#75](https://github.com/marcschier/opcua-drafts/pull/75).
The substantive one: clause 6.1.5's absent-versus-empty rule was
**unsatisfiable** for five container fields that materialize as parent
components with no node of their own, which made `AAS-LosslessRoundTrip`
unachievable.

OPC 30270 contradicts itself twice. Both are recorded in
`AasV2ConformanceUnits.cs` and the documentation rather than smoothed
over: Table 83 spells the unit `I4AAS MultiLangaugeProperty` where Table
85 spells it correctly, and Table 85 lists an `I4AAS Security` unit that
Table 83 never defines. Table 84, which would assign profile URIs, is
empty, so `ServerProfileArray` gains no I4AAS entry.

## Known limitation

Calling an `Operation` **with arguments** answers `BadTooManyArguments`.
Method resolution works from both the instance NodeId and the
`MethodDeclarationId`, and the argument definitions are published, but
`NodeState.AddChild` does not route through `MethodState.FindChild`, so
a Method imported from a NodeSet leaves its typed `InputArguments` null.
Closing this means changing how the shared NodeSet import claims typed
children, which affects every consumer of runtime NodeSets and is out of
scope here. It is documented in `docs/Aas.md` §11, the conformance
matrix marks `AAS-OperationInvoke` partial rather than claiming it, and
`samples/Aas` exercises the path and reports the status rather than
working around it. V2 is unaffected — its `Operation` is an
OptionalPlaceholder with no declared arguments.

## Related Issues

- No tracking issue yet. Opening as a **draft** for design discussion
first, per the ADR guidance below; happy to open one and link it once
the shape is agreed.

## 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.
- [ ] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [ ] I have addressed **all** PR feedback received.

### Verification

| Check | Result |
|---|---|
| AAS tests | **670 passed, 0 failed** on net472, net48, net8.0, net9.0,
net10.0 |
| Coverage | Client 80.8 %, Server 81.2 %, `Opc.Ua.Aas` 82.0 %, WoT 82.4
% — all above the 80 % gate |
| Libraries | `Opc.Ua.Aas`, `.Server`, `.Client`, `.WoT` build clean on
every target framework, zero warnings |
| Regression | `Opc.Ua.Types` 8677, `Opc.Ua.WotCon` 1094,
`Opc.Ua.XRegistry` 198, `Opc.Ua.Server` 4050 — all green |
| Sample | `samples/Aas` builds warning-free and runs end to end |
| Merge validation | Solution builds clean on net10.0 and net48; WoT
Types 504, WotCon 1111, AAS 670, XRegistry 198 tests passed |
| CI | All 99 checks green on `ff9298e44`; only the CLA signature status
is outstanding |

### Review pass

A full review against both specifications, and for API consistency and
correctness, produced twelve
fixes. Each one has a test that fails without it.

| Defect | Where | Why it mattered |
|---|---|---|
| V2 projection aborted on **every** `File` read from a document |
`AasV2EnvironmentRuntime` | The runtime bound `File/Value`
unconditionally, the materializer emitted it only with content, and the
builder throws `BadNotFound` for an unknown NodeId — aborting the whole
registration. No reader ever populates `AasFile.File`, so no AAS V2
document could be hosted at all. |
| `aas-suppl` anchored on the wrong part | `AasxPackageReaderCore`,
`AasxPackageWriter` | IDTA and the Package Explorer anchor it on the
environment part; we used the origin part. Every real `.aasx` returned
zero supplementary files, silently. Affects both halves. |
| Federation failed closed on pooled connections | `AasFederation` |
`ConnectCallback` fires only for new connections, so the second fetch to
an origin — and all of net472/net48/netstandard2.1 — failed with a
security-flavoured error. The peer is now validated *inside* the
callback, which makes reuse safe by construction. |
| Malformed `Decimal` escaped as `ArgumentOutOfRangeException` |
`BinaryDecoder` | A declared body shorter than `Scale` produced a
negative read length. Two of the three test cases had been passing for
the wrong reason. |
| V2 and V3 cross-wired their value providers |
`OpcUaAasServerBuilderExtensions` | Both registered `IAasValueProvider`;
whichever was added first served both AddressSpaces. V2 now has its own
contract, so co-hosting is harmless rather than silently wrong.
`EnvironmentFolder` was also bound and ignored on the V2 path. |
| Export filter skipped three nesting kinds | `AasEnvironmentExporter` |
Content under `Entity`, `AnnotatedRelationshipElement` and `Operation`
was exported unevaluated *and* stamped with a Digest presenting it as
complete (clause 6.5.10). List authorization paths also shifted after a
denial. |
| Concealment held at the Method but not in the projection |
`AasRegistryModel` | `GetSubmodel` answered `BadNotFound` while an
anonymous Browse revealed the node, its identifier, semanticId and
digest (clause 6.5.7). |
| File handles were unsynchronized and unowned | `AasElementFileManager`
| The async node manager holds no lock, so concurrent Calls raced a bare
`Dictionary`; sequential handles let any Session read, seek or commit
another's. Writes were also unbounded. |
| Projection host was unimplementable outside the stack |
`AasEnvironmentProjection` | The handle demanded a type with an internal
constructor — our own tests used
`FormatterServices.GetUninitializedObject` to get round it. Now mirrors
WotCon's interface-typed registration. |
| Embedded `FileType` omitted 7 of 10 Mandatory members |
`AasEnvironmentMaterializer` (V2) | OPC 10000-3 6.4.4 requires them all;
without `Size` and `OpenCount` a Client cannot size a read or detect an
abandoned handle. |
| Round-trip oracle ignored most of the model | `AasRoundTripComparer` |
`Blob`, `File`, `ReferenceElement` and `BasicEventElement` had no case
arm, so their fields compared equal by falling off the switch;
`valueType`, `semanticId`, `entityType` and `Key.type` were never read.
The clause 6.4 losslessness claim rested on it. |

Known, unchanged: calling an `Operation` with arguments answers
`BadTooManyArguments`, because
`NodeState.AddChild` does not route through `MethodState.FindChild`.
Documented in `docs/Aas.md` §11.

Not addressed in this pass, and worth a maintainer decision: OPC 30270
§9.2 says all NodeIds of
Nodes not defined in the companion specification **shall not** use the
standard namespaces, and
Table 87 marks a vendor-specific instance namespace Mandatory. Both
halves currently mint instances
in the companion namespace. Separating them touches NodeId minting, the
runtime and the client
together, so it is better done deliberately than folded into a review
pass.
This is a large change and touches shared code (`Opc.Ua.Types`, the
source generator, the xRegistry projection). It is deliberately a draft:
the enabling changes are separable if maintainers would prefer them
split into their own PRs. The latest `master` is merged into this branch
in `0dd0ff0e1`.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9e6a5abf-3299-4cd1-9855-010fedbf0ad8
Copilot-Session: c3d88950-4a65-4ff6-87d2-1f545a875c9b
Copilot-Session: b8ab3763-b9bd-46ae-b0ef-045db26e5782
2026-08-18 08:11:47 -07:00
..

OPC UA .NET Standard stack documentation

Here is a list of available documentation for different topics:

New contributor? Start with the Developer Guide — prerequisites, building, testing, coding standards, and how-to recipes (including how to add logging).

  • OPC UA Profiles and Facets - Overview of supported OPC UA profiles, facets, security policies, and transport protocols.
  • Transport Profiles - Developer guide for the wire transports: opc.tcp / HTTPS (binary + JSON + REST) / WSS (binary + JSON), including server hosting and client connect examples.
  • REST Binding (OpenAPI Mapping) - OPC UA Part 6 §G.3 OpenAPI mapping: ASP.NET Core MVC controllers for every spec service, Compact / Verbose encoding negotiation, four pluggable auth modes (Anonymous / Bearer JWT / HTTP Basic / Mutual TLS), and the symmetric IWebApiClient.
  • What's New in 2.0 - Developer-facing tour of the 1.5.378 → 2.0 changes, grouped by theme and layer, with links to deeper feature docs.
  • Migration Guide - How to migrate from a previous version.
  • Sessions, Reconnection, and Subscription Engines - Architectural overview of Session, ManagedSession, SessionReconnectHandler, and the classic / V2 subscription engines, including guidance on which to use.
  • About .NET platform support, NuGet packages and versioning.
  • About continuous integration — which pipeline runs what, how to start a validation build on a pull request with /azp run, and the coverage gates a change has to satisfy.
  • How X.509 Certificates are used in the certificate stores.
  • CertificateManager - Centralized certificate lifecycle management, server-side push certificate rotation, and the OPC UA Part 12 PushManagement transaction model (ApplyChanges/CancelChanges, staged TrustList/Certificate updates, DeleteCertificate, pending-key persistence).
  • Crypto provider - Replacing the stack's cryptography with another library, a remote service or hardware (TPM, HSM, PKCS#11, cloud key service), keeping private keys inside the device, selecting providers per purpose and security policy, and auditing the use of uncertified cryptography.
  • Using the Reverse Connect for the UA-TCP and WSS transports.
  • Support for the TransferSubscriptions service set.
  • Diagnostics — logging, telemetry, server audit events, server diagnostics nodes, and packet capture.
  • Performance Benchmarks — BenchmarkDotNet methodology, the 2.0 (master) vs 1.5.378 (master378) comparison, root-cause analysis of the encoder/decoder/session regressions and their real-world impact, the subscription-notification (pooled encodeable) micro-benchmarks, server session scalability (the 500-session capability, sizing and bottlenecks), and planned future work.
  • Server Session Scalability — why a single node tops out at ~2000 concurrent sessions, the establishment vs steady-state boundaries (socket backlog, the BadTcpInternalError retry-storm amplifier, the O(N²) diagnostics rescan, CreateSession crypto-under-lock, the RSA CPU wall, and the held-Publish worker-accounting coupling) with code references, and a prioritized admission-control / rate-limiting roadmap for moving beyond it.
  • Rate Limiting and Admission Control — the server's deterministic, configurable connection- and session-establishment limiters (on by default, System.Threading.RateLimiting-based, DI-pluggable), the BadServerTooBusy signalling, the diagnostics-independent server retry-after carriers (ResponseHeader.additionalHeader, HTTP Retry-After, UA-TCP ERR, and load-based Server.ServiceLevel), and the client's server-signal-aware adaptive reconnect backoff (IReconnectPolicy.TryGetNextDelay).
  • Support for WellKnownRoles & RoleBasedUserManagement.
  • Pluggable Identity Providers — interfaces (IClientIdentityProvider, IUserTokenAuthenticator, IAccessTokenProvider, ITokenIssuer, IIdentityClaims) plus the OPC 10000-6 §6.5.2.2 IssuerEndpointUrl JSON parser for OAuth2 / OIDC / Entra / JWT flows.
  • Support for ECC Certificates.
  • Working with ComplexTypes - Custom structures and enumerations.
  • Client-based NodeSet Export - Export server address space to NodeSet2 XML.
  • Source generated [DataTypes] - How to annotate POCO classes and let the source generator generate the IEncodeable implementation.
  • Runtime Schema Generation - Produce XSD, OPC Binary (BSD) and JSON Schema (Part 6 Annex C, compact + verbose) for generated encodeable types and dynamically added complex types via the injectable ISchemaProvider; schemas are built as object models in code (trimmable, NativeAOT compatible).
  • NodeManagers - Overview of the server node-manager architecture, built-in managers (master, core, diagnostics/configuration), CoreNodeManager vs CustomNodeManager2 guidance, registration and runtime lifecycle rules, namespace metadata and historical-access reconciliation, and source-generated AsyncCustomNodeManager authoring with the fluent INodeManagerBuilder API. Includes NativeAOT single-file server guidance and samples such as MinimalBoilerServer and PumpDeviceIntegrationServer.
  • Runtime NodeSets - Load one or more NodeSet2 XML documents into the server address space at startup without source generation. Covers file and stream sources, dependency ordering, parent-child browse-path resolution, fluent Configure callbacks, default namespace inference, and the default complex-type loading path. Use when the XML content changes independently of the server binary or for rapid prototyping.
  • WoT / NodeSet conversion - WotNodeSetConverter readable mapping, preservation projections, and the WoT-to-NodeSet default/failure table.
  • WoT Connectivity - OPC 10100-1 asset connectivity, the WoT Connectivity 1.1 registry/client, dependency-closure materialization, and runtime NodeSet projection.
  • WoT protocol bindings - The bindings that ship today (planner/executor architecture, bundled and separate packages, operation coverage, target mapping, lazy channels, generation lifetime) and the contributor guide for adding your own, with a complete memory binding, registration, diagnostics, tests, packaging, TFM, trimming, and NativeAOT guidance.
  • Asset Administration Shell - OPC 30270 / AAS V2 ingestion-only metamodel support and the AAS V3 draft (I4AAS) model, JSON/XML/AASX serialization, metamodel server/client, xRegistry-based AAS registry, updateable materialization, package integrity, federation, DPP/WoT bridge, and conformance matrices.
  • WoT aggregation sample - Two flat OPC UA sources aggregated into a runtime-loaded DI/Machinery/Pumps Pump model, including commands, Refresh, monitoring, replacement, troubleshooting, and NativeAOT publishing.
  • Device Integration (DI) developer guide - End-to-end documentation for the Opc.Ua.Di* library trio: fluent IDeviceBuilder, device sub-type extensions (AddSoftware, AddBlock, AddConfigurableObject, AddLifetimeIndication, WithSupportInfo), hosting integration (AddOpcUaDi / ConfigureDevicesFor), lock service, software-update package store, and client helpers (DiLockClient, DiTopologyClient, SoftwareUpdateClient). Includes a section enumerating supported OPC 10000-100 features against the spec.
  • OpenUSD — bridge an OPC UA address space to an OpenUSD stage, in two parts. Part 1 — bindings: the generic domain-agnostic OpenUsdConnector (discovers Server/OpenUSD/Representations, subscribes, composes, verifies stage/asset digests, replays history), the Variant-based IUsdSink with UsdFileSink / MockUsdSink, the fluent/DI AddOpenUsdConnector extensions + OpenUsdConnectorFactory / OpenUsdConnectorOptions, server-side UsdAssetDelivery, and the optional --view viewport. Part 2 — scene materialization: materializes a composed USD stage inside the address space so the prim tree is the node hierarchy — the Opc.Ua.OpenUsdScene companion model plus scene document model, .usda reader/writer and the §6.2 UsdValueTypeMap (USD roles as DataTypes subtyping their built-in), and Opc.Ua.OpenUsdScene.Server with MaterializeUsdStage / ExportUsdStage, unknown-type fallbacks, Mode-A live attributes, portable Cesium georeference dual-authoring, discovery and Part 1 binding-target resolution. (Both companion models are currently drafts.)
  • Robotics developer guide — the Opc.Ua.Robotics / Opc.Ua.Robotics.Server / Opc.Ua.Robotics.Client trio for OPC 40010 Robotics 1.02 over OPC 40001-1 IA and OPC 10000-100 DI: source-generated models, AddRobotics / AddRoboticsModel / ConfigureRobotics(For) hosting, IRoboticsModelProvider / IRoboticsConfigurator / IRoboticsBuildContext, validated fluent topology builders (AddMotionDeviceSystemAsync down to axes, power trains, motors, gears, drives, safety states, and task controls), semantic references, ArrayOf<T> snapshot contracts, and RoboticsClient discovery. It also covers Robot Intent, the draft task-level motion verbs OPC 40010 leaves undefined, including the MCP surface for LLM agents.
  • Relative Spatial Location and Global Positioning — source-generated OPC 10000-210 RSL and OPC 10000-211 GPOS models, standalone/composed server hosting, provider contracts, high-level clients, frame-chain resolution, WGS84/ENU conversion, and ground-control-point fitting.
  • Generators (generating sets) — the draft Generators companion specification realised end to end by GeneratorServer: a datasheet-driven simulation in which load fraction is the only independent variable, DI + Machinery integration, and one independent OpenUSD twin per configured set. Includes SiteCompositionServer, a supervisory server that owns no devices and composes the pump and generator servers into a single scene through cross-server components.
  • ISA-95 developer guide - End-to-end documentation for the Opc.Ua.ISA95* library trio: the OPC-10030 Common Model and OPC-10031-4 Job Control V1/V2, the two transparently-documented normative NodeSet repairs, AddIsa95Server/AddIsa95Client hosting, the typed common-model builder, the shared Job Control state engine and its Uncertain/Annex-B ReturnStatus result model, the provider-backed GeoSpatialLocationType seam and planned Part 210/211 RSL/GPOS integration, and a conformance matrix distinguishing static NodeSet structure from runtime-tested behavior.
  • Alias Names - Full server + client support for the OPC UA Part 17 alias-name model (AliasNameType, AliasNameCategoryType, FindAlias, FindAliasVerbose, AddAliasesToCategory, DeleteAliasesFromCategory, LastChange).
  • Alarms and Conditions - Full server + client support for OPC UA Part 9. Server-side state types for latched/silenced/out-of-service alarms, alarm groups and suppression engine, alarm rate metrics. Client-side AlarmClient, typed alarm event records, fluent AlarmEventFilterBuilder, IAsyncEnumerable alarm streaming via AlarmStreamExtensions.
  • Historical Access (Part 11) - Server provider model (IHistorianProvider family) and InMemoryHistorianProvider, plus the client HistoryClient (session.Historian()) for raw/modified/at-time/processed reads, annotations, and updates.
  • Aggregates (Part 13) - All 37 standard Part 13 v1.05.07 aggregate functions over historical data: server AggregateManager / calculators, native push-down vs framework fallback, AnnotationCount via the annotation provider, AggregateConfiguration defaults, and the client ReadProcessedAsync helper.
  • Subscriptions and Monitored Items Service Set - V2 subscription engine API. Covers ISubscriptionManager for long-lived callback-based subscriptions, the declarative+imperative SetTriggering API with N:M support and automatic replay on recreate/reconnect, and IStreamingSubscription (IAsyncEnumerable-based) for state-machine waits and short-lived monitoring (ManagedSession.DefaultStreaming, TakeUntilAsync / WithTimeoutAsync helpers).
  • Unbounded Monitored Items - V2 logical-subscription wrapper that transparently splits monitored items across multiple server-side partitions when the per-subscription cap is exceeded (IPartitionedSubscription, MonitoredItemOptions.Affinity, reactive Bad_TooManyMonitoredItems fallback, secondary-partition idle-delete).
  • State Machines - Generic, extensible Part 16 state-machine API. Client side: streaming + read helpers on the source-generated *TypeClient proxies (GetCurrentFiniteStateAsync, ObserveFiniteTransitionsAsync, WaitForStateAsync). Server side: unified fluent StateMachineBuilder with two complementary modes — definition (Create(...) + AddState / AddTransition / OnCause for ad-hoc machines via FluentFiniteStateMachineState) and lifecycle (For(...) / INodeBuilder.AsStateMachine() + OnEnterState / WithCause / WithTimedTransition to attach behavior to stack-shipped or generator-emitted FSMs). Vendor state machines inherit both ends of the API automatically.
  • Model Change Tracking - Client-side address-space change tracking with per-node INodeCache invalidation; server-side ModelChangeAggregator and auto-emitted GeneralModelChangeEvent from CustomNodeManager.CreateNode/DeleteNode.
  • NodeManagement Service Set - Server-side AddNodes / DeleteNodes / AddReferences / DeleteReferences, including the INodeManagementAsyncNodeManager opt-in pattern and per-NodeManager AllowNodeManagement gate.
  • High Availability and OPC UA Redundancy - OPC 10000-4 §6.6 mapping for server, client, and network redundancy; RedundancySupport, ServiceLevel, manual failover, transparent/non-transparent ManagedSession modes, HotAndMirrored/Transparent state mirroring, distributed address-space/session/subscription stores with CRDT (eventual) or Raft (strong) consistency, shared certificate/trust-list stores, snapshot+delta hydration, and the optional GetEndpoints load-direction seam.
    • Kubernetes High Availability Deployment - Consolidated Kubernetes guide for the Opc.Ua.Redundancy.Kubernetes package: Lease leader election, EndpointSlice peer discovery, ServiceLevel-driven readiness, StatefulSet/Deployment and Service manifests, RBAC, probes, time sync, secrets, and GDS/NTRS registration.
    • Redundant Sample Integration Tests - Process-level integration tests that launch the RedundantServer / RedundantClient / RedundantPubSub sample apps and assert on their failover, reconnect, and data-loss-visibility behavior; short-haul variants run on every PR, long-haul soak variants run via dedicated manual/scheduled GitHub Actions and Azure DevOps jobs (SAMPLE_HA_DURATION_MINUTES).
  • Dependency Injection - The unified services.AddOpcUa() / IOpcUaBuilder surface for hosting OPC UA components in Microsoft.Extensions.DependencyInjection / the .NET Generic Host (servers as IHostedService, options via Action<T> or IConfiguration, AOT-friendly).
  • AuthorizationService - Modern Part 12 StartRequestToken / FinishRequestToken, ITokenIssuer, and GDS token issuance.
  • Fuzz testing - SharpFuzz + afl-fuzz + libFuzzer integration. Three areas: Encoders (Binary/JSON/XML decoders, built-in type readers, parser entry points), Certificates (X509CRL, X509 extension parsers, PEMReader, Pkcs10CertificationRequest, ASN.1 helpers), and Network (UA-SC framing via Opc.Ua.Core.Diagnostics + internal TcpMessageParsers seam on Opc.Ua.Core). The fuzz-tester custom agent drives the whole toolchain autonomously: it detects OS-available engines, runs them in parallel, fixes novel findings per repo guidelines, adds the failing input as a regression asset, and pushes one commit per fix until the user says stop.
  • KeyCredentialService - Pull, Push, and experimental bridge guidance for Part 12 KeyCredential flows.
  • xRegistry (abstract registry base model) - Generic, registry-agnostic content-addressed resource registry: IResourceContentIdProvider identity, the Opaque-NodeId fast path (resolve a resource in one Read), the CreateResource/Write/Close registration lifecycle with auto-bootstrap, federated resource proxies, and the resource-exhaustion bounds. Shipped as Opc.Ua.XRegistry, Opc.Ua.XRegistry.Client, and Opc.Ua.XRegistry.Server.
  • PubSub (Part 14) - Publisher/subscriber support library: architecture, fluent builder, transports (UDP / MQTT 3.1.1 + 5.0 / Kafka / Ethernet Layer 2), encodings (UADP / JSON), security, and server-side address space.
    • PubSub High Availability - Distributed Part 14 §9.1.6 active/standby publishers and subscribers with Cold/Warm/Hot modes, leader election or fenced leases, shared runtime checkpoints, protected SKS key storage, consistency guidance, and Kubernetes deployment notes.
    • Migration sub-doc - 1.5.378 → 2.0 breaking API, transport, JSON, and field-encoding changes, plus the compatibility matrix.
    • Ethernet transport - Layer 2 PubSub (opc.eth://, EtherType 0xB62C, 802.1Q VLAN) with native AF_PACKET / BPF, SharpPcap, and in-memory backends.
    • Kafka transport - Apache Kafka broker transport (kafka://, kafkas://) for UADP and JSON PubSub profiles with SASL/TLS and NativeAOT support on net10.0.
    • PubSub Transcoding - In-process subscriber-to-publisher transcoding with UADP/JSON cross-encoding, field/value/metadata transforms, identifier remap, receive hooks, egress, and managed UADP re-securing.
    • External server adapter - Bind PubSub publishers, subscribers, and Action responders to an external OPC UA server through ManagedSession.
    • Dependency Injection extensions - AddPubSub, AddPubSubPublisher, AddPubSubSubscriber, AddPubSubSecurityKeyServiceClient/Server, AddPubSubAddressSpace.
    • Profiles - Datagram-v2, SKS pull / push, AES-128/256-CTR security facets.
    • PubSub Diagnostics - packet capture, dissection and replay of UDP / MQTT PubSub traffic, including decryption of encrypted UADP messages.
  • Reference Client documentation for configuration of the console reference client using parameters.
  • Reference Server documentation for running against CTT.
  • ConsoleReferencePubSubClient documentation for the PubSub reference sample (publisher / subscriber / external-server adapter modes).
  • Provisioning Mode for secure certificate provisioning and initial server configuration.
  • Using the Container support of the Reference Server in Visual Studio 2026 and for local testing.

Starting with version 1.5.375.XX the Windows Forms reference client & reference server were moved to the OPC UA .NET Standard Samples repository.

Global Discovery Server (GDS)

  • GDS Developer Guide — Application registration, certificate management (pull & push models), roles and authorization, provider implementation, end-to-end examples, and a per-requirement OPC UA Part 12 conformance matrix that links every implemented ServerConfiguration/PushManagement, TrustList, certificate-alarm, KeyCredentialService and AuthorizationService requirement to its source and automated tests (with applicable profiles/conformance units and honest complete/partial/optional/unsupported marks).
  • KeyCredentialService — Credential issuance for non-OPC UA services (MQTT, REST), IKeyCredentialRequestStore provider guide, ISecretStore integration.
  • AuthorizationService — OAuth2-style access token issuance, IAccessTokenProvider implementation guide.
  • Role-Based Security — Part 18 roles and claim-based identity-mapping rules.
  • Identity Providers — server and client identity-provider architecture.
  • Dependency Injection — dependency injection hosting and identity registration extensions.