Skip to main content
This feature is currently in public preview and is not recommended for production use. During the preview, the proxy and network features are only available in the us-was-1 region.
The Blaxel SDK supports two network features when creating sandboxes:
  • Proxy routing with secrets injection - the Blaxel proxy performs man-in-the-middle (MITM) interception on outbound HTTPS traffic and injects headers, body fields, and secrets server-side.
  • Domain filtering - the Blaxel proxy controls which external domains the sandbox can reach.
Proxy and network configuration is set at sandbox creation time and cannot be updated after the sandbox has been created. To change the configuration (e.g. rotate a secret, add a new routing rule, or update the allowlist), you must create a new sandbox. Support for in-place updates is coming soon.

How it works

When a sandbox is created with a proxy config, Blaxel:
  1. Sets HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables inside the sandbox
  2. Installs a CA certificate and sets NODE_EXTRA_CA_CERTS and SSL_CERT_FILE so TLS clients trust the proxy
  3. Performs MITM on outbound HTTPS via CONNECT tunneling
  4. Matches each request against routing rules by destination domain
  5. Injects configured headers and body fields, resolving {{SECRET:name}} placeholders server-side
  6. Adds an X-Blaxel-Request-Id header to every proxied request for tracing
Standard HTTP clients work transparently: curl, wget, git, pip, npm, Node.js https, Python requests, etc.
Localhost (127.0.0.1), private ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), 169.254.169.254, .local, and .internal are always bypassed automatically.

Configuration reference

All network settings are passed via the network key in the sandbox creation options:
import { SandboxInstance } from "@blaxel/core";

const sandbox = await SandboxInstance.create({
  name: "my-sandbox",
  image: "blaxel/base-image:latest",
  region: "us-was-1",
  network: {
    // Domain filtering (firewall)
    allowedDomains: [...],
    forbiddenDomains: [...],
    // Proxy with header/body injection
    proxy: {
      routing: [...],
      bypass: [...],
    },
  },
});

SandboxNetwork

FieldTypeDescription
allowedDomainsstring[] / list[str]Allowlist — only these domains are reachable. Supports wildcards (*.s3.amazonaws.com).
forbiddenDomainsstring[] / list[str]Denylist — all domains except these are reachable. Supports wildcards. If both are set, forbiddenDomains takes precedence.
proxyProxyConfigProxy routing and bypass configuration.

ProxyConfig

FieldTypeDescription
routingProxyTarget[] / list[ProxyTarget]Per-destination routing rules with header/body injection.
bypassstring[] / list[str]Domains added to NO_PROXY that skip the proxy entirely. Supports wildcards.

ProxyTarget

FieldTypeDescription
destinationsstring[] / list[str]Domain patterns this rule applies to. Use ["*"] for a global catch-all rule. Supports wildcards (*.example.com matches sub.example.com but not example.com).
headersRecord<string, string> / dictHeaders injected into matching requests. Values may contain {{SECRET:name}} references.
bodyRecord<string, string> / dictJSON body fields injected into matching requests. Values may contain {{SECRET:name}} references.
secretsRecord<string, string> / dictNamed secret values for this rule. Referenced via {{SECRET:name}} in headers and body. Write-only — never returned in API responses. Stored encrypted at rest.

Region availability

Proxy availability is region-dependent. The Region type includes a proxyAvailable boolean field. Check region support before relying on proxy features:
import { listRegions } from "@blaxel/core";

const { data: regions } = await listRegions({ throwOnError: true });
for (const r of regions) {
  console.log(`${r.name}: proxy=${r.proxyAvailable}`);
}

Environment variables set inside the sandbox

When proxy is configured, the sandbox automatically has:
VariablePurpose
HTTP_PROXYProxy URL for HTTP traffic
HTTPS_PROXYProxy URL for HTTPS traffic
NO_PROXYComma-separated bypass list (always includes localhost, private ranges)
NODE_EXTRA_CA_CERTSPath to CA cert for Node.js TLS verification
SSL_CERT_FILEPath to CA cert for other TLS clients (curl, Python, etc.)

CLI tool compatibility

When proxy is enabled, the following tools work transparently inside the sandbox with no extra configuration:
ToolProtocolNotes
curlHTTPSAutomatic via HTTPS_PROXY env var
gitHTTPSMay need GIT_SSL_CAINFO=$SSL_CERT_FILE for some operations
pip / pip3HTTPSAutomatic
npm / npxHTTPSAutomatic
Python requestsHTTPSAutomatic via env vars
Node.js httpsHTTPSAutomatic via HTTPS_PROXY + NODE_EXTRA_CA_CERTS env vars

Behavior details

  • Wildcard matching: *.example.com matches sub.example.com and a.b.example.com but not example.com itself
  • No cross-route leakage: Headers/secrets from one routing rule are never applied to requests matching a different rule
  • User headers preserved: The proxy adds injected headers alongside any headers the sandbox code sends — it does not overwrite user-sent headers
  • Body merge: Injected body fields are merged into the outbound JSON payload. User-sent fields take precedence if there’s a key collision
  • Tracing: Every proxied request gets an X-Blaxel-Request-Id header for observability
  • Local traffic: Requests to localhost / 127.0.0.1 are never routed through the proxy

Full example: agent sandbox with proxy + firewall

import { SandboxInstance } from "@blaxel/core";

const sandbox = await SandboxInstance.create({
  name: "agent-workspace",
  image: "blaxel/base-image:latest",
  region: "us-was-1",
  labels: { team: "ml", env: "staging" },
  network: {
    allowedDomains: [
      "api.stripe.com",
      "api.openai.com",
      "httpbin.org",
      "*.s3.amazonaws.com",
    ],
    proxy: {
      routing: [
        {
          destinations: ["api.stripe.com"],
          headers: {
            "Authorization": "Bearer {{SECRET:stripe-key}}",
            "Stripe-Version": "2024-12-18.acacia",
          },
          body: {
            "api_key": "{{SECRET:stripe-key}}",
          },
          secrets: {
            "stripe-key": "sk-live-abc123...",
          },
        },
        {
          destinations: ["api.openai.com"],
          headers: {
            "Authorization": "Bearer {{SECRET:openai-key}}",
            "OpenAI-Organization": "org-abc123",
          },
          secrets: {
            "openai-key": "sk-proj-xyz789...",
          },
        },
      ],
      bypass: ["*.s3.amazonaws.com"],
    },
  },
});

// curl https://api.stripe.com/...  -> gets auth header + body injected
// curl https://api.openai.com/...  -> gets auth header injected
// curl https://httpbin.org/...     -> allowed, no injection
// curl https://evil.com/...        -> BLOCKED by allowedDomains firewall

const result = await sandbox.process.exec({
  command: "curl -s https://api.stripe.com/v1/charges",
  waitForCompletion: true,
});
console.log(result.logs);
Last modified on April 10, 2026