capsite/toybox: a switchboard, the vats' only way out
A vat granted a host (PUT /<vat>?egress=<host> on the admin socket) gets Egress as its globalOutbound, with the host in ctx.props where the vat can't change it. Egress forwards matching requests, WebSocket upgrades included, to the switchboard and refuses the rest with a 403; with no grant, fetch still throws. The switchboard is a separate workerd: a Switchboard DO that calls fetch and returns the response, so a 101's webSocket passes through. toybox reaches it over a unix socket in HTTP proxy style, which keeps the full URL, scheme included. Its network service is the outer fence, with TLS trusting the browser CAs; systemd units for it join toybox's, and only the toybox group can open its socket. The loaded Worker is now named by vat and incarnation, not by code hash: the same code with a different grant must not share a Worker. The new incarnation table sits beside the old ones; vats installed before it read as incarnation 0 with no grant. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
88739d9495
commit
7bf6eb44c7
13 files changed
+279
-51
No files matched your search
@@ -0,0 +1,26 @@
|
||||
# switchboard: toybox's only way out. A forward proxy (HTTP and WebSocket)
|
||||
# that toybox's Egress gateway reaches over a socket handed in with -S/-s.
|
||||
#
|
||||
# The network service is the switchboard's outer fence; under systemd,
|
||||
# IPAddressAllow=/IPAddressDeny= narrow it further (see systemd/).
|
||||
using Workerd = import "/workerd/workerd.capnp";
|
||||
|
||||
const config :Workerd.Config = (
|
||||
services = [
|
||||
(name = "main", worker = .switchboard),
|
||||
(name = "internet", network = (allow = ["public", "local"], tlsOptions = (trustBrowserCas = true))),
|
||||
],
|
||||
sockets = [
|
||||
# proxy style: the request line carries the full URL, scheme included
|
||||
(name = "http", http = (style = proxy), service = "main"),
|
||||
],
|
||||
);
|
||||
|
||||
const switchboard :Workerd.Worker = (
|
||||
compatibilityDate = "2026-10-01",
|
||||
modules = [(name = "switchboard.js", esModule = embed "switchboard.js")],
|
||||
durableObjectNamespaces = [(className = "Switchboard", uniqueKey = "toybox-switchboard")],
|
||||
durableObjectStorage = (inMemory = void),
|
||||
bindings = [(name = "BOARD", durableObjectNamespace = "Switchboard")],
|
||||
globalOutbound = "internet",
|
||||
);
|
||||
Reference in new issue
Block a user