How CubeProxy Routes Requests to Sandbox Instances with E2B Protocol Compatibility
CubeProxy uses Nginx and OpenResty Lua scripts to parse incoming requests, verify traffic tokens against Redis metadata, and forward traffic to sandbox containers while maintaining compatibility with both Cube API and E2B protocols.
CubeProxy serves as the edge gateway for TencentCloud's CubeSandbox, handling inbound HTTP traffic for both the native Cube API and the E2B-compatible protocol. Written in Lua and running on OpenResty, the proxy parses request headers or URI paths to identify target sandbox instances, validates security tokens against Redis metadata, and intelligently routes traffic to container processes. This design ensures that existing E2B SDK clients can interact with CubeSandbox instances without protocol modifications.
Dual Entry Points for Request Routing
CubeProxy accepts traffic through two distinct routing patterns that converge on the same backend resolution logic. Both methods extract the sandbox identifier and container port, then delegate to sandbox_backend.resolve_backend for upstream resolution.
Host-Based Routing (E2B-Compatible)
Requests using the hostname format <container-port>-<sandbox-id>.<domain> trigger the rewrite_phase.lua script. Located at CubeProxy/lua/rewrite_phase.lua (lines 5-20), this phase parses the Host header via parse_port_and_instance_from_host to extract the port and instance ID. This pattern matches the standard E2B API URL structure, allowing existing E2B clients to connect by setting their E2B_API_URL environment variable to the CubeProxy endpoint.
Path-Based Routing (Cube API)
Alternatively, clients may use the URI pattern /sandbox/<sandbox-id>/<container-port>/..., handled by CubeProxy/lua/path_rewrite_phase.lua. This approach extracts the routing parameters directly from the request path before invoking the same backend resolution functions defined in sandbox_backend.lua.
Backend Resolution and Metadata Lookup
The core routing logic resides in CubeProxy/lua/sandbox_backend.lua, where resolve_backend performs the heavy lifting of locating sandbox instances and enforcing access controls.
Redis Metadata Structure
The function queries Redis for proxy metadata using the key sandbox:proxy:<sandbox_id> or the legacy key bypass_host_proxy:<sandbox_id> (lines 60-74). The returned hash contains critical fields including HostIP (the external host address), SandboxIP (the internal container IP), port mappings, AllowPublicTraffic, and TrafficAccessToken.
Local Cache Optimization
To minimize Redis load, resolve_backend caches results in the Nginx shared dictionary local_cache with a randomized TTL calculated by get_cache_timeout (lines 19-33). Even cached entries enforce traffic token validation (lines 41-46), preventing stale public-access entries from bypassing security checks.
Traffic Token Enforcement
When AllowPublicTraffic is set to "false", the proxy requires a valid access token in either the e2b-traffic-access-token header (for E2B compatibility) or the cube-traffic-access-token header (for Cube-native clients). Missing or mismatched tokens result in a 404 response (lines 15-25 and 36-44), deliberately masking the sandbox's existence for security.
Network Optimization and Routing Decisions
After validating tokens, resolve_backend determines the optimal forwarding path based on the caller's location (lines 82-99).
If the client IP (referenced as cube_proxy_host_ip or server_addr) matches the sandbox's HostIP, the proxy rewrites the target to the internal SandboxIP and forwards directly to the container port. For external callers, traffic routes to the external HostIP using the mapped port from the Redis metadata.
Auto-Pause Gate and State Management
Before forwarding, both routing phases invoke sandbox_state.gate(ins_id) from CubeProxy/lua/sandbox_state.lua to respect the sandbox's pause state. If the sandbox is paused, the gate returns a 503 or 410 status (as referenced in rewrite_phase.lua lines 35-36), preventing requests from reaching stopped containers.
Practical Routing Examples
# Host-based routing (E2B-compatible)
curl -H "e2b-traffic-access-token: ${E2B_API_KEY}" \
http://49983-7c8fbcd45ffe450fb8f7fb223ad45507.cube.app/hello
In this example, Nginx parses port 49983 and sandbox ID from the Host header, loads metadata from Redis, enforces the token, and forwards to the container's internal IP.
# Path-based routing (Cube API style)
curl -H "cube-traffic-access-token: ${CUBE_API_KEY}" \
http://proxy.mycompany.com/sandbox/7c8fbcd45ffe450fb8f7fb223ad45507/49983/hello
Here, path_rewrite_phase.lua extracts the sandbox ID and port from the URI path, runs the same resolve_backend logic, and proxies to the container.
Summary
- CubeProxy leverages OpenResty Lua scripts to parse both host-based and path-based routing patterns.
- The
sandbox_backend.resolve_backendfunction inCubeProxy/lua/sandbox_backend.luahandles metadata retrieval from Redis, local caching, and traffic token enforcement. - E2B compatibility is achieved by accepting the
e2b-traffic-access-tokenheader and parsing hostnames matching the E2B API URL format. - Local-host optimization routes internal traffic directly to container IPs while external traffic uses mapped ports.
- The auto-pause gate prevents requests from reaching paused sandboxes.
Frequently Asked Questions
What is the difference between E2B and Cube API routing in CubeProxy?
There is no functional difference in the routing logic itself. Both protocols use the same Redis metadata and resolve_backend function. The only distinction is the header name for traffic tokens (e2b-traffic-access-token versus cube-traffic-access-token) and the URL format, which the proxy handles transparently.
How does CubeProxy handle high-traffic scenarios without overwhelming Redis?
CubeProxy implements a local cache layer using Nginx's shared dictionary local_cache. The get_cache_timeout function randomizes TTL values to prevent cache stampedes, while still enforcing traffic token validation on cached entries to maintain security.
What happens if a request targets a paused sandbox?
Before forwarding, rewrite_phase.lua calls sandbox_state.gate(ins_id). If the sandbox is paused, this function returns a 503 or 410 status code, preventing the request from reaching the container process.
How does the proxy distinguish between internal and external traffic?
The proxy compares the client IP (cube_proxy_host_ip or server_addr) against the sandbox's HostIP stored in Redis. Matching IPs trigger a direct rewrite to the internal SandboxIP, while non-matching IPs route through the external host's mapped port.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →