Skip to content

feat(computer): a computer reaches the run's websites by their names (FD-4683) - #448

Open
williamloo-scale wants to merge 9 commits into
wloo/website-live-replayfrom
wloo/website-computer-routing
Open

williamloo-scale wants to merge 9 commits into
wloo/website-live-replayfrom
wloo/website-computer-routing

Conversation

@williamloo-scale

@williamloo-scale williamloo-scale commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #447.

A deployed computer reaches the run's websites by their own names (https://notes.test/), opt-in.

  • Name table (computer/utils/sites.py): each site's names claimed once, synthetic over live over the network allowlist.
  • Per-deploy CA, name-constrained to those names, signs a certificate for each site.
  • site_proxy.py, standard library only, runs on the computer's python3: it maps the names to loopback, trusts the CA (system store, Firefox policy, NSS) and proxies 443/80 (and DNS for wildcards) to the site's gateway route with X-Forwarded-Host/-Proto, rewriting redirects and cookies and relaying WebSockets.
  • env_params.site_routing (true, or env ids): deploy_env fills the table from the websites deployed before the computer, read from their cards; once the computer is ready the provider installs the proxy and records the table, the CA and each name's check. A reset routes the new computer under a new CA. Without site_routing nothing changes.

Before merging

  • Fits main's WebsiteBrowserEnvironment (feat(computer): WebsiteBrowserEnvironment, the base class for website browsers #449): this proxy answers on loopback through the hosts file, so a website browser in a computer, which bypasses loopback and has no AGENTENV_SITE_PROXY set there yet, reaches the sites through it. Setting AGENTENV_SITE_PROXY in a computer (M5.5/M5.7) would need a forward proxy, which this isn't.
  • Linux computers only. The proxy has been checked from a Mac against the real Notes site over HTTPS, but not yet inside a deployed Linux computer.

Test

Unit suite: 12,923 passed (one GitHub-clone test from main, which hangs on the local machine on main too, deselected).

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

No new blocking issue was established in the reviewed changes.

Summary

Adds opt-in routing so a computer can open the run’s websites by their declared names.

  • Opted-in computers reach earlier run websites by their declared names.
  • Website gateway routes now serve browser traffic, including WebSockets.
  • Boot apps wait to launch until computer setup is ready.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Run[Previously deployed websites] --> Table[Site names and gateway routes]
  Table --> Install[Install certificates and local proxy]
  Install --> Apps[Launch held boot apps]
  Browser[Computer browser] --> Proxy[Local site proxy]
  Proxy --> Gateway[Website gateway route]
  Gateway --> Website[Website server]
Loading

Reviews (18) · Last reviewed commit: "fix(computer): write the routing config'..." · Reviewed by Greptile

@williamloo-scale williamloo-scale changed the title computer: reach the run's websites by their names (FD-4683) feat(computer): a computer reaches the run's websites by their names (FD-4683) Nov 3, 2026
@williamloo-scale
williamloo-scale marked this pull request as ready for review November 3, 2026 00:24
@williamloo-scale
williamloo-scale requested a review from a team as a code owner November 3, 2026 00:24
@socket-security

socket-security Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpypi/​websockets@​17.496100100100100

View full report

Comment thread src/agent_env/env/gateway/rest_proxy.py Resolved

@earakely-scale earakely-scale left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this against our plan for websites in the computer. Three parts are better than what we'd planned, and we've changed our design docs to follow them:

  • the CA made for each deploy, limited to the run's site names, with its key discarded after signing;
  • the transparent loopback routing;
  • the site table's rules.

The latest commits already fix three things we'd found: Chromium's trust (the CACertificates policy), the check's time budget, and WebSockets through the gateway. Four things are inline. Three smaller ones are below, and are optional.

Smaller things:

  • Leaf keys: RootChannel.write (sites.py:324) sends them base64-encoded in a bash -c argument, through a staging file in the VM host's /tmp. write_secret_file avoids both.
  • site_routing validation: run_env_params (computer/env.py:172) uses the value before ComputerParams validates it. "web-env" becomes one env id per character, and 1 raises a TypeError.
  • Rewrites:
    • a scheme-relative Location: //gw/website/notes/x is passed through unchanged (site_proxy.py:181), so the browser leaves the site's name for the gateway;
    • Set-Cookie: ...; Path = /website/notes/x, with spaces around =, isn't rewritten (site_proxy.py:200).

Comment thread src/agent_env/env/gateway/gateway.py Resolved
williamloo-scale added a commit that referenced this pull request Nov 3, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from a50d72f to a767a25 Compare November 3, 2026 21:50
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from cb672e5 to 306587d Compare November 3, 2026 21:50
Comment thread src/agent_env/env/gateway/rest_proxy.py Resolved
williamloo-scale added a commit that referenced this pull request Nov 3, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from a767a25 to d160d31 Compare November 3, 2026 22:52
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from 306587d to 2b782e9 Compare November 3, 2026 22:52
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from 2b782e9 to 0d613b8 Compare November 3, 2026 23:51
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from d160d31 to 5953d5a Compare November 3, 2026 23:53
williamloo-scale added a commit that referenced this pull request Nov 4, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from 0d613b8 to 9495ed2 Compare November 4, 2026 00:32
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from 9495ed2 to 25dcf9a Compare November 4, 2026 01:06
williamloo-scale added a commit that referenced this pull request Nov 4, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from 4283738 to 0cca3db Compare November 4, 2026 01:30
Comment thread src/agent_env/env/gateway/rest_proxy.py Resolved
williamloo-scale added a commit that referenced this pull request Nov 4, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from 0cca3db to a1ec8b4 Compare November 4, 2026 03:37
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from c2bd2fb to f7c679d Compare November 4, 2026 03:37
williamloo-scale added a commit that referenced this pull request Nov 4, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from a1ec8b4 to d044c00 Compare November 4, 2026 03:56
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from f7c679d to 571c04b Compare November 4, 2026 03:56
williamloo-scale added a commit that referenced this pull request Nov 4, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from d044c00 to f813a59 Compare November 4, 2026 05:07
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from 571c04b to 04d3f23 Compare November 4, 2026 05:07
@williamloo-scale

williamloo-scale commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor Author

@earakely-scale thanks for the review. Everything you raised is now addressed in #448:

Inline (replied to and resolved on each thread):

  • Boot apps vs routing (55c29836): with site_routing, the boot environment holds each app's boot launch. Readiness counts a held app as ready. Once the sites are routed, the provider launches the held apps through computer-app/v1 launch, a framework-only call, then waits until the computer is ready. Chromium's start URLs and Firefox's policies therefore see the hosts entries, the CA and the proxy already in place. A reset does the same.
  • Proxy as the session user (55c29836): serve drops to nobody where the base has it, else to the session user. A root keep loop restarts it. Its log is root-owned beside the config, opened O_NOFOLLOW with mode 0600, so a planted link is refused.
  • OPTIONS on website routes (55c29836): both /website/<name> routes accept OPTIONS, so a cross-name CORS preflight reaches the site.
  • _ in a site's name: already handled. fallback_name maps _ to - before .localhost, so slack_website gets slack-website.localhost.

The smaller three (faf8e7c2):

  • Leaf keys: the routing config holds each site's leaf key and the provider's upstream headers. It now goes through RootChannel.write_secret, which writes with write_secret_file over the exec's stdin into a staging folder only its owner can open. It is then docker cp'd into the container's root-only /etc/agentenv/sites, and the staged copy is removed. It never appears on a command line or in a shared /tmp path. Tested by test_the_config_holding_the_keys_is_written_over_stdin_into_a_private_staging_folder_never_as_text.

  • site_routing validation: run_env_params refuses anything other than true or a list of env-id strings before using it, so "web-env", 1 and ["web-env", 2] each raise a clear ValueError. Tested by test_a_site_routing_that_is_neither_true_nor_a_list_of_env_ids_is_refused_before_it_is_read.

  • Rewrites:

    • a scheme-relative Location: //gw/website/notes/x is read with the page's scheme and moved onto the site's name, while //other.example/... is left alone;
    • Set-Cookie: ...; Path = /website/notes/x is rewritten whatever the spacing around = or the case of path.

    Covered by test_only_a_location_on_the_sites_route_is_moved_onto_its_name and test_a_cookie_path_on_the_route_is_rooted_however_it_is_spelled.

Each new test fails on the code before its fix.

williamloo-scale added a commit that referenced this pull request Nov 4, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from f813a59 to faf8e7c Compare November 4, 2026 05:10
@williamloo-scale
williamloo-scale force-pushed the wloo/website-live-replay branch from 04d3f23 to 956163f Compare November 4, 2026 05:10
williamloo-scale and others added 9 commits November 3, 2026 21:16
…(FD-4683)

This PR's change, rebased as one commit onto #447.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… their route, and bound DNS and WebSocket relays (FD-4683)

- site_routing on a disk computer is refused before boot, and a container form is chosen when one is ready.
- deployed_sites matches a card's website to its frontend URL by its /svc/<name>/ route, not its card name.
- The in-computer DNS relay passes on an upstream UDP answer whole, up to the largest datagram.
- The gateway's WebSocket relay holds at most WEBSOCKET_MESSAGE_MAX_BYTES of one upstream message, closing both sides with 1009 past it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…proxy running as nobody, and pass CORS preflights (FD-4683)

- With site_routing, a computer holds its boot apps' launches (AGENTENV_HOLD_BOOT_LAUNCH); the driver counts a held
  app ready, and the provider launches each through computer-app/v1's launch once the names, CA and proxy are in
  place, then waits until the computer is ready.
- The site proxy drops to nobody where the base has it, so the agent can't stop it; keep, as root, starts it again
  should it end; its log sits in the root-owned config folder and is opened without following a link.
- A website's gateway routes accept OPTIONS, so a CORS preflight between two sites reaches the site.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… alone, so a name longer than a common name takes is signed (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…stream, kept where root alone reads them (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…the sites it forwards to, and relays a refused handshake's headers (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…part, each named for its env (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ths its card advertises, with no state path (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…_routing before reading it, and rewrite scheme-relative redirects and spaced cookie paths (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
williamloo-scale added a commit that referenced this pull request Nov 4, 2026
… traffic/v1 (FD-4683)

This PR's change, rebased as one commit onto #448.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale force-pushed the wloo/website-computer-routing branch from faf8e7c to 27a865f Compare November 4, 2026 05:16

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.

2 participants