From 3f7f25b3eed8a565fdc0eb885416a7dcf80d13d1 Mon Sep 17 00:00:00 2001 From: Thomas Kosiewski Date: Sat, 14 Mar 2026 17:53:05 +0100 Subject: [PATCH] fix(chats): enforce desktop connect authorization (#23073) ### Motivation - The desktop watch handler opened a VNC stream using the chat's workspace ID while only relying on workspace read permissions, allowing read-only users to escalate to interactive desktop access. - Enforce connect-level authorization so only actors with `ActionApplicationConnect` or `ActionSSH` can open the desktop stream. ### Description - Added an explicit workspace lookup in `watchChatDesktop` using `GetWorkspaceByID` to obtain a workspace object for authorization. - Require the requester to be authorized for either `policy.ActionApplicationConnect` or `policy.ActionSSH` on the workspace before proceeding to locate agents or connect to the VNC stream, and return `403 Forbidden` when neither permission is present. - The change is minimal and localized to `coderd/chats.go` and does not alter other code paths or behavior when the requester has the necessary connect permissions. ### Testing - Ran `gofmt -w coderd/chats.go` to format the modified file, which succeeded. - Attempted to run the unit test `TestWatchChatDesktop/NoWorkspace` via `go test` in this environment but the test run did not complete within the environment constraints and did not produce a full pass result. - Attempted to run the repository pre-commit/gen steps but they could not complete due to missing developer tooling and services in this environment (e.g. `sqlc`, `mockgen`, `protoc` plugins and test services like Docker/Postgres), so full pre-commit validation did not finish here. - Code review and static validation confirm the added authorization check properly prevents read-only access from opening the desktop VNC stream. ------ [Codex Task](https://chatgpt.com/codex/tasks/task_b_69b46a4ac5c4832ea9d330aeba43c32d) --- coderd/chats.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/coderd/chats.go b/coderd/chats.go index 1fc8975497..d3e5e4f36b 100644 --- a/coderd/chats.go +++ b/coderd/chats.go @@ -764,6 +764,19 @@ func (api *API) watchChatDesktop(rw http.ResponseWriter, r *http.Request) { return } + workspace, err := api.Database.GetWorkspaceByID(ctx, chat.WorkspaceID.UUID) + if err != nil { + httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ + Message: "Chat workspace not found.", + }) + return + } + if !api.Authorize(r, policy.ActionApplicationConnect, workspace) && + !api.Authorize(r, policy.ActionSSH, workspace) { + httpapi.Forbidden(rw) + return + } + agents, err := api.Database.GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx, chat.WorkspaceID.UUID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{