Choose the workspace boundary
A workspace is where sessions, files, knowledge, connections, and integrations are shared. Pick it from who may share those things:
A workspace is configuration, not a running machine. Hundreds of workspaces are normal. Call
ensureWorkspace with a stable externalSource and externalId and persist the returned id; repeat calls return the same workspace.
Onboard users
Make each user a member once, when your product admits them, not on every request:files:upload and files:read for attachments and mcp_servers:attach for per-session tools. To change permissions, revoke with cancelExternalWorkspaceMemberGrant (this also cancels the user’s running turns) and add the member again with a new operationId.
Use the same source everywhere: onboarding, asUser, and the proxy’s resolve.
Choose who shares chats
Setchats on the session proxy or the chat facade:
- Private chats need private sessions enabled for your organization. Without it the SDK throws
OpenGeniSetupError, which says who can turn it on and where. "isolated"gives each user their own workspace. Pass theOpenGenifacade from@opengeni/sdk/chatto the proxy and return{ tenant, user }fromresolve;og.workspaceIdFor({ tenant, user }, { isolation: "user" })provisions the workspace and membership.chatssetsvisibility,agentAccess, andmemoryScopeon sessions it creates. Values yourcreateSessionhook returns still win, and OpenGeni still authorizes each one.
What is enforced where
OpenGeni enforces: workspace membership on every call, private session ownership, the agent’s session reach, and each member’s permissions intersected with your API key’s. Your product enforces: who your users are, which tenant they belong to, and which conversations they may open. Use the proxy’sresolve for identity and authorizeSession for per-session checks, and authorize every tool call in your own API.
The organization API key can read every session in the organization’s shared workspaces. Keep it on your server.