Skip to content

fix(env): a step reaches a multi env's computer through its gateway with the computer's own token (FD-5903) - #690

Open
earakely-scale wants to merge 2 commits into
mainfrom
edgararakelyan/multi-env-computer-token
Open

earakely-scale wants to merge 2 commits into
mainfrom
edgararakelyan/multi-env-computer-token

Conversation

@earakely-scale

@earakely-scale earakely-scale commented Nov 15, 2026 •

Copy link
Copy Markdown
Collaborator

What changes

FD-5903. A step couldn't reach a framework-only route of a multi env's computer through the multi env's gateway. Such a call was answered 401 unauthorized: this route is agent-env's own: it takes the env's control token.

  • The gateway takes its own control token off every call and passes any other token on.
  • Each computer the gateway fronts takes only its own token, which the multi env's record keeps in child_envs.
  • Task.run granted a step only the gateway's token for the multi env's address, and DeployedEnv.invoke(environment_name=...) sent the gateway's token too.

So the gateway's token went to the computer's /svc/<name> route, the gateway took it off, and the computer refused the call. That breaks:

  • an env_outcome_verifier that reads files in the computer with computer-exec (the FD-5483 pilot's check reads a document there);
  • start_computer_recording with an environment_name, which, being best effort, only warns.

Browser steps don't hit this, because they call the computer at its own address with its own record (find_browser).

The fix:

  • DeployedEnv.control_grants: the addresses an env's framework-only routes are at, each with the headers that carry its token. For most records that's its own address. A gateway env adds the gateway's route to each child it fronts on a sandbox of its own (<address>/svc/<name>), with that child's own token.
  • granted_headers (protocol) gives a call the headers of the longest granted address it's under, so the child's route wins over the gateway's address.
  • Task.run grants each step every deployed env's control_grants. DeployedEnv.invoke and control_headers_for use them too.

Testing

  • New unit tests:

    • protocol, test_control_token.py: a call under two granted addresses gets the longer one's headers, whichever was granted first;
    • test_env.py: through a real gateway's composed card, an invoke on a computer the gateway fronts sends the computer's token, and one on an MCP server sends the gateway's;
    • control_grant_test.py: a step's call to a computer through the gateway carries the computer's token.

    All three fail without the fix.

  • tst/unit/env, tst/unit/task, tst/unit/task_step and the protocol's tests: 7439 passed. The one failure, test_disk_recipe's Windows install, fails the same way on main on macOS. ruff check is clean.

  • multi_env_computers_test.py's first test now runs a command in the desktop through the gateway with invoke(..., environment_name="desktop"). On the x86 host (local Docker) it passed with the fix (150 s). With this PR's three product files at main's, it failed at that call with 401 unauthorized: this route is agent-env's own: it takes the env's control token (240 s).

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge.

Summary

Fixes calls to a multi env’s computer through its gateway.

  • Steps and invoke calls use a computer’s token when they go through its gateway.

No actionable issues found. Tests were inspected but not run.

Diagram

sequenceDiagram
    participant Caller as Step or invoke
    participant Grants as Control grants
    participant Gateway
    participant Computer
    Caller->>Grants: Choose headers for /svc/desktop/...
    Grants-->>Caller: Computer's token
    Caller->>Gateway: Call with computer's token
    Gateway->>Computer: Forward token unchanged
    Computer-->>Caller: Authorized response
Loading

Reviews (1) · Last reviewed commit: "test(env): the multi env computers test ..." · Reviewed by Greptile

earakely-scale and others added 2 commits November 14, 2026 21:52
…ith the computer's own token

A multi env's gateway takes its own control token off a call and passes any other on, and each computer it fronts takes
only its own. A step's grant and DeployedEnv.invoke gave a call to the gateway's /svc/<computer> route the gateway's
token, so the computer refused its framework-only routes: an env_outcome_verifier reading files in the computer with
computer-exec, or start_computer_recording with an environment_name. A record's control_grants now add, for each child
env a gateway fronts on a sandbox of its own, the gateway's route to it with the child's own token, and the protocol's
granted_headers picks the longest address a call is under.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r through the gateway's route to it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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