SDK 2.0.1: API-key logins fail (BadIdentityTokenInvalid) when the client clock is >5 min ahead of the server #873

Closed
opened 2026-11-11 16:34:48 -05:00 by dohertj2 · 2 comments
Owner

Found by the #800 partial Windows validation on windev (master 88698ca0, SDK 2.0.1, self-contained win-x64, 2026-11-11).

Symptom: every API-key login from the Mac to the server on windev failed with BadIdentityTokenInvalid. The same key from a client on windev itself was accepted, and so was a Mac→Mac connection.

Cause: with SDK 2.0.1, a client whose password is over 64 bytes encrypts it as RsaEncryptedSecret, which carries a signing time. OtOpcUa API keys are 65 characters, so every SDK 2 client now does this. The 2.0.1 server (EncryptedSecret.cs) rejects the token if the client's signing time is more than 5 minutes ahead of the server's clock or more than 1 hour behind it. windev's time service is stopped and its clock was 549 s slow. SDK 1.5 clients use the old format and are unaffected.

Impact: on any SDK 2 server, API-key logins depend on client and server clocks agreeing within 5 minutes in that direction. This covers our CLI, the OpcUaClient driver, and ScadaBridge once it moves to SDK 2 (ScadaBridge#125). Before upgrading VD03 or QA, check the Windows time service and clock offset on both server and client hosts. Document this in the SDK 2 rollout runbook and docs/security.md, and consider a startup health warning.

Found by the #800 partial Windows validation on windev (master `88698ca0`, SDK 2.0.1, self-contained win-x64, 2026-11-11). **Symptom:** every API-key login from the Mac to the server on windev failed with `BadIdentityTokenInvalid`. The same key from a client on windev itself was accepted, and so was a Mac→Mac connection. **Cause:** with SDK 2.0.1, a client whose password is over 64 bytes encrypts it as `RsaEncryptedSecret`, which carries a signing time. OtOpcUa API keys are 65 characters, so every SDK 2 client now does this. The 2.0.1 server (`EncryptedSecret.cs`) rejects the token if the client's signing time is more than 5 minutes ahead of the server's clock or more than 1 hour behind it. windev's time service is stopped and its clock was 549 s slow. SDK 1.5 clients use the old format and are unaffected. **Impact:** on any SDK 2 server, API-key logins depend on client and server clocks agreeing within 5 minutes in that direction. This covers our CLI, the OpcUaClient driver, and ScadaBridge once it moves to SDK 2 (ScadaBridge#125). Before upgrading VD03 or QA, check the Windows time service and clock offset on both server and client hosts. Document this in the SDK 2 rollout runbook and docs/security.md, and consider a startup health warning.
dohertj2 added the type:bugpriority:p2 labels 2026-11-11 16:34:48 -05:00
Author
Owner

Documented on master: a clock-sync prerequisite in docs/plans/2026-11-10-opcua-sdk-2-rollout.md (Operating constraints) and a note in docs/security.md. The refusal is now visible in the server log (#874). This stays open as an operational item: check w32tm /query /status on VD03 and every SDK 2 client host before the OtOpcUa SDK 2 deploy. A startup check is not possible server-side, because the server never sees a client's clock until it logs in.

Documented on master: a clock-sync prerequisite in `docs/plans/2026-11-10-opcua-sdk-2-rollout.md` (Operating constraints) and a note in `docs/security.md`. The refusal is now visible in the server log (#874). This stays open as an operational item: check `w32tm /query /status` on VD03 and every SDK 2 client host before the OtOpcUa SDK 2 deploy. A startup check is not possible server-side, because the server never sees a client's clock until it logs in.
Author
Owner

Closing: docs landed on master (rollout runbook Operating constraints + docs/security.md), the refusal is logged (#874), and the vd03 clock was checked during the #793 upgrade (agrees with the Mac within seconds, w32tm source recorded in docs/deploy/vd03-upgrade-b8b4c18f-to-master.md). The remaining per-host clock check for QA vq03/vq04 and every SDK 2 client host is a deploy precondition and belongs to the SDK2 rollout gates #800/#801.

Closing: docs landed on master (rollout runbook Operating constraints + docs/security.md), the refusal is logged (#874), and the vd03 clock was checked during the #793 upgrade (agrees with the Mac within seconds, w32tm source recorded in docs/deploy/vd03-upgrade-b8b4c18f-to-master.md). The remaining per-host clock check for QA vq03/vq04 and every SDK 2 client host is a deploy precondition and belongs to the SDK2 rollout gates #800/#801.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#873