e2bcompat

package
v0.0.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

README

E2B compatibility layer

AgentBox serves a subset of the E2B API on :8090, so an application written against the E2B SDK runs against a self-hosted AgentBox cluster without code changes.

It is a subset, and this document is the boundary. Anything not listed as supported answers HTTP 501 with a message naming what to use instead — the message is the only thing the SDK surfaces to the caller, and increasingly the caller is a model deciding what to do next.

Supported

Area Operations
Sandboxes POST /sandboxes, GET /sandboxes, GET /v2/sandboxes, GET /sandboxes/{id}, DELETE /sandboxes/{id}, POST /sandboxes/{id}/timeout, POST /sandboxes/{id}/refreshes, POST /sandboxes/{id}/connect
Logs GET /sandboxes/{id}/logs, GET /v2/sandboxes/{id}/logs
Metrics GET /sandboxes/metrics, GET /sandboxes/{id}/metrics (requires a metrics backend, see below)
Templates GET /templates, GET /templates/{id} (read-only)
Secrets GET/POST /secrets, GET/POST/DELETE /secrets/{id}
API keys GET/POST /api-keys, DELETE /api-keys/{id}
Health GET /health

Deliberately different

create returns a usable sandbox

Sandbox.create() returns only once the sandbox is armed: its runtime answers, the envVars are in place, and (where configured) the injected CA, egress policy and credentials are loaded. Upstream returns as soon as the sandbox record exists.

The practical difference is that the first command after create works. The cost is that create takes as long as the sandbox actually takes to be ready — typically a few seconds on a warm pool. Pass metadata={"agentbox.scitix.ai/no-wait": "true"} to opt out per request.

A template is a SandboxEnv

templateID names a SandboxEnv, and GET /templates lists them. Templates are not built through this API: the image is built by your own CI and registered as a SandboxEnv. Other clusters' Envs appear as cluster::env, and that id can be passed straight back to create.

Secrets are resolved at egress, never handed to the sandbox

Secret.create(name, value) stores a credential; Secret.fill(name) produces the ${e2b.secrets.<name>} placeholder, which goes in a network.rules transform header. The egress gateway sets the real value on each matching request, so the sandbox can use the credential without being able to read it.

Values are write-only: no read surface returns one. Header values in network.rules must be built from placeholders — a literal is refused, because it would put the credential in the request body and the access log.

Secrets are scoped to (namespace, user) and replicated to every cluster, so a sandbox placed on another cluster resolves the same credential.

PUT /sandboxes/{id}/network replaces the egress filtering of a running sandbox, so an agent can install its dependencies and then lock down before it runs anything untrusted. Two limits: rules cannot be changed there (the CA the gateway uses to intercept TLS is minted per claim and installed into the sandbox's trust store while it starts), and connections already open are not re-evaluated — tightening applies to what the sandbox does next, it is not a kill switch.

Reaching an internal service

The anti-SSRF baseline has two tiers. The cloud metadata endpoints and link-local (169.254.0.0/16, 100.100.100.200, fd00:ec2::254) are denied unconditionally — no field opens them, because an unauthenticated GET there hands out instance credentials. RFC1918 / CGNAT / ULA are denied by default but reachable when the request names them:

network={"allowOut": ["harbor.internal", "10.20.0.0/16", "pypi.org"]}

A named host or CIDR lifts the baseline for that destination. A wildcard does not: allowOut: ["*"] means the internet, not the cluster network. For "everything, cluster network included", pass metadata={"agentbox.scitix.ai/allow-private-networks": "true"}.

The environment has to have the gateway on for any of this: without the sidecar there is nothing to intercept the request, so a create carrying network.rules — or any egress filtering — is refused rather than silently unenforced. That switch (overrides.gateway.enabled) is the environment's whole say in the matter; the rules themselves are per sandbox and arrive on the create call.

Accepted and ignored

Field Why
secure Governs whether envd requires its own access token; AgentBox authenticates at the gateway instead. Rejecting it would break every caller passing the SDK default.
autoPauseMemory Only selects the snapshot kind for an auto-pause, and autoPause is already refused.

Refused at create (HTTP 400)

autoPause, autoResume, iam.tokens, mcp, volumeMounts, network.egressProxy, and wildcard hosts in network.rules. Each error names the alternative.

These used to be dropped silently. For a human that is a confusing afternoon; for an agent it is unrecoverable, because there is no signal to correct from.

Not supported (HTTP 501)

Pause, resume, snapshots and fork have no counterpart: an AgentBox sandbox is a claimed Pod from a pre-warmed pool, not a Firecracker microVM, so there is no memory image to capture. Template builds, volumes, nodes, teams and the admin surface live in the AgentBox native API or console.

agentbox_e2b_unsupported_total{operation,category} counts what callers actually reach for, so the next batch of work is chosen from evidence.

Observability backends

Metrics read container metrics (cAdvisor series) from a Prometheus-compatible backend, scoped to the Pod backing the sandbox. Configure the operator with --prometheus-url and PROMETHEUS_TOKEN; the per-cluster label matcher comes from the cluster config's selector.

Logs come from two places, chosen by whether the sandbox still exists. A live sandbox's lines are read from its Pod through the Kubernetes log API. Once the sandbox is released the Pod is recycled and that source is empty, so a finished run is served from the central log service (--log-service-url, LOG_SERVICE_TOKEN, and --log-service-project where the gateway requires a scope); the per-cluster filters come from the cluster config's logs.filters.

Either backend left unconfigured makes its endpoints answer 501 naming the missing configuration, rather than an empty result — which would read as "this sandbox is idle" or "this sandbox printed nothing".

Credentials come from the environment rather than flags so they do not appear in the Pod spec or in ps output; the worker chart moves them into its Secret.

Layout

Path Contents
handlers/server.go The strict-server implementation: sandboxes, templates, API keys
handlers/secrets.go The credential vault endpoints
handlers/logs.go · handlers/metrics.go Observability endpoints
handlers/egress.go network → SandboxNetworkPolicy, and rule parsing
handlers/create_validate.go Refusal of create fields we would otherwise drop
handlers/unsupported.go The 501 surface and its message catalogue
domain/convert.go Projections onto the E2B wire shapes
gen/ Generated from the vendored E2B OpenAPI spec — do not edit

Documentation

Overview

Package e2bcompat provides an E2B-compatible HTTP API server for AgentBox. It runs on an independent port and maps E2B SDK calls to AgentBox operations.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// BindAddress is the TCP address the HTTP server listens on (e.g. ":8090").
	BindAddress string
	// Domain is the gateway domain name returned to SDK clients for building
	// connection URLs. Can be a hostname (e.g. "my.gateway.com") or host:port.
	// When empty, the domain field in API responses will be null.
	Domain string
	// ServerVersion is stamped on every response via X-AgentBox-Server-Version.
	ServerVersion string
	// LocalClusterID identifies this cluster in federation records, so the
	// template listing can tell its own Envs from other clusters'.
	LocalClusterID string
	// MetricsSelector returns the PromQL label matcher that identifies this
	// cluster's series in a shared metrics backend, e.g. `cluster="foo"`.
	// Evaluated per query, because the cluster config it comes from is live.
	MetricsSelector func() string
	// LogFilters returns the central-log-service filters scoping queries to
	// this cluster (region / cluster labels). Evaluated per query.
	LogFilters func() map[string]string
}

Config holds the configuration for the E2B-compatible API server.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the E2B-compatible HTTP API server.

func New

func New(cfg Config, k8sClient client.Client,
	keyStore apikey.KeyStore, adminKeyMgr *apikey.AdminKeyManager, iamSvc service.IAMService,
	sandboxSvc service.SandboxService, forwarder *service.CrossClusterForwarder,
	fedRegistry *federation.Registry, metricsClient *promclient.Client,
	vaultSvc service.VaultService, centralLogs *logclient.Client) *Server

New creates and configures the E2B-compatible HTTP server. keyStore, adminKeyMgr, and iamSvc are shared with the native API server so that both servers validate keys against the same store without duplicating the Secret-backed cache. sandboxSvc is the shared SandboxService instance; passing the same instance avoids duplicate per-pool scheduler goroutines and ensures a single Shutdown path.

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start runs the server until ctx is cancelled, then gracefully shuts down.

Directories

Path Synopsis
Package domain provides E2B-compatible conversion utilities.
Package domain provides E2B-compatible conversion utilities.
Package e2bgen provides primitives to interact with the openapi HTTP API.
Package e2bgen provides primitives to interact with the openapi HTTP API.
Package handlers implements the E2B-compatible StrictServerInterface generated by oapi-codegen.
Package handlers implements the E2B-compatible StrictServerInterface generated by oapi-codegen.
Package router provides E2B-compatible HTTP route registration.
Package router provides E2B-compatible HTTP route registration.
middleware
Package middleware provides E2B-compatible authentication middleware.
Package middleware provides E2B-compatible authentication middleware.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL