ACL: event/alarm monitored items are revalidated by neither trigger (arch-review 03/S19 residual R1) #562

Closed
opened 2026-08-20 10:05:41 -04:00 by dohertj2 · 1 comment
Owner

Source: arch-review round 3, archreview/plans/R3-05-acl-hot-path-expiry-plan.md → Residual R1.
Discovered while closing 03/S19 (clock-driven key expiry reaching live subscriptions).

What is wrong

OtOpcUaNodeManager re-authorizes live monitored items in RevalidateMonitoredItems(), which walks
_liveItems. That map is populated only by OnMonitoredItemCreated(… ISampledDataChangeMonitoredItem …)
— i.e. data-change items.

Event / alarm monitored items are tracked by nothing. SubscribeToEvents gates an event subscription
at creation and then never again, so an alarm feed authorized under a grant (or an API key) survives:

  • a deployment that removes the grant or disables the key (the deployment axis), and
  • the key's ExpiresUtc passing (the clock axis, closed for data-change items by R3-05 / 03/S19).

An alarm subscription therefore keeps delivering after its authority is gone, until the client disconnects.

Not a regression

Pre-existing: the deploy trigger has had the same hole since #520 stage 6. R3-05 did not introduce it and
deliberately did not widen its scope to fix it — closing it needs a second tracking map keyed on
IEventMonitoredItem plus the SDK's own detach mechanics for event fan-out, which is materially more than
the timer R3-05 added.

Anchors

  • src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/OtOpcUaNodeManager.cs — OnMonitoredItemCreated
    (ISampledDataChangeMonitoredItem parameter), SubscribeToEvents (creation-time gate),
    RevalidateMonitoredItems (_liveItems walk).
  • Documented as a known gap in docs/security.md § Data-Plane Authorization ("Event/alarm monitored items
    are revalidated by neither trigger") and in CLAUDE.md's API-key/ACL section.

Suggested shape

A second tracked map for event items, revalidated by the same two triggers, standing an item down through
whatever the SDK's event fan-out equivalent of MonitoredNode.Remove(item) is — and reversibly, for the
reason a data-change denial detaches rather than setting MonitoringMode.Disabled (a disabled item can only
be re-enabled by the client, and a machine consumer has no reason to try). Needs an over-the-wire test:
whether an event monitored item can recover the identity of the session that created it is the same SDK
assumption the data-change path had to prove at the wire.

**Source:** arch-review round 3, `archreview/plans/R3-05-acl-hot-path-expiry-plan.md` → Residual **R1**. Discovered while closing 03/S19 (clock-driven key expiry reaching live subscriptions). ### What is wrong `OtOpcUaNodeManager` re-authorizes live monitored items in `RevalidateMonitoredItems()`, which walks `_liveItems`. That map is populated **only** by `OnMonitoredItemCreated(… ISampledDataChangeMonitoredItem …)` — i.e. data-change items. **Event / alarm monitored items are tracked by nothing.** `SubscribeToEvents` gates an event subscription at *creation* and then never again, so an alarm feed authorized under a grant (or an API key) survives: - a deployment that removes the grant or disables the key (the deployment axis), and - the key's `ExpiresUtc` passing (the clock axis, closed for data-change items by R3-05 / 03/S19). An alarm subscription therefore keeps delivering after its authority is gone, until the client disconnects. ### Not a regression Pre-existing: the deploy trigger has had the same hole since #520 stage 6. R3-05 did not introduce it and deliberately did not widen its scope to fix it — closing it needs a second tracking map keyed on `IEventMonitoredItem` plus the SDK's own detach mechanics for event fan-out, which is materially more than the timer R3-05 added. ### Anchors - `src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/OtOpcUaNodeManager.cs` — `OnMonitoredItemCreated` (`ISampledDataChangeMonitoredItem` parameter), `SubscribeToEvents` (creation-time gate), `RevalidateMonitoredItems` (`_liveItems` walk). - Documented as a known gap in `docs/security.md` § Data-Plane Authorization ("Event/alarm monitored items are revalidated by neither trigger") and in CLAUDE.md's API-key/ACL section. ### Suggested shape A second tracked map for event items, revalidated by the same two triggers, standing an item down through whatever the SDK's event fan-out equivalent of `MonitoredNode.Remove(item)` is — and **reversibly**, for the reason a data-change denial detaches rather than setting `MonitoringMode.Disabled` (a disabled item can only be re-enabled by the client, and a machine consumer has no reason to try). Needs an over-the-wire test: whether an event monitored item can recover the identity of the session that created it is the same SDK assumption the data-change path had to prove at the wire.
Author
Owner

Fixed: event/alarm monitored items are tracked and revalidated by both triggers (deploy + AclRevalidationTimer), stood down reversibly (detach, never Disabled). Over-the-wire tests in AclEventSubscriptionEnforcementTests. The Server-object (i=2253) path found while doing this was filed and fixed as #586. (merge 35152fca on master, pushed 2026-10-08)

Fixed: event/alarm monitored items are tracked and revalidated by both triggers (deploy + AclRevalidationTimer), stood down reversibly (detach, never Disabled). Over-the-wire tests in AclEventSubscriptionEnforcementTests. The Server-object (i=2253) path found while doing this was filed and fixed as #586. (merge `35152fca` on master, pushed 2026-10-08)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#562