docs(acl): record the shared-root-folder browse-transit mapping
CLAUDE.md's "Browse needs ancestor visibility" bullet and docs/security.md's ancestor-visibility bullet now name the topmost ancestor: the single shared root folder (s=OtOpcUa, raw namespace) that both realm trees hang under, its mapping onto the trie's zero-segment realm-root scope, the either-realm transit (it fronts both trees), and the realm qualification. Also corrects the adjacent security.md bullet that claimed "the two namespace root folders remain visible" — there is one anchor, not one per namespace, and what an ungranted session sees is the ns=0 Objects listing of it rather than a browse into it. Flagged rather than silently left, since it contradicts the mechanism the new bullet documents.
This commit is contained in:
+14
-3
@@ -427,12 +427,23 @@ Behaviours worth knowing before enabling it:
|
||||
what this necessarily discloses — the *names* of the folders on the path to a granted node are visible
|
||||
to whoever holds that grant. It is conferred only by grants that actually carry `Browse`, and it
|
||||
confers nothing but `Browse`.
|
||||
- **…including the shared root folder every browse starts at.** Both realm trees hang under a single
|
||||
anchor folder (`s=OtOpcUa`, minted in the **raw** namespace by `CreateAddressSpace`; top-level raw
|
||||
folders and top-level UNS areas alike parent under it). Its identifier is a display name rather than
|
||||
a path, so splitting it produced a segment no grant path can contain, and the Browse gate refuses the
|
||||
*whole* call when its source node is denied — every narrow `Browse` grant was therefore unreachable
|
||||
by navigation, denied at the front door. The gate maps that one identifier onto the trie's
|
||||
zero-segment **realm-root** scope, and because the anchor fronts both trees its browse considers
|
||||
transit in **either** realm: a principal whose only grant lives in the UNS tree still enters through
|
||||
this raw-namespace node. The mapping is realm-qualified — in the UNS namespace `s=OtOpcUa` is an
|
||||
ordinary Area an operator happened to name that way and is evaluated as the path it is.
|
||||
- **A denied node reports `BadUserAccessDenied` rather than `BadNodeIdUnknown`**, because the gate runs
|
||||
before node resolution. That is the information-hiding direction — error codes can no longer be used
|
||||
to enumerate the address space — but it does mean "access denied" is not evidence the node exists.
|
||||
- **The two namespace root folders remain visible** to any admitted session. They are referenced from
|
||||
the ns=0 `Objects` folder, whose browse the SDK's own node manager serves; a session with no grants
|
||||
sees the two roots and is refused on entry.
|
||||
- **The shared root folder remains *listed*** for any admitted session. It is referenced from the ns=0
|
||||
`Objects` folder, whose browse the SDK's own node manager serves, so a session with no grants sees the
|
||||
anchor in that listing — and is refused the moment it tries to browse *into* it (the transit above is
|
||||
what a granted session enters on). There is one anchor, not one per namespace.
|
||||
|
||||
#### Cost
|
||||
|
||||
|
||||
Reference in New Issue
Block a user