Repository navigation
Security Policies
Applies to Milo 1.2.0-RC1. Source baseline 69cb25087, 2026-10-12.
This page lists the security policies Milo supports, the application certificate each one needs, and the rules that pair user tokens with channels. Use it when you choose an endpoint's policy and mode, provision certificates, or work out why a handshake or token was rejected.
Choose a policy that both applications can run with their installed certificates and cryptographic providers, because recognizing a policy URI does not mean a peer supports it or that your runtime can use it. Configure trust as described in Client security and Server security before connecting.
A secured endpoint combines two choices. The security policy fixes the algorithms and the application certificate type, and the message security mode fixes how much protection each message gets.
SecurityPolicy identifies the policy URI. SecurityPolicyProfile describes its certificate, authentication, key agreement, and message-protection requirements, and getProfile() returns it when application code needs those details. isLegacy() and the optional find...Algorithm() accessors help distinguish legacy algorithm availability. Enhanced profiles do not populate all legacy algorithm getters, so do not iterate the enum and dereference those getters unconditionally.
The endpoint's MessageSecurityMode is a separate selection:
| Mode | Protection |
|---|---|
None |
No channel confidentiality or integrity |
Sign |
Authenticates applications and protects message integrity, without confidentiality |
SignAndEncrypt |
Also protects confidentiality |
ECC and RSA-DH policies accept only Sign and SignAndEncrypt, and EndpointConfig rejects other pairings at build time.
The loopback tutorials use None only to introduce the SDK without provisioning certificates. For a deployed application, choose a secured endpoint that meets your requirements and configure certificate validation. Silently falling back to None changes the application's security.
Use this table to match a policy to the application certificate it needs. The certificate types are constants in NodeIds. Select the exact advertised policy URI and a mode that both applications support.
| Policy or family | Application certificate type | Cryptographic requirements |
|---|---|---|
None |
No application certificate required by the channel | No channel security. Token policies can still require a server certificate. |
Basic128Rsa15, Basic256
|
RsaSha256ApplicationCertificateType or RsaMinApplicationCertificateType
|
Legacy RSA policies deprecated by OPC UA |
Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss
|
RsaSha256ApplicationCertificateType |
RSA identity and matching legacy policy algorithms |
ECC_nistP256 or ECC_nistP384, with _AesGcm or _ChaChaPoly
|
EccNistP256ApplicationCertificateType or EccNistP384ApplicationCertificateType
|
ECDSA identity on the corresponding NIST curve, matching key agreement and AEAD primitives |
ECC_brainpoolP256r1 or ECC_brainpoolP384r1, with either suffix |
EccBrainpoolP256r1ApplicationCertificateType or EccBrainpoolP384r1ApplicationCertificateType
|
Matching Brainpool ECDSA identity and Milo's Bouncy Castle provider profile |
ECC_curve25519 or ECC_curve448, with either suffix |
EccCurve25519ApplicationCertificateType or EccCurve448ApplicationCertificateType
|
Ed25519 or Ed448 application certificate and matching key agreement and AEAD primitives |
RSA_DH_AesGcm or RSA_DH_ChaChaPoly
|
RsaSha256ApplicationCertificateType |
RSA identity, ffdhe3072 key agreement, HMAC-SHA256, and the selected AEAD cipher |
The full URI prefix is http://opcfoundation.org/UA/SecurityPolicy#. For example, the NIST P-256 AES-GCM policy is http://opcfoundation.org/UA/SecurityPolicy#ECC_nistP256_AesGcm. Milo does not recognize the suffix-less #ECC_nistP256 URI, so two products that advertise different URIs have no common ECC policy, even if both use P-256 cryptography. The table describes this source baseline, not a vendor-interoperability or certification result.
Milo classifies an application certificate by more than its key algorithm. A SHA-1-signed RSA application certificate is classified as RsaMin, so a client that selects it for Basic256Sha256 fails locally with Bad_ConfigurationError. Choosing an RSA key alone does not make a certificate compatible.
Milo bundles bcprov-jdk18on, so applications do not need to register Bouncy Castle to use these policies. The default resolver prefers the bundled provider for enhanced policies and falls back to JDK primitives when available. Brainpool requires Bouncy Castle on the classpath. Its certificate-path validation also registers BC at the lowest JVM provider precedence, which is a process-wide side effect.
Use this procedure when you add a secured endpoint.
- Provision the key pair and certificate chain in a
CertificateManagergroup. Match the certificate type to the policy and the certificate ApplicationUri to the application configuration. - On the server
EndpointConfigbuilder, callsetSecurityPolicyandsetSecurityMode. By default the server selects the endpoint certificate from the DefaultApplicationGroup of itsCertificateManager, with the certificate type the policy chooses. CallsetEndpointCertificateConfigto request a different certificate group or type, orsetCertificateto advertise a fixed certificate instead. - Discover endpoints and require the intended policy and mode. Configure the client with
setCertificateGrouporsetCertificateIdentity, and usesetCertificateTypeIdwhen selecting a specific type. Configure its validator and user identity separately. - Establish a Session, perform an authorized operation, and test rejection with an untrusted peer and an unauthorized user. GetEndpoints tests discovery, not authentication or data access.
The server resolves every secured endpoint at startup, and the checks depend on how the endpoint gets its certificate:
| Endpoint certificate setup | Startup checks |
|---|---|
Managed selection: setEndpointCertificateConfig, or no setCertificate
|
The security provider resolves, and the certificate group holds a compatible identity. If you also call setCertificate, that certificate must be the identity selected. |
setCertificate without setEndpointCertificateConfig, enhanced policy |
The security provider resolves, and the fixed certificate is compatible with the policy |
setCertificate without setEndpointCertificateConfig, legacy policy |
The security provider resolves. The fixed certificate is then advertised without managed identity checks. |
If a check fails, the endpoint is neither advertised nor bound. Look for the WARN message "Omitting endpoint advertisement" and its reason. Because the legacy fixed-certificate path skips identity checks, verify the actual handshake.
When an endpoint is missing or a handshake fails, fix the configuration instead of weakening the client. For example, an RSA certificate cannot authenticate a channel on a NIST ECC endpoint, so fix the certificate and profile pairing instead of disabling validation. If an endpoint is missing from discovery, inspect the server configuration and the provider and certificate diagnostics before changing the client selector.
Read this when you configure username, certificate, or issued tokens. Application certificates and user certificates serve different roles, and each user-token policy carries its own security policy that must fit the channel. UsernameProvider and X509IdentityProvider choose from the advertised user-token policies that their identity can use, so a secured channel alone does not make every token policy compatible.
The token policy's securityPolicyUri decides how the password is protected:
| Token policy securityPolicyUri | Rule |
|---|---|
| Explicit, not None, on a secured channel | Must use the channel's RSA or ECC public-key family. Legacy RSA token policies on ECC channels fail with Bad_SecurityPolicyRejected. |
| Inherited | Uses the channel policy |
| Explicit None | Exempt from the family rule. The password is unencrypted at the token layer. |
| Inherited, on a None endpoint | The password is unencrypted at the token layer |
On a Sign-only or None channel, an unencrypted password crosses the wire in cleartext.
The server convenience constant OpcUaServerConfig.USER_TOKEN_POLICY_USERNAME explicitly selects Basic256Sha256, so it is not suitable for an ECC channel.
By default, UsernameProvider chooses the first usable advertised username policy. Explicit None counts as usable, so it can be selected ahead of encrypted policies without a warning. For policy None, channel and CreateSession checks also skip the validator from setCertificateValidator or the certificate group, so on a None endpoint only a validating CertificateValidator, such as DefaultClientCertificateValidator, passed to UsernameProvider checks the certificate that encrypts the password. Client security shows how to keep the password encrypted with a SignAndEncrypt endpoint or a policyChooser. See also UsernameProvider and Client connecting.
A None endpoint that offers encrypted username tokens under an RSA token policy needs a server certificate. Without one, the server warns when it resolves the endpoint at startup, and a Milo client fails locally with Bad_ConfigurationError before sending the encrypted token. Provision the certificate before advertising this combination, and do not rely on server-side token rejection to detect the misconfiguration. See Endpoints and user token policies for migration details.
Enhanced secret-protection policies require a secured channel. An enhanced certificate-token policy cannot run on a legacy secured channel, and a client with no compatible certificate-token policy fails with Bad_IdentityTokenRejected.
Milo has no built-in client issued-token provider. A server application can override AbstractIdentityValidator.validateIssuedIdentityToken(...), whose default rejects tokens with Bad_IdentityTokenInvalid. This path does not invoke UserTokenSecurityPolicyRules, despite that helper's broad Javadoc wording, so the application override owns the issued token's policy compatibility, protection, signature, and identity validation. See the server validation entry point.
These gaps apply at this baseline:
| Limitation | What to do |
|---|---|
A Milo client using Reverse Connect (ReverseTcpClientTransport) does not supply the SecureChannel thumbprint that ECC and RSA-DH Session signatures require |
Use client-initiated (forward) OPC TCP for those policies. See Reverse Connect. |
| The server uses a fixed security provider resolver and exposes no application setting for provider preference | No workaround. Plan for the default provider order described under Cryptographic providers. |
This guide's secured examples use Basic256Sha256. For other policies and token types in code, see the project tests EccSessionIntegrationTest, X509PolicySelectionTest, and UserTokenSecurityPolicyRulesTest.
Use the client security and server security workflows for identity and trust setup. Keep private keys, trust stores, and certificate-group resources under application ownership, and close their watchers after all users have stopped.
- Security policy and certificate contracts
- Policy profiles and certificate types
- Provider resolution
- SecurityPolicy
- Server endpoint resolution
A policy is one of several settings you choose before a client or server starts. For the builder settings, defaults, and limits that go with it, continue with the Configuration reference.
Related: Reference · Client security · Server security · Troubleshooting
User guide for Milo 1.2.0-RC1 at source 69cb25087, 2026-10-12. Home · Getting started · Examples · Troubleshooting · Release notes
- Home
- Start here
- Client guide
- Server guide
- Feature guides
- Reference
- Operations
- Examples
- Release notes
- Contributing