Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/opensandbox-group/OpenSandbox/llms.txt

Use this file to discover all available pages before exploring further.

The OpenSandbox JavaScript/TypeScript SDK provides a fully-typed async API for interacting with secure sandbox environments from Node.js or the browser. It covers sandbox lifecycle management, streaming command execution, file operations, endpoint resolution, volume mounts, egress policy control, and Credential Vault integration.

Installation

npm install @alibaba-group/opensandbox

Quick Start

The following example creates a sandbox, runs a command, and releases all resources.
import { ConnectionConfig, Sandbox, SandboxException } from "@alibaba-group/opensandbox";

const config = new ConnectionConfig({
  domain: "api.opensandbox.io",
  apiKey: "your-api-key",
  // protocol: "https",
  // requestTimeoutSeconds: 60,
});

try {
  const sandbox = await Sandbox.create({
    connectionConfig: config,
    image: "ubuntu",
    timeoutSeconds: 10 * 60,
  });

  const execution = await sandbox.commands.run("echo 'Hello Sandbox!'");
  console.log(execution.logs.stdout[0]?.text);

  // Terminate the remote instance and release the HTTP agent
  await sandbox.kill();
  await sandbox.close();
} catch (err) {
  if (err instanceof SandboxException) {
    console.error(`Sandbox Error: [${err.error.code}] ${err.error.message ?? ""}`);
    console.error(`Request ID: ${err.requestId ?? "N/A"}`);
  } else {
    console.error(err);
  }
}

ConnectionConfig

The ConnectionConfig class manages API server connection settings.
ParameterDescriptionDefaultEnvironment Variable
apiKeyAPI key for authenticationOptionalOPEN_SANDBOX_API_KEY
domainSandbox service domain (host[:port])localhost:8080OPEN_SANDBOX_DOMAIN
protocolHTTP protocol (http/https)http
requestTimeoutSecondsRequest timeout for SDK HTTP calls30
debugEnable basic HTTP debug loggingfalse
headersExtra headers applied to every request{}
useServerProxyRoute execd/endpoint calls through the server proxyfalse
import { ConnectionConfig } from "@alibaba-group/opensandbox";

const config = new ConnectionConfig({
  domain: "api.opensandbox.io",
  apiKey: "your-key",
  requestTimeoutSeconds: 60,
  headers: { "X-Custom-Header": "value" },
});

Sandbox.create() Parameters

ParameterDescriptionDefault
imageDocker image to useRequired
timeoutSecondsAutomatic termination TTL (null = no expiry)10 minutes
entrypointContainer entrypoint command["tail","-f","/dev/null"]
resourceCPU and memory limits{"cpu":"1","memory":"2Gi"}
envEnvironment variables{}
metadataCustom metadata tags{}
networkPolicyOptional outbound egress policy
credentialProxyCredential Vault proxy startup settings
extensionsExtra server-defined fields{}
skipHealthCheckSkip readiness checksfalse
healthCheckCustom readiness check function
readyTimeoutSecondsMax time to wait for readiness30 seconds
healthCheckPollingIntervalPoll interval while waiting (ms)200 ms
volumesStorage mounts (host, pvc, ossfs)
Metadata keys under opensandbox.io/ are reserved for system-managed labels and will be rejected by the server.

Operations

Lifecycle

const info = await sandbox.getInfo();
console.log("State:", info.status.state);
console.log("Expires:", info.expiresAt); // null when manual cleanup mode is used

await sandbox.pause();

// Resume returns a fresh, connected Sandbox instance
const resumed = await sandbox.resume();

// Renew: expiresAt = now + timeoutSeconds
await resumed.renew(30 * 60);
Create a non-expiring sandbox by passing timeoutSeconds: null:
const manual = await Sandbox.create({
  connectionConfig: config,
  image: "ubuntu",
  timeoutSeconds: null,
});

Custom Health Check

Override the default ping check to define your own readiness condition.
const sandbox = await Sandbox.create({
  connectionConfig: config,
  image: "nginx:latest",
  healthCheck: async (sbx) => {
    const ep = await sbx.getEndpoint(80);
    return !!ep.endpoint;
  },
});

Command Execution with Streaming

import type { ExecutionHandlers } from "@alibaba-group/opensandbox";

const handlers: ExecutionHandlers = {
  onStdout: (m) => console.log("STDOUT:", m.text),
  onStderr: (m) => console.error("STDERR:", m.text),
  onExecutionComplete: (c) =>
    console.log("Finished in", c.executionTimeMs, "ms"),
};

await sandbox.commands.run(
  'for i in 1 2 3; do echo "Count $i"; sleep 0.2; done',
  undefined,
  handlers,
);

File Operations

await sandbox.files.createDirectories([{ path: "/tmp/demo", mode: 755 }]);

await sandbox.files.writeFiles([
  { path: "/tmp/demo/hello.txt", data: "Hello World", mode: 644 },
]);

const content = await sandbox.files.readFile("/tmp/demo/hello.txt");
console.log("Content:", content);

const files = await sandbox.files.search({
  path: "/tmp/demo",
  pattern: "*.txt",
});
console.log(files.map((f) => f.path));

await sandbox.files.deleteDirectories(["/tmp/demo"]);

Endpoints

getEndpoint() returns an address without a scheme (e.g. "localhost:44772"). Use getEndpointUrl() when you need a full URL.
const { endpoint } = await sandbox.getEndpoint(44772);
const url = await sandbox.getEndpointUrl(44772);
// url => "http://localhost:44772"

Volume Mounts

volumes supports host, pvc, and ossfs backends. Each volume entry must specify exactly one backend type.
const sandbox = await Sandbox.create({
  connectionConfig: config,
  image: "ubuntu",
  volumes: [
    {
      name: "oss-data",
      ossfs: {
        bucket: "bucket-a",
        endpoint: "oss-cn-hangzhou.aliyuncs.com",
        accessKeyId: process.env.OSS_ACCESS_KEY_ID!,
        accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET!,
        version: "2.0",
      },
      mountPath: "/mnt/oss",
      subPath: "prefix",
    },
  ],
});

Egress Policy

Inspect and patch the sandbox’s outbound network policy at runtime.
const policy = await sandbox.getEgressPolicy();

await sandbox.patchEgressRules([
  { action: "allow", target: "www.github.com" },
  { action: "deny", target: "pypi.org" },
]);

Credential Vault

Inject outbound credentials through the egress sidecar without exposing them in environment variables or logs.
const sandbox = await Sandbox.create({
  connectionConfig: config,
  image: "python:3.11",
  networkPolicy: {
    defaultAction: "deny",
    egress: [{ action: "allow", target: "api.example.com" }],
  },
  credentialProxy: { enabled: true },
});

await sandbox.credentialVault.create({
  credentials: [{ name: "api-token", source: { value: "<token>" } }],
  bindings: [
    {
      name: "api-token",
      match: {
        schemes: ["https"],
        ports: [443],
        hosts: ["api.example.com"],
        paths: ["/v1/*"],
      },
      auth: { type: "apiKey", name: "x-api-key", credential: "api-token" },
    },
  ],
});

SandboxManager

Use SandboxManager for administrative tasks such as listing or killing existing sandboxes.
import { SandboxManager } from "@alibaba-group/opensandbox";

const manager = SandboxManager.create({ connectionConfig: config });
const list = await manager.listSandboxInfos({
  states: ["Running"],
  pageSize: 10,
});
console.log(list.items.map((s) => s.id));
await manager.close();
In Node.js, each Sandbox and SandboxManager instance owns an isolated undici keep-alive pool. Always call sandbox.close() and manager.close() when finished to release the underlying HTTP agent. In browsers the SDK falls back to the global fetch implementation; streaming file uploads are Node.js-only.

Build docs developers (and LLMs) love