QA finding
The collaboration panel already lists participants, but the browser currently generates actorId, userId and displayName locally and lets the user edit all three before joining. The server accepts this self-asserted actor object from the request. Consequently, a displayed value is not a verified login name and can be impersonated or collide with another browser identity.
The current participant row also emphasizes the internal actorId, while role, verification, connection health and last activity are not presented as first-class information.
Decision
Participants should be visible in a shared session, but the UI must distinguish:
- a user-facing display name;
- an optional authenticated and verified account handle;
- an anonymous/self-asserted pseudonym;
- the per-client actor/device identity used for operation scoping.
Do not label an editable or browser-generated value as a login name. Do not expose stable internal userId values by default.
Identity model
Introduce an identity projection with explicit provenance, for example:
subjectId — stable server-side account subject, never directly editable;
actorId — stable identity of one browser/client instance;
displayName — user-facing name;
accountHandle — optional verified login/handle suitable for disclosure;
provenance — ANONYMOUS, SELF_ASSERTED, AUTHENTICATED;
verified — derived server-side, never accepted from request JSON;
role — owner/editor/viewer or future permission role;
- optional avatar/color that contains no authorization meaning.
Authenticated mode must derive account identity from the server security principal. Anonymous mode may retain a generated pseudonym but must display it as unverified.
Server requirements
- Never trust
userId, handle, role or verification supplied by a client.
- Bind operations and session membership to the authenticated subject or an anonymous server-issued token.
- Prevent actor-id takeover and duplicate active actor identities.
- Define reconnect semantics for the same account in multiple tabs/devices.
- Preserve immutable actor/account attribution in history without leaking unnecessary personal data.
- Add configurable privacy policy for whether account handles are shown to other participants.
UX requirements
Participant rows should show:
- display name;
You marker for the current client;
- owner/editor/viewer role;
- verified handle only when authenticated and allowed by policy;
- verification/anonymous indicator;
- live, reconnecting, idle or offline status;
- last-seen or last-operation time when not live;
- optional current activity such as selected node or executing run, using bounded presence fields.
Internal actorId and userId belong in an expandable diagnostic view, not the primary row.
Remote presence attributes must be rendered through an allow-listed model instead of dumping arbitrary key/value pairs directly into the UI.
Tests
- a client cannot mark itself verified or choose another account subject;
- two anonymous users with identical display names remain distinguishable;
- reconnect retains attribution without creating a false duplicate participant;
- multi-tab same-account behavior is explicit and deterministic;
- anonymous and authenticated rendering are visually distinct;
- account handle visibility follows privacy policy;
- stale presence expires while durable membership/history remains correct;
- history attribution survives restart without exposing secrets or bearer tokens.
Acceptance criteria
- Users can confidently identify who is currently collaborating with them.
- The UI never presents a self-asserted value as a verified login.
- Authorization and attribution are based on server-derived identity.
- Participant presence remains understandable without exposing internal identifiers by default.
QA finding
The collaboration panel already lists participants, but the browser currently generates
actorId,userIdanddisplayNamelocally and lets the user edit all three before joining. The server accepts this self-asserted actor object from the request. Consequently, a displayed value is not a verified login name and can be impersonated or collide with another browser identity.The current participant row also emphasizes the internal
actorId, while role, verification, connection health and last activity are not presented as first-class information.Decision
Participants should be visible in a shared session, but the UI must distinguish:
Do not label an editable or browser-generated value as a login name. Do not expose stable internal
userIdvalues by default.Identity model
Introduce an identity projection with explicit provenance, for example:
subjectId— stable server-side account subject, never directly editable;actorId— stable identity of one browser/client instance;displayName— user-facing name;accountHandle— optional verified login/handle suitable for disclosure;provenance—ANONYMOUS,SELF_ASSERTED,AUTHENTICATED;verified— derived server-side, never accepted from request JSON;role— owner/editor/viewer or future permission role;Authenticated mode must derive account identity from the server security principal. Anonymous mode may retain a generated pseudonym but must display it as unverified.
Server requirements
userId, handle, role or verification supplied by a client.UX requirements
Participant rows should show:
Youmarker for the current client;Internal
actorIdanduserIdbelong in an expandable diagnostic view, not the primary row.Remote presence attributes must be rendered through an allow-listed model instead of dumping arbitrary key/value pairs directly into the UI.
Tests
Acceptance criteria