OPC UA Sessions and SecureChannels: Renew Security Without Losing Application State

A SecureChannel supplies protected message transport; a Session supplies application-level state and user association. Renewing a channel’s SecurityToken normally keeps the same channel and Session. Recovering through a new channel requires the surviving Session to be associated through ActivateSession. Creating a new Session on every token renewal confuses two lifecycles and can unnecessarily disrupt application state.

This guide pins OPC UA Part 4, Services, version 1.05.07, published 15 April 2026. The main scope is a secured, nonanonymous client/server connection with a supported communication mapping. No OPC UA SDK, server, certificate, renewal or reconnect experiment was executed; the procedures below are source-derived qualification plans.

Keep identifiers and lifetimes in separate records

Object Useful diagnostic identity Lifetime or transition
SecureChannel Channel identifier and security configuration Can contain successive SecurityTokens
SecurityToken Token identifier, creation time, revised lifetime Renew before expiry under the protocol’s overlap rules
Session Session identifier and redacted local reference Negotiated inactivity timeout or explicit closure
Application work Operation identity and known completion boundary Independent reconciliation after interruption

CreateSession returns both a sessionId and an authenticationToken. The former supports identification and diagnostics; the latter associates requests with the Session. Do not confuse the Session authenticationToken with a channel SecurityToken. Keep raw authentication tokens and private-key material out of exported diagnostic logs.

Session S remains associated with channel A while SecurityToken T1 renews to T2. After channel interruption, new channel B cannot use S until valid ActivateSession succeeds. Acceptance moves S to B and causes old-channel requests to be rejected; an expired Session follows a separate new-session recovery path.
Token renewal, channel replacement and Session replacement are different transitions. Preserve Session state only when its lifetime and activation checks permit it.

Renew the token rather than recreating the Session

OpenSecureChannel parameters, section 5.6.2.2, distinguish ISSUE for a new channel from RENEW for an existing channel. The returned revisedLifetime, rather than the requested lifetime, governs the client’s renewal planning. RENEW creates a new SecurityToken for the existing channel identifier.

Section 5.6.2.1 recommends requesting the new token after seventy-five percent of its lifetime has elapsed. It also defines transition behavior intended to tolerate clock differences and network latency. The server continues using its existing token until it expires or a message arrives secured with the new token; clients should accept expired-token messages for up to twenty-five percent of the token lifetime.

These recommendations are not a measured scheduling guarantee. Use the stack’s supported renewal mechanism and test its actual mapping, timers and token overlap. Do not implement an unqualified background timer that overwrites keys while another thread is still decoding an old-token response.

Keep the Session timeout independent

CreateSession, section 5.7.2.1, makes Sessions independent of the underlying communications connection. Losing that connection does not immediately terminate the Session. However, the server terminates an inactive Session when the client does not issue a Session Service request within the negotiated timeout.

Do not assume that channel renewal alone refreshes the Session’s activity. OpenSecureChannel uses a null Session authenticationToken, and its security-token lifetime is a different contract. Record both lifetimes and the activity that actually keeps each object valid.

For a hypothetical client, a requested token lifetime of 60,000 milliseconds might be revised to 40,000. The nominal seventy-five-percent point is then 30,000 milliseconds into that token’s lifetime, not into the requested lifetime and not automatically thirty seconds after a delayed response is received. The Session’s negotiated inactivity budget must be tracked separately.

Associate a replacement channel explicitly

When recovery creates a new SecureChannel while the Session survives, call ActivateSession through the new channel according to the selected SDK. Do not simply reuse the old Session authenticationToken in arbitrary service calls and assume the server will infer migration.

ActivateSession, section 5.7.3.1, requires the first activation to use the channel associated with CreateSession. Later activation can use another channel, but the server checks the same client certificate, the same ClientUserId and matching SecurityPolicy and SecurityMode for that migration.

Once the server accepts the new channel, it rejects requests through the old channel. Treat successful activation as the ownership transition in the client: update the active channel association through one serialized owner, and stop submitting new Session work through the previous path.

Changing credentials or security policy while reconnecting is not automatically a valid Session migration. If the required checks cannot be met, use the approved new-Session recovery procedure rather than weakening certificate or identity checks to force continuity.

Handle expired state and uncertain work separately

If the Session has already expired, opening a fresh channel does not recreate it. Classify failed activation, expired Session and channel-token failure separately. They lead to different recovery decisions and should not all become a generic “connection restored” event.

Preserving a Session also does not prove that every interrupted application operation completed or failed. Record outstanding operation identities and their last established result. Avoid automatically repeating consequential writes merely because a replacement channel became active.

Subscriptions have their own lifetime and recovery rules. Do not claim that every Session termination immediately deletes every Subscription, or that a new Session automatically inherits them. Subscription transfer and notification-gap recovery require their own qualified procedures beyond this channel/Session boundary.

A lifecycle acceptance campaign

  1. Record channel, token and Session identifiers, requested and revised lifetimes, selected security configuration and SDK versions.
  2. Exercise ordinary token renewal while benign reads continue. Verify a changed token identifier without unnecessary Session recreation.
  3. Delay renewal responses within the isolated test setup and inspect the stack’s old/new token transition and failure reporting.
  4. Interrupt communication briefly, create a replacement channel and activate the surviving Session with unchanged permitted identity and security parameters.
  5. Verify old-channel requests are rejected after successful reassociation, without submitting real actuator operations.
  6. Repeat beyond the Session timeout and with a deliberately incompatible migration identity in the lab. Confirm recovery does not falsely claim Session continuity.

Acceptance requires each observed transition to match the correct object’s lifetime. Archive redacted identifier timelines and application-result evidence, not just a reconnect counter. The design is understandable when an engineer can explain whether a failure lost a token, a channel, a Session or only an operation’s completion evidence.

Similar Posts