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.
| Parameter | Description | Default | Environment Variable |
|---|
apiKey | API key for authentication | Optional | OPEN_SANDBOX_API_KEY |
domain | Sandbox service domain (host[:port]) | localhost:8080 | OPEN_SANDBOX_DOMAIN |
protocol | HTTP protocol (http/https) | http | — |
requestTimeoutSeconds | Request timeout for SDK HTTP calls | 30 | — |
debug | Enable basic HTTP debug logging | false | — |
headers | Extra headers applied to every request | {} | — |
useServerProxy | Route execd/endpoint calls through the server proxy | false | — |
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
| Parameter | Description | Default |
|---|
image | Docker image to use | Required |
timeoutSeconds | Automatic termination TTL (null = no expiry) | 10 minutes |
entrypoint | Container entrypoint command | ["tail","-f","/dev/null"] |
resource | CPU and memory limits | {"cpu":"1","memory":"2Gi"} |
env | Environment variables | {} |
metadata | Custom metadata tags | {} |
networkPolicy | Optional outbound egress policy | — |
credentialProxy | Credential Vault proxy startup settings | — |
extensions | Extra server-defined fields | {} |
skipHealthCheck | Skip readiness checks | false |
healthCheck | Custom readiness check function | — |
readyTimeoutSeconds | Max time to wait for readiness | 30 seconds |
healthCheckPollingInterval | Poll interval while waiting (ms) | 200 ms |
volumes | Storage 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.