ACL: an expired API key keeps its session's roles while Security:Acl:Enabled is false (arch-review 03/S19 residual R2) #563
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Source: arch-review round 3,
archreview/plans/R3-05-acl-hot-path-expiry-plan.md→ Residual R2.Discovered while closing 03/S19.
What is wrong
With
Security:Acl:Enabled = false— the default — there is no per-operation API-key check anywhere inthe server.
DataPlaneAuthorizerreports itself disabled, every seam falls back to its server-wide rolecheck, and
RevalidateMonitoredItemsearly-returns on!AclEnforced.Consequence: a session's roles are resolved once, at activation, from
ApiKeyInterimRoleMapper.Map(grants, principal). When that key'sExpiresUtcpasses, the open sessionkeeps whatever roles it was given —
WriteOperate,AlarmAck— until the client disconnects. On amachine-to-machine data plane that can be indefinite.
With the flag on, this is closed:
Evaluatere-checkssnapshot.FindUsableKey(keyId, now)against theauthorizer's clock on every operation, and (since R3-05) a timer carries the same verdict to live
subscriptions.
Why R3-05 did not fix it
Closing it means gating on key usability independently of ACL enforcement — i.e. changing behaviour on
the default configuration, for every deployment that has not opted into
Security:Acl:Enabled. That is aseparate decision from the two 03/S18+03/S19 fixes, which were both designed to be inert when the flag is
off, so it was named as a residual rather than folded in.
Anchors
src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/Security/DataPlaneAuthorizer.cs—Enabled, and thesnapshot.FindUsableKey(keyId, now)re-check insideEvaluatethat only runs when enforcing.src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/OtOpcUaNodeManager.cs—RevalidateMonitoredItems'sif (!AclEnforced …) return;.src/Server/ZB.MOM.WW.OtOpcUa.Host/OpcUa/ApiKeyInterimRoleMapper.cs— where the activation-time rolescome from.
Suggested shape
A key-usability check on the two role gates (
WriteOperateon Value writes,AlarmAckon the Part 9methods) that runs regardless of
Security:Acl:Enabled— reading the same artifact snapshot the authorizerdoes, so it costs one dictionary probe and no I/O. Decide explicitly whether it also applies to Anonymous
sessions (which carry no key and so cannot expire) and whether it needs its own flag for the rollout.
Fixed: key usability (FindUsableKey on the deployed snapshot) now gates WriteOperate value writes and AlarmAck methods regardless of Security:Acl:Enabled; anonymous unaffected; no new flag. Note: on a fused node a key minted after the last deploy cannot write/ack until a deployment carries it (same as flag-on). Tests: NodeManagerKeyUsabilityGateTests. (merge
35152fcaon master, pushed 2026-10-08)