Skip to content

[Fix] Slack-started tasks get 403 "User context required" when creating or updating environments - #188

Merged
mrubens merged 1 commit into
developfrom
fix/environment-writes-live-acting-user-1mga6gt1092gj
Jul 11, 2026
Merged

[Fix] Slack-started tasks get 403 "User context required" when creating or updating environments#188
mrubens merged 1 commit into
developfrom
fix/environment-writes-live-acting-user-1mga6gt1092gj

Conversation

@roomote-roomote

Copy link
Copy Markdown
Contributor

Opened on behalf of Matt Rubens. Follow up by mentioning @openmote, in the web UI, or in Slack.

What changed

Tasks started from chat surfaces (Slack app mentions and other channel auto-start paths) can now create and update environments through the MCP endpoints. POST /api/mcp/environments and PATCH /api/mcp/environments/:id previously returned 403 "User context required" for every Slack-started task, because those runs are enqueued with skipInitialActingUser: true and dequeued before an acting user is attached — so their run tokens are minted as the deployment service principal with no mint-time user claim, which was the only identity the handlers accepted.

Both handlers now resolve the effective human through a shared resolveEnvironmentWriteUserId helper: prefer the live task_runs.actingUserId (via the MCP proxy's existing resolveActingUserIdOrNull), fall back to the token's mint-time claim, and still return 403 when no human actor is resolvable. Environment writes remain forbidden for pure deployment-principal automation.

Why this change was made

The live actingUserId is the codebase's established source of truth for "which human is driving this run" — it feeds actor-scoped credential resolution and is written only by trusted server-side writers (web steer, follow-up delivery); run tokens cannot reassign it. The environment write handlers were the outlier in requiring frozen mint-time attribution, which made every Slack-launched task unable to manage environments even when a linked user was actively driving it. The resolved user only feeds deployment-scoped attribution (createdByUserId on the environment and its config-version audit rows), so no per-user privilege is granted; the task-control handlers (launchTask, sendMessage, steerMessage, task-stop) act as a user and intentionally keep their stricter gating.

How it was tested

New handler tests cover both endpoints: deployment-principal run tokens are rejected with no live actor, accepted once a live actor is attached, mint-time fallback works, user auth tokens skip the lookup entirely, and the persisted createdByUserId prefers the live actor over a differing mint-time claim (14/14 passing). pnpm lint and pnpm check-types pass.

Impact

Slack-started Roomote tasks asked to set up or patch environments can now do so once the requesting user's messages have attached them as the run's acting user, instead of dead-ending on a 403 the task cannot recover from. Web-launched tasks and dashboard flows are unchanged, and automation-only runs with no human actor are still rejected.

@roomote-roomote

roomote-roomote Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

No code issues found. See task

Reviewed the shared resolveEnvironmentWriteUserId helper and both handlers. The live-actor-first resolution with mint-time fallback is correct, actingUserId is a trusted server-written column that run tokens cannot reassign, the resolved user only feeds createdByUserId attribution (not a new privilege gate), and the strict task-control handlers are intentionally left untouched. New tests pass locally (11/11).

@mrubens
mrubens marked this pull request as ready for review July 11, 2026 13:48
@mrubens
mrubens merged commit ada8830 into develop Jul 11, 2026
1 check passed
@mrubens
mrubens deleted the fix/environment-writes-live-acting-user-1mga6gt1092gj branch July 12, 2026 04:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant