ACL: Server-object (i=2253) event subscriptions bypass the data-plane ACL #586

Closed
opened 2026-10-07 23:13:41 -04:00 by dohertj2 · 1 comment
Owner

Found while closing #562 (event/alarm monitored-item revalidation).

What is wrong: an event monitored item on the Server object (i=2253) bypasses the data-plane ACL entirely — at creation and at revalidation. The SDK routes it through SubscribeToAllEvents and the core node manager's Server object, which OtOpcUaNodeManager never sees, so neither the SubscribeToEvents creation gate nor the #562 revalidation map applies.

Observed over the wire (throwaway probe, not committed): with Security:Acl:Enabled=true, an anonymous session holding no grant received a native alarm through a Server-object event item.

Why it matters: native alarms report once to the Server object (one ReportEvent, one Server-object copy — see CLAUDE.md), so this is the one feed that carries every alarm in the server, and it is ungated when ACL enforcement is on.

To do:

  • Filter events at the point the Server object delivers them to a monitored item, per the item's session identity, using the same DataPlaneAuthorizer decision as the per-folder path (the event's source / ConditionId → RawPath scope).
  • Revalidated by both triggers (deploy + AclRevalidationTimer), reversibly.
  • Over-the-wire test: no-grant session gets nothing via i=2253; granted session gets the event (positive control); revoke → stops; restore → resumes.
  • Update docs/security.md + CLAUDE.md (the residual added by #562).
Found while closing #562 (event/alarm monitored-item revalidation). **What is wrong:** an event monitored item on the **Server object** (`i=2253`) bypasses the data-plane ACL entirely — at creation and at revalidation. The SDK routes it through `SubscribeToAllEvents` and the core node manager's Server object, which `OtOpcUaNodeManager` never sees, so neither the `SubscribeToEvents` creation gate nor the #562 revalidation map applies. **Observed over the wire** (throwaway probe, not committed): with `Security:Acl:Enabled=true`, an anonymous session holding **no grant** received a native alarm through a Server-object event item. **Why it matters:** native alarms report once to the Server object (one `ReportEvent`, one Server-object copy — see CLAUDE.md), so this is the one feed that carries every alarm in the server, and it is ungated when ACL enforcement is on. **To do:** - [ ] Filter events at the point the Server object delivers them to a monitored item, per the item's session identity, using the same `DataPlaneAuthorizer` decision as the per-folder path (the event's source / ConditionId → RawPath scope). - [ ] Revalidated by both triggers (deploy + `AclRevalidationTimer`), reversibly. - [ ] Over-the-wire test: no-grant session gets nothing via `i=2253`; granted session gets the event (positive control); revoke → stops; restore → resumes. - [ ] Update docs/security.md + CLAUDE.md (the residual added by #562).
Author
Owner

Fixed: i=2253 items are delivered per condition with the same DataPlaneAuthorizer decision as the folder path (condition RawPath, notifier folders, equipment folders), the ungated folder→Server forward removed, ConditionRefresh filtered, SDK audit guard mirrored, EventsMonitored bookkeeping maintained. Independently reviewed (fix round + re-review APPROVE). Model-change/audit residual → #588. (merge 390c8269 on master, pushed 2026-10-08)

Fixed: i=2253 items are delivered per condition with the same DataPlaneAuthorizer decision as the folder path (condition RawPath, notifier folders, equipment folders), the ungated folder→Server forward removed, ConditionRefresh filtered, SDK audit guard mirrored, EventsMonitored bookkeeping maintained. Independently reviewed (fix round + re-review APPROVE). Model-change/audit residual → #588. (merge `390c8269` 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#586