Skip to content

Credential/Secret Brokering for HTTP(S) Requests #1160

@hewliyang

Description

@hewliyang

We must have some way of passing credentials outside of the VM layer in order to avoid exfiltration attacks.

Vercel released credential brokering for HTTP(S) egress by intercepting and transforming the request.

Their approach is:

  • Per-sandbox ephemeral ECDSA CA cert (24h TTL), injected into system trust store
  • Env vars set for all common clients (NODE_EXTRA_CA_CERTS, SSL_CERT_FILE, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, PIP_CERT, etc.)
  • Selective TLS MITM — only domains with transform rules get terminated; all other traffic passes through untouched

Proposed SDK API:

  const sandbox = await Sandbox.create('template-id', {
    network: {
      denyOut: [ALL_TRAFFIC],
      allowOut: ['api.openai.com', '*.github.com'],
      egressTransform: {
        'api.openai.com': {
          headers: { Authorization: `Bearer ${process.env.OPENAI_API_KEY}` },
        },
        '*.github.com': {
          headers: { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` },
        },
      },
    },
  });

Changes Required to e2b/infra (AI Slop)

  1. New TLS MITM proxy handler in packages/orchestrator/internal/tcpfirewall/ — intercept TLS for transform domains, generate leaf certs on-the-fly, parse HTTP, inject/overwrite headers, forward. Wire it into domainHandler in handlers.go as an alternate path when transform rules exist on the matched domain.
  2. Per-sandbox CA generation in orchestrator sandbox lifecycle — ECDSA P-256 keypair + self-signed CA cert at creation time. Write cert to sandbox filesystem and set env vars
    (NODE_EXTRA_CA_CERTS, SSL_CERT_FILE, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, PIP_CERT, GIT_SSL_CAINFO, AWS_CA_BUNDLE, CARGO_HTTP_CAINFO, GRPC_DEFAULT_SSL_ROOTS_FILE_PATH) via packages/envd/.
  3. Config plumbing — add egressTransform (domain → headers map) to the network config protobuf/gRPC defs, thread it through packages/api/internal/handlers/sandbox_create.go
    packages/api/internal/orchestrator/create_instance.go → orchestrator sandbox config → tcpfirewall handlers.
  4. Leaf cert cache — in-memory LRU keyed by SNI hostname per sandbox, so repeated requests to the same domain don't regenerate certs.
  5. SDK — add egressTransform option to SandboxNetworkOpts in JS (packages/js-sdk/src/sandbox/sandboxApi.ts) and Python (packages/python-sdk/e2b/sandbox/sandbox_api.py).

Gondolin

FWIW I saw this first in Gondolin. Gondolin explicitly injects a placeholder into the sandbox ENV gondolin_* that gets find-and-replaced via the MITM.

I think this is better because

  1. If agent decides to change the env var - it is respected while Vercel's approach overrides regardless
  2. The env var name is is ENV so validators won't throw like
if not os.environ["OPENAI_API_KEY"]: raise ...

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions