An AUP tree is not an access-control list. Hiding a node, naming a data path, or rendering a button never grants a caller the right to read, write, execute, or bridge that resource.
Session substitutions have narrow semantics
$session.* has two distinct roles:
- A presentation condition can read session facts, such as
$session.authenticatedor$session.role == owner. - Path substitution occurs only in
src,bind, andpropBind, not in general props, events, or execution arguments.
For example:
input display-name
bind="/user/persons/$session.did/profile/display-name"The server performs per-session path substitution from own fields; missing values remain unresolved tokens rather than inventing an identity. The client cannot assert its own caller identity by sending a UI message.
The renderer is not the authorization authority
AFS/provider/runtime policy decides whether a resolved read, write, or exec action is allowed. UI visibility and navigation are only presentation. Likewise, validation that rejects javascript: or .. is useful input safety; it does not replace service-side permission policy.
Frames, bridges, remote surfaces, and write-capable flows each need their own trust, origin, session, and scope review. A same-looking button on two targets can still be backed by different authorization contexts.
For embedding rules, see Frames, bridges, and embedded surfaces. For data-binding semantics, see Events, state, and bindings.