Refuses an anonymous visitor changing an anonymous-session ownership key on an EXISTING row (#4931).
An anonymous visitor's realtime session is owned through AIAgentSession.ConversationID →
Conversation.ExternalID (see AuthorizeSessionAccess in @memberjunction/server). Every anonymous
visitor shares one Anonymous user, so under a role whose row-level security filters by UserID (the
stock UI role) one visitor can load another visitor's row and would otherwise rewrite either key to
its own identity and pass the ownership gate. The key is set once, when the row is created — by
SessionManager for a server-created session and its conversation, and by the web widget for the
conversation it creates — so an insert is allowed and only a change to a saved row is refused.
Named callers are unaffected.
Refuses an anonymous visitor changing an anonymous-session ownership key on an EXISTING row (#4931).
An anonymous visitor's realtime session is owned through
AIAgentSession.ConversationID→Conversation.ExternalID(seeAuthorizeSessionAccessin@memberjunction/server). Every anonymous visitor shares one Anonymous user, so under a role whose row-level security filters byUserID(the stockUIrole) one visitor can load another visitor's row and would otherwise rewrite either key to its own identity and pass the ownership gate. The key is set once, when the row is created — bySessionManagerfor a server-created session and its conversation, and by the web widget for the conversation it creates — so an insert is allowed and only a change to a saved row is refused. Named callers are unaffected.