Skip to content

Serve every hosted sandbox over the Link - #525

Merged
SaladDay merged 8 commits into
aos/cutoverfrom
aos/sandbox-serve
Oct 7, 2026
Merged

SaladDay merged 8 commits into
aos/cutoverfrom
aos/sandbox-serve

Conversation

@SaladDay

@SaladDay SaladDay commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Every hosted sandbox now runs oac-sandbox-io and Serves its allocation over the sandbox Link. The change is additive: the in-sandbox daemon still runs Sessions until PR5.

  • Minting. Provisioning mints the allocation's Serve credential in the transaction that records the allocation, and stores only its hash. The Link authority verifies it with the same runtimedevice.HashCredential.
  • Bootstrap. sandbox.Bootstrap carries SandboxIO (Link URL, credential, resource). Core validates the Bootstrap once in sandbox_provider.go before Create, and the adapters' copies are deleted. Docker, E2B, microsandbox and the node Provider each deliver the input as a private file and start oac-sandbox-io. Docker starts both processes from the container's own command, so BootstrapComplete implies the service started. The node wire carries it in create (ProtocolVersion 5). Every sandbox image includes the binary.
  • Public URL. The Link URL comes only from PublicOrigin.SandboxLink(). Selection and admission of every hosted Provider reject a public URL that is loopback or not https, with the existing ErrPublicURLUnreachable. A hosted sandbox runs outside Core's network namespace, and plain http has no Link. The per-Provider PublicOrigin requirement is deleted. Hosted sandboxes therefore need an https, non-loopback public URL.
  • Docs: sandbox-provider.md, sandbox-bootstrap.md, node-generation-protocol.md, sandbox-deployment.md, configuration.md, install.md, install-options.md, core-errors.md and console-api-usage.md (+zh); the /core/v1 annotation and make openapi; the Web copy and its e2e fixture.

Blind review (fresh Claude subagent), round 1: seven findings, all fixed (one public-origin rule, Docker start order, a Bootstrap.Validate rejection table, a microsandbox delivery test, one Serve hash, the /core/v1 contract, the Docker Serve test using this tree's binary). The coordinator reviewed the fix diff.

Checks: focused tests for sandbox, deployment, api, runtimegateway, execution, sessions, the Postgres stores and cmd/*; the Core integration suite; -race -count=50 for the Link authority and runtimegateway; the opt-in Docker Serve test; make openapi, make check-sqlc, the E2B contract generator, make check-microsandbox-provider; agents-client and Web unit tests; darwin/windows daemon builds; make check-names check-docs check-ci. Not run: Playwright browser cases. E2B and microsandbox real-machine runs are deferred to the final qualification.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Provisioning mints the allocation's Serve credential with its device
credential and stores only its digest, in the same transaction that records
the allocation. sandbox.Bootstrap carries the Sandbox I/O service's input
(Link URL, credential, allocation resource). Core validates the whole
Bootstrap once with Bootstrap.Validate before Create; the Docker, E2B and
microsandbox copies of that validation are gone. An invalid input creates
nothing and releases the allocation as settled absent.

Docker, E2B and microsandbox write the input to the private file
/home/runtime/sandbox-io-bootstrap.json and start oac-sandbox-io beside the
daemon as UID/GID 1000. The node wire carries the new field, so
node.ProtocolVersion is 5; the E2B helper contract and the microsandbox
helper's stdin input change with it. Every Runtime image ships
/usr/local/bin/oac-sandbox-io, and the distribution verifies it.

A public URL that gives no Link URL now rejects hosted selection and
admission with ErrNoLink (409 sandbox_configuration_error). The opt-in
Docker tests need a fixture image that contains oac-sandbox-io; a new one
proves that a real Docker sandbox Serves its allocation through a test
relay.
Every hosted sandbox runs outside Core's network namespace and dials the
sandbox Link, so selection and admission reject a loopback or plain-http
public URL for every provider with ErrPublicURLUnreachable. The rule no
longer depends on a per-provider declaration, so the PublicOrigin
configuration requirement is deleted.
The Link authority hashed a presented Serve credential with a raw
SHA-256 while allocation reservation stored runtimedevice.HashCredential.
Both sides now use HashCredential, as Attach already does.
Docker started oac-sandbox-io with an exec after ContainerStart, so a
running container whose exec never ran was reported BootstrapComplete.
The container command now starts the service in the background from the
private files written before start and execs the daemon, so
ContainerStart is the last mutating step.
The opt-in Serve test builds oac-sandbox-io from this tree and copies it
into the image it derives, so a local run tests the current binary
rather than whatever the fixture image ships.
One unit test sends a Create through Core's adapter, decodes the request
as the helper does, and checks that it carries SandboxIO and that the
helper's stdin payload holds exactly Runtime and SandboxIO.
One table test covers the gate Core applies before Create, including a
SandboxIO resource that names another allocation, tenant or Environment.
The install options guide and Web comments still tied the HTTPS public
URL requirement to E2B; it now applies to every sandbox backend.
@SaladDay
SaladDay merged commit fb52cda into aos/cutover Oct 7, 2026
@SaladDay
SaladDay deleted the aos/sandbox-serve branch October 7, 2026 19:26
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