Skip to content

feat(e2b): builds and built templates reach the network through their source pool's proxy - #78

Merged
CMGS merged 1 commit into
masterfrom
feat/e2b-build-network
Sep 28, 2026
Merged

CMGS merged 1 commit into
masterfrom
feat/e2b-build-network

Conversation

@CMGS

@CMGS CMGS commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

What

Builds and built templates reach the network through the guarded egress proxy of their source pool, and a pool-image create's processes use that proxy too. This needs sandboxd cocoonstack/sandbox@dcffdec or later: a promoted template's clone takes its source pool's policy, and the claim reports net_route and accepts egress: false.

General packages (no e2b concept):

  • pkg/sandboxd: ClaimSpec.Egress *bool and ClaimResult.NetRoute, plus NetRouteRelay.
  • pkg/scale: ClaimOptions.NoEgress and Assignment.NetRoute, so the route reaches the caller and the opt-out reaches the node.

e2b

  • envd builds a child's environment only from its /init defaults and the request. It never reads its unit's environment (e2b-dev/infra packages/envd/internal/services/process/handler/handler.go). So when a claim reports relay, this surface hands envd the variables silkd's unit sets: http_proxy and https_proxy http://127.0.0.1:3128, no_proxy localhost,127.0.0.1,::1,169.254.169.254. It hands them to envd at three points:
    • Build: a build seeds its step state with them, so every RUN step (root ones included) goes through the proxy. The final tokenless /init stores them as the template's defaults. An ENV step can override them.
    • Pool-image create: the /init carries them under the request's own envVars, so a caller's value wins.
    • Built-template create: it keeps them through the template defaults and the existing GET /envs merge.
    • A direct or none route sets nothing.
  • allow_internet_access: false now claims any create with egress: false, a built template's or a pool image's. true or unset claims as before (true still picks the egress lane for a pool image). A built template no longer answers 400 for true.
  • Docs: e2b-compat.md's no-network paragraph is replaced by "Network for builds":
    • how the proxy reaches builds and clones;
    • a worked config block that allow-lists the package indexes on the e2b-rt/e2b-ci pools;
    • that a template built before its pool gained a policy must be rebuilt;
    • that sudo steps drop the variables, so package installs run as root;
    • a pointer to sandboxd's egress rules for the tenant behavior change A1 made.

Kit rows

Two-node kit, sandboxd dcffdec on both hosts. The e2b-rt and e2b-ci none pools were given the package-index allow-list from the docs. Curl runs inside the guest through envd's commands.run.

row kube mesh
A2-01 pool-image create (e2b-rt): pypi.org / example.com, https_proxy in the process env 200 / 000 403, set 200 / 000 403, set
A2-02 Template.build from e2b-ci with RUN /opt/python/bin/pip install pyjokes (not in the image) Successfully installed pyjokes-0.8.3, 4.0 s same, 3.6 s
A2-03 the built template's sandbox: import pyjokes + requests.get(pypi), curl allowed / denied pyjokes 200, 200 / 000 403 same
A2-04 built template with allow_internet_access=false 000 000 both (no proxy behind the relay) same
A2-05 pool image with allow_internet_access=false 000 000 both, no proxy variables same

Unchanged on this head:

  • the D1, D2, D3a, D3b and D3c lanes, kube and mesh (S3 store included);
  • B1 (single claim p50 1.13 ms), B2, E2-PY and the mesh rows;
  • kube with the e2b API off (plain-42).

Hot path

A pool-image create on a relay route adds one small map clone (three entries plus the request's) before the /init it already makes. Any other route adds nothing.

Create→201 A/B, a6a86a5 (d3c) against this PR (a2), interleaved with the order swapped, p50 of 15 creates each:

run front a6a86a5 ms this PR ms
1 kube 6.39 / 6.45 / 5.78 / 5.86 5.70 / 6.38 / 7.07 / 5.57
1 mesh 6.52 / 6.05 / 6.63 / 6.31 6.38 / 5.70 / 7.18 / 6.01
2 kube 7.52 / 6.11 / 5.78 / 6.47 5.84 / 5.77 / 5.63 / 5.85
2 mesh 6.53 / 7.17 / 6.27 / 5.47 6.05 / 8.11 / 6.52 / 5.79

No shift.

Tests

  • TestStoreClaim_RoutesToAWarmNode: the route rides the assignment back, and NoEgress sends egress: false.
  • TestARelayedBuildSeedsItsStepsWithTheProxyEnvironment: relay seeds both the RUN env and the /init defaults; none seeds neither.
  • TestARelayedCreateHandsEnvdTheProxyUnderTheRequestEnvs: relay, none and direct; a request's no_proxy wins; allow_internet_access=false sets the opt-out on a pool image.
  • TestARelayedBuildLeavesTheProxyInTheTemplateDefaults.
  • TestACreateNamingABuiltTemplateClaimsItsKey: true is a plain claim, false is the opt-out.

Gates: lint 8× "0 issues.", fmt-check, asl -forwarder=false on both GOOS, tidy, tagged vet, race over all packages, helm lint.

Size

  • Production Go: +43 / −9.
  • Tests: +75 / −7.
  • Comment lines: +7 / −1, all godoc on the new fields and one-line notes on the relay variables.

… source pool's proxy

A claim now reports its net_route and can carry egress false. When a claim relays through the node's egress proxy, a build starts its steps with the proxy variables silkd's unit sets, so RUN steps download through the proxy and the template keeps them as defaults, and a pool-image create hands them to envd under the request's envVars: envd builds a child's environment only from its defaults and the request. allow_internet_access false now claims any create with egress off, and a built template no longer refuses true.
@CMGS
CMGS merged commit 123f2ac into master Sep 28, 2026
2 checks passed
@CMGS
CMGS deleted the feat/e2b-build-network branch September 28, 2026 04:03
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