Repository navigation
fix(env): the gateway's control routes take the deploy's control token - #492
Open
earakely-scale wants to merge 2 commits into
Open
earakely-scale wants to merge 2 commits into
earakely-scale wants to merge 2 commits into
Conversation
Each gateway deploy draws a control token, as computer envs already do, passes it to the gateway as AGENTENV_CONTROL_TOKEN and keeps it on the deploy record. The gateway then refuses any call without it to the routes that change tool access, triggers, the clock and notifications. Their framework callers already send the record's control headers. Every other route stays open for now. A gateway started without a token checks none: an older framework, an export, or a create_gateway caller that passes none. An older gateway image ignores the token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y-control-token # Conflicts: # src/agent_env/env/gateway/entrypoint.py # src/agent_env/env/gateway/gateway.py # src/agent_env/providers/env_providers/env_gateway_provider.py
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The env gateway serves the harness's control routes on the same listener it gives the agent as its MCP server, with no check of who's calling. Any caller that reaches the gateway, the agent included, could:
Computer envs already take a per-deploy control token on their framework-only routes. This gives the gateway the same.
What changes
env/gateway/).AGENTENV_CONTROL_TOKEN, mirrored inconstants.pylike the other protocol constants.CONTROL_ROUTESthat doesn't carryAuthorization: Bearer <token>, with 401 and{"ok": false, "error": "this route takes the env's control token"}. Those routes are:/tools/enable|disable;/triggers/register|remove|clear;/clock/set-time|advance|clear;/notifications/config|take|clear.hmac.compare_digest./mcp, the card, the site routes,/step,/state, the state reads,/svcand/agentenv.deploy()draws a token once per deploy, with the computer env'scontrol_token(), so each attempt of a provider chain uses the same one.DeployedGatewayEnv.control_token. That field already existed and is serialized.*TOKEN*key.create_gatewaytakes an optionalcontrol_token. Its callers build their own records, and the SDK's CUA and iOS envs don't copy fields they don't know. So it draws none by default, and those gateways stay open as today.DeployedEnv.invoke, which sends the record's control headers: tool access, trigger registration, scheduled checks, notification delivery,sync_env_clockand post-turn hooks. No other repo calls these routes; checked in the Scale monorepo and synthetic-pipelines.create_gatewaycaller that passes none;Tests
Unit:
deploy()records it andcreate_gatewayforwards it.Integration:
test_gateway_clock_extensionchecks that a caller without the token gets 401 on every covered route, changes nothing, and can still read/clock/time. It fails on main, where the no-token caller arms the clock.On an agent-environments-admin EC2 box:
tst/integration/task_step(36);Chaos, main against this branch on the same box:
http://gateway:18765/tools/disableand two moredocker compose up -d --force-recreateMixed versions on the box: this branch's framework with main's gateway image, and main's framework with this branch's image. Both stay open, exactly as today, and the framework's calls work.
Real Modal, from a MultiEnv with an MCP server, on
modal_vmand on Modal containers:/clock/timeanswers.Rollout
Nothing changes in prod until the gateway image this builds is promoted and Scale's framework pin is bumped. Either alone keeps today's behaviour.
Not covered here
/svc,/agentenv, the state reads,/trajectoryand/changes. Also the SQL consoles. These come in a follow-up, because callers outside this repo use them and need the token first./step,/state,GET /clock/timeand child cards stay open on purpose: generated MCP CLIs, OpenClaw skills, Harbor verifiers and synced env servers call them from sandboxes.🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; no actionable defects were found.Summary
The gateway now checks a per-deploy token before serving the covered control routes.
No actionable issues were found. Tests were inspected, not run.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD D[Deploy] --> T[Create one token] T --> G[Gateway environment] T --> R[Deployment record] R --> F[Framework request with token] F --> C{Covered control route?} A[Agent request] --> C C -->|No| O[Existing route behavior] C -->|Yes| V{Token matches?} V -->|Yes| H[Control handler] V -->|No| U[401 before handler]Reviews (2) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile