Skip to content

feat(sandbox): serve the egress broker and inject the gateway config - #209

Merged
quickbeard merged 1 commit into
mainfrom
sandbox-broker
Aug 13, 2026
Merged

quickbeard merged 1 commit into
mainfrom
sandbox-broker

Conversation

@quickbeard

Copy link
Copy Markdown
Owner

Phase 4a: the two halves of sandbox LLM egress the in-app e2e scoped — nothing served broker.sock, and the guest's seeded config pointed at the default opencode.ai provider (chat died on getaddrinfo EAI_AGAIN).

Broker (broker.ts)

  • BrokerRoute gains headers overrides, applied case-insensitively over the forwarded headers: the guest carries a placeholder credential and the broker swaps in the real gateway token host-side — the token never enters the sandbox and rotation is a host concern.
  • New SandboxEgress type: { routes, guestConfig?, fetchImpl? }.

Providers — new resolveEgress?: () => Promise<SandboxEgress | null> hook, resolved at every start

  • vz: broker listens on runtime/broker.sock before boot (codev-vmm dials it per guest connection); guestConfig lands in the existing read-only config share as /codev-config/codev.json.
  • bwrap: same unix socket; config rides the read-only bridge mount.
  • WSL: the broker listens on TCP (0.0.0.0, ephemeral port) because the guest reaches the host at the NAT default gateway, and the boot script grows a socat stub bridging guest 127.0.0.1:8788 → $HOST_IP:<port> — so the guest-side broker address is identical on all three backends. Guest config is bind-mounted at /codev-config. (The WSL egress firewall remains the separate 4c item.)
  • All backends announce the config via CODEV_CONFIG, which the server merges between global and project config — no image respin needed.
  • Broker lifecycle tied to the sandbox: closed on stop, exit, and every start-failure path.

Desktop (src/main/sandbox/egress.ts, fork-only)

Reads the hub auth file (@codev/gateway loadApiKey) at each sandbox start, builds the guest provider block with buildGatewayConfig pointed at http://127.0.0.1:8788/llm/v1, routes /llm/v1 → the user's gateway with the real bearer token injected, and forwards upstream through Electron's net stack so host proxy/PAC/enterprise trust roots apply without entering the guest. No gateway login → null → the sandbox boots with no egress at all, exactly as before.

Verification

  • Live vz e2e on the Node-24 image: health: OK / path api: OK / broker: OK — the new e2e stage has a guest pty curl http://127.0.0.1:8788/probe/... through vsock → broker → host upstream and reads the response back out of the shared workspace.
  • New unit tests: broker header-override swap (mixed-case), WSL egress wiring (socat line + /codev-config mount + CODEV_CONFIG env + host-side config file + live TCP broker with credential swap, driven through the fake wsl.exe).
  • Sandbox suite 75 pass / 2 skip; desktop 76 pass; full-repo typecheck green.
  • Not yet exercised: a real in-app chat through the broker (needs a machine with a hub gateway login) and the WSL/bwrap backends live — same follow-ups as the rest of the e2e campaign.

CHANGELOG entry added; DIVERGENCES desktop-wiring row extended for the @codev/gateway dep.

🤖 Generated with Claude Code

Every backend gains a resolveEgress hook: at start the provider serves
the broker on the runtime socket (TCP at the NAT gateway for WSL, which
also grows a socat stub on guest loopback 8788), writes an optional
guest codev.json, and announces it via CODEV_CONFIG — merged between
the guest's global and project configs, so no image respin is needed.
Broker routes can now carry header overrides: the guest holds a
placeholder credential and the broker swaps in the real gateway token
host-side, so it never enters the sandbox.

The desktop resolves egress from the hub auth file at each sandbox
start (rotation needs no restart), builds the guest provider block with
buildGatewayConfig pointed at the guest broker stub, and forwards
upstream through Electron's net stack so host proxy/PAC/trust roots
apply. e2e-vz now proves the chain live: a guest pty curls the broker
and the host reads the response from the shared workspace.

Verified: vz e2e health OK / path api OK / broker OK on the Node-24
image; sandbox suite 75 pass, desktop 76 pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@quickbeard
quickbeard merged commit 1626d1c into main Aug 13, 2026
0 of 5 checks passed
@quickbeard
quickbeard deleted the sandbox-broker branch August 13, 2026 03:51
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