You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(agents): share chats with permissions (#4505)
## Motivation
Entity permission enforcement is now in place, and the users table is
populated for tenant-scoped identity lookup. This PR exposes that
capability in the agents UI so a chat manager can grant access to
specific users or all users in the workspace without manually working
with principal URLs or grant APIs.
It also tightens the client-side auth and affordances around those
permissions so non-managers do not see sharing controls, non-writers
cannot send or signal, and shared sessions are recognizable in the
sidebar.
## Changes
- Adds a server-defined, tenant-scoped `users` Electric shape and a
`usersCollection` in the agents UI provider for names, emails, and
avatars.
- Limits synced users columns to display-safe fields: id, display name,
email, avatar URL, and timestamps.
- Adds an `entity_effective_permissions` Electric shape and UI hooks for
checking current-principal permissions against a chat.
- Adds a chat sharing dialog that can grant roles to a selected user
principal or to all workspace users via `subject_kind: principal_kind`
and `subject_value: user`.
- Maps sharing roles onto backend permissions explicitly: `View` grants
`read` and `fork`; `Chat` grants `read`, `write`, `signal`, `fork`,
`schedule`, and `spawn`; `Manage` grants `manage` and `delete`.
- Resolves user principals consistently from raw `user:<id>` keys and
`/principal/...` URLs so the current user is filtered from individual
sharing, message metadata renders `Me`, and creator checks do not depend
on principal encoding.
- Displays synced user names for user principals in message metadata,
share rows, sidebar creator filters, and sidebar hover cards when
available.
- Adds a small `Users` shared marker to sidebar rows for sessions
created by another principal, plus a `Created by` sidebar filter with
`Me` pinned first.
- Gates UI actions using effective permissions: share is only visible
with manage access; fork, send, stop/signal, pending-message controls,
and signal menu actions are disabled when the current principal lacks
the corresponding permission.
- Gives forked chats `created_by` for the principal that clicked fork,
so the new fork is controlled by its creator rather than the original
chat owner.
- Shows the signed-in Cloud user's principal key under Account settings
for debugging.
- Injects the signed-in Cloud user as the Electric principal for
Cloud-targeted desktop requests, removes the legacy
`x-electric-asserted-user-id` header, removes saved Cloud servers on
logout so re-login refreshes stale service tokens, and avoids logging
injected auth headers.
- Adds focused coverage for principal normalization, share role
mappings, users/effective-permissions shapes, fork ownership, Cloud auth
header injection, and desktop server fetch auth injection.
- Adds a changeset for `@electric-ax/agents-desktop`,
`@electric-ax/agents-server`, and `@electric-ax/agents-server-ui`.
## Decisions
The sharing UI creates explicit grants for every permission implied by a
role instead of relying on backend permission implication. That keeps
product-level roles transparent: for example, workspace “view” sharing
can grant both `read` and `fork` even though `read` itself does not
imply `fork`.
“All users” sharing uses the existing principal-kind permission
mechanism rather than synthetic user rows. Workspaces are siloed, so
`principal_kind:user` means every user principal in the current tenant,
not cross-workspace sharing.
Permission gates in the UI are affordance controls, not the source of
truth. Server-side permission checks still decide whether grant, signal,
fork, spawn, and mutation APIs are allowed.
Cloud desktop auth headers are merged after saved server headers so the
signed-in Cloud user wins over stale saved `Electric-Principal` values.
The sidebar shared marker only appears when `created_by` is present and
differs from the current normalized principal. Missing creator data is
left unmarked rather than inferred.
---------
Co-authored-by: Kyle Mathews <mathews.kyle@gmail.com>
Expose tenant-scoped users as an Electric shape and add a chat sharing dialog that grants user principals or all workspace users view, chat, or manage permissions over an entity. View/chat sharing includes fork access, forked chats are owned by the principal that creates the fork, shared chats can be identified and filtered by creator in the sidebar, and Cloud requests now inject the signed-in user as the Electric principal.
9
+
10
+
Mobile now syncs the users and effective-permissions shapes, marks and filters shared chats by creator, disables native chat and signal controls when the current principal lacks permission, and shows the signed-in user principal on the Account screen for debugging.
0 commit comments