Skip to content
Endpoint Auto-Selection

Endpoint Auto-Selection

OPC UA servers expose multiple endpoints, each with a different combination of security policy and security mode. Endpoint auto-selection discovers all available endpoints and picks the most secure one automatically, so you don’t need to know the server’s security configuration in advance.

How It Works

When auto-selection is enabled, the client performs these steps before connecting:

  1. Opens a temporary SecureChannel with SecurityPolicy#None to the server
  2. Sends a GetEndpoints request to retrieve all available endpoints
  3. Scores each endpoint based on its security policy and mode
  4. Selects the highest-scoring endpoint that matches the URL scheme (opc.tcp)
  5. Closes the temporary channel and connects to the selected endpoint

This follows the OPC Foundation reference implementation pattern — discovery always uses an unsecured channel, then the real connection uses the discovered security settings.

Selection Algorithm

Each endpoint receives a security level score based on its security policy and mode. The endpoint with the highest score wins.

Policy Base Scores

Security PolicyBase Score
None0
Basic128Rsa152
Basic2564
Basic256Sha2566
Aes128_Sha256_RsaOaep8
Aes256_Sha256_RsaPss10
ECC_brainpoolP256r111
ECC_nistP25612
ECC_brainpoolP384r113
ECC_nistP38414
ECC_curve2551915
ECC_curve44816

Mode Modifier

Security ModeModifier
Sign+0
SignAndEncrypt+100
NoneScore is 0 regardless of policy

For example, Aes256_Sha256_RsaPss + SignAndEncrypt scores 110 (10 + 100), while ECC_curve448 + Sign scores 16 (16 + 0). SignAndEncrypt is always preferred over Sign for the same policy.

The useSecurity Toggle

The selector accepts a useSecurity parameter:

  • true (default) — only considers endpoints with Sign or SignAndEncrypt mode and a recognized security policy. Falls back to the first URL-matching endpoint if no secure endpoint is available.
  • false — only considers endpoints with SecurityMode.None. Useful for development servers or when connecting to servers that only support unsecured transport.

Client Library Usage

Enable auto-selection with the WithAutoSelectEndpoint() builder method:

// Auto-select the most secure endpoint
var client = new OpcSharpClientBuilder()
    .WithEndpoint("opc.tcp://192.168.1.100:4840")
    .WithAutoSelectEndpoint()
    .WithAutoAcceptUntrustedCertificates(true)
    .Build();

await client.ConnectAsync();

The client will discover endpoints, pick the best one, generate a self-signed application certificate if needed, and connect — all within ConnectAsync().

For development servers that only support unsecured transport:

var client = new OpcSharpClientBuilder()
    .WithEndpoint("opc.tcp://localhost:4840")
    .WithAutoSelectEndpoint(useSecurity: false)
    .Build();

await client.ConnectAsync();

You can combine auto-selection with user credentials:

var client = new OpcSharpClientBuilder()
    .WithEndpoint("opc.tcp://192.168.1.100:4840")
    .WithAutoSelectEndpoint()
    .WithUserIdentity(new UserNameIdentity("operator", "password"))
    .WithAutoAcceptUntrustedCertificates(true)
    .Build();

await client.ConnectAsync();

The selector automatically matches the user identity type to a supported UserTokenPolicy on the chosen endpoint.

CLI Tool Usage

The CLI tool uses endpoint auto-selection as the default behavior for the browse, read, and check commands. You no longer need to specify --security-policy and --security-mode manually.

# Connects using the most secure endpoint automatically
opcsharp browse opc.tcp://192.168.1.100:4840

# Same for read
opcsharp read opc.tcp://192.168.1.100:4840 i=2258

--no-security Flag

Use --no-security to force a connection without security (equivalent to useSecurity: false):

# Connect to a development server with no security
opcsharp browse opc.tcp://localhost:4840 --no-security

If you provide --security-policy or --security-mode explicitly, auto-selection is bypassed and the specified values are used directly.

Enhanced discover Output

The discover command now shows the computed security level for each endpoint and marks the auto-selected endpoint with *:

Server: My OPC UA Server
URI:    urn:myserver:opcua

┌─────────────────────────────┬──────────────────────┬──────────────────┬──────────────────┬───────┬───┐
│ Endpoint URL                │ Security Policy      │ Security Mode    │ User Tokens      │ Level │   │
├─────────────────────────────┼──────────────────────┼──────────────────┼──────────────────┼───────┼───┤
│ opc.tcp://localhost:4840    │ Aes256_Sha256_RsaPss │ SignAndEncrypt   │ Anonymous, User  │  110  │ * │
│ opc.tcp://localhost:4840    │ Basic256Sha256       │ SignAndEncrypt   │ Anonymous, User  │  106  │   │
│ opc.tcp://localhost:4840    │ Basic256Sha256       │ Sign             │ Anonymous        │    6  │   │
│ opc.tcp://localhost:4840    │ None                 │ None             │ Anonymous        │    0  │   │
└─────────────────────────────┴──────────────────────┴──────────────────┴──────────────────┴───────┴───┘

Endpoints are sorted by security level in descending order. The * marker shows which endpoint the client would auto-select.

When to Use Explicit Security

Auto-selection is the right choice for most scenarios, but there are cases where you should specify the security policy and mode explicitly:

  • Compliance requirements — your organization mandates a specific policy (e.g., only Aes256_Sha256_RsaPss or ECC policies)
  • Pinning — you want to ensure the client always uses the exact same policy, even if the server adds new endpoints
  • Debugging — you need to test a specific security configuration
  • None-only servers — if you know the server only supports None and want to skip the discovery round-trip, use WithSecurity(SecurityPolicyUris.None, MessageSecurityMode.None) directly

For explicit configuration, see the Security page.