Skip to content

feat(coderd): support creating chats on behalf of another user - #29576

Closed
bpmct wants to merge 1 commit into
mainfrom
ben/codagt-132-chats-on-behalf-of-user
Closed

bpmct wants to merge 1 commit into
mainfrom
ben/codagt-132-chats-on-behalf-of-user

Conversation

@bpmct

@bpmct bpmct commented Sep 18, 2026

Copy link
Copy Markdown
Member

Adds POST /api/v2/users/{user}/chats, modeled directly on the existing POST /api/v2/users/{user}/workspaces (postUserWorkspaces): same httpmw.ExtractOrganizationMembersParam middleware, same "authz story" (permission checked on the owner-scoped resource, not on the User object). The target user becomes the chat's owner; the caller who made the request is the initiator recorded in the audit log. This is not chat sharing.

Fixes CODAGT-132

Unlike postUserWorkspaces, a chat's RBACObject is org-scoped (InOrg(OrganizationID)), so the owner must always belong to the requested organization, or they could never read or use their own chat afterward. postUserWorkspaces tolerates an owner outside the org because a template pins the org; that doesn't apply here.

A caller who can act on behalf of another user (typically a site owner) also cannot bind the resulting chat to a workspace the owner has no SSH access to, even if the caller itself administers that workspace. Ownership equality is used as a conservative proxy for "the owner can use this workspace," except when the path already resolves to the caller themselves (e.g. the me alias), which behaves exactly like the existing self-service /chats route.

Review notes

Spawned a Fable 5.1 review pass against the diff before opening this PR. It found two real gaps that are fixed here:

  1. A caller who could read the target user's User object (site owners) skipped the organization-membership check entirely, so a chat could be created for an owner outside the requested org, one they could never subsequently read or use.
  2. Workspace selection was authorized against the caller, not the chat's owner, so a caller could bind another user's chat to a workspace that owner has no SSH access to.

Both are covered by new test cases (OwnerRejectedWhenTargetOutsideRequestedOrganization, OwnerCannotBindChatToWorkspaceOwnerCannotAccess, MeAliasBehavesLikeSelfServiceForOwnWorkspace).

Known gaps not addressed in this PR, called out for a follow-up: org-admin-specific test coverage (as opposed to site owner), a positive test for the mems.User == nil fallback path, and a username-instead-of-UUID path-param test.

Testing

  • go build ./...
  • go vet ./coderd/...
  • golangci-lint run ./coderd/... ./codersdk/...
  • go test ./coderd/ -run TestPostUserChats and the surrounding TestPostChats/TestChats/TestPatchChat suites
  • make coderd/apidoc/.gen (swagger docs regenerated)

Generated by Coder Agents on behalf of @bpmct.

@github-actions

Copy link
Copy Markdown
Contributor

Docs preview

Check off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here.

@linear-code

linear-code Bot commented Sep 18, 2026

Copy link
Copy Markdown

CODAGT-132

@bpmct

bpmct commented Sep 18, 2026

Copy link
Copy Markdown
Member Author

Closing in favor of #29581, which covers this more thoroughly (owner-context authorization for model config, MCP servers, and workspace binding; API-key/session-minting gate; suspended/system-user handling).

Linear: CODAGT-132

Generated by Coder Agents on behalf of @bpmct.

@bpmct bpmct closed this Sep 18, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant