Docs / concepts / isolation

Isolation Model

How Runra Sandbox isolates execution — VM-backed sandboxes, file system isolation, process isolation, resource limits, network policy, and timeout controls

Runra Sandbox provides VM-backed isolation for every sandbox. This means each sandbox runs in its own virtual machine, not just a container — giving you stronger security boundaries than container-based solutions.

VM-backed execution

Each sandbox runs inside a dedicated VM provisioned by CubeSandbox, the open-source engine that powers Runra. This provides:

  • Kernel-level isolation: Separate kernel instances prevent privilege escalation between sandboxes
  • No shared OS state: /proc, /sys, and other kernel interfaces are sandbox-private
  • Guaranteed resource allocation: CPU cores and memory pages are assigned per VM, not shared
┌─────────────────────────────────────────────┐
│                  Host Node                   │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ Sandbox A│  │ Sandbox B│  │ Sandbox C│  │
│  │  VM #1   │  │  VM #2   │  │  VM #3   │  │
│  │ CPU: 2   │  │ CPU: 4   │  │ CPU: 8   │  │
│  │ RAM: 4GB │  │ RAM: 8GB │  │ RAM:16GB │  │
│  └──────────┘  └──────────┘  └──────────┘  │
│         ↕              ↕              ↕      │
│  ┌──────────────────────────────────────┐   │
│  │         CubeProxy (network layer)     │   │
│  └──────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

File system isolation

Every sandbox gets its own private filesystem workspace. There is no shared filesystem between sandboxes:

const sandboxA = await runra.sandboxes.create({ image: "node:22" });
const sandboxB = await runra.sandboxes.create({ image: "node:22" });

await sandboxA.files.write("/workspace/secret.txt", "token-abc");
await sandboxB.files.write("/workspace/secret.txt", "token-xyz");

// Each sandbox only sees its own file
const a = await sandboxA.files.read("/workspace/secret.txt"); // "token-abc"
const b = await sandboxB.files.read("/workspace/secret.txt"); // "token-xyz"

Workspace structure

/workspace/              ← Your sandbox workspace (persisted across pause/resume)
├── app/                 ← Your application code
├── node_modules/        ← Dependencies (preserved on pause)
└── ...
/tmp/                    ← Ephemeral temp (cleared on sandbox restart)

File operations

All standard file operations go through the sandbox API:

// Write a file
await sandbox.files.write("/workspace/app.ts", content);

// Read a file
const content = await sandbox.files.read("/workspace/app.ts");

// List directory
const files = await sandbox.files.list("/workspace");

// Check if exists
const exists = await sandbox.files.exists("/workspace/app.ts");

// Delete a file
await sandbox.files.delete("/workspace/temp.log");

// Create directory
await sandbox.files.mkdir("/workspace/src/components");

Process isolation

Processes in one sandbox cannot see or interact with processes in another:

// Sandbox A runs a server
await sandboxA.exec("python -m http.server 8000 &");

// Sandbox B cannot see the server process
const result = await sandboxB.exec("ps aux");
// Shows only sandbox B's processes — no http.server from sandbox A

Each sandbox has its own PID namespace, mount namespace, and IPC namespace — standard Linux namespace isolation reinforced by the VM boundary.

Resource limits

Every sandbox has hard resource limits that cannot be exceeded:

ResourceDefaultMaxDescription
CPU cores28Dedicated vCPUs
Memory4096 MB16384 MBHard limit, OOM kill on exceed
Disk10240 MB51200 MBWorkspace storage
Processes2561024Max simultaneous processes
const sandbox = await runra.sandboxes.create({
  image: "node:22",
  resources: {
    cpu: 4,           // 4 dedicated vCPUs
    memoryMb: 8192,   // 8 GB RAM (hard limit)
    diskMb: 20480,    // 20 GB disk
  },
});

If a sandbox exceeds its memory limit, the kernel OOM killer terminates the offending process. If CPU usage is sustained at 100%, the VM is throttled to its allocated cores — no noisy neighbor problems.

Network policy

Network access is controlled per sandbox:

const sandbox = await runra.sandboxes.create({
  image: "node:22",
  network: {
    // Allow outbound to specific hosts
    egress: {
      allow: ["github.com", "registry.npmjs.org", "api.openai.com"],
      // Block everything else
      default: "deny",
    },
    // Inbound is only through exposed ports
    ingress: {
      allowPorts: [3000, 8080],
    },
  },
});

Default network policy

DirectionDefaultDescription
Outbound (egress)Allow allSandbox can reach any internet host
Inbound (ingress)Deny allOnly ports explicitly exposed are accessible
Sandbox-to-sandboxDenySandboxes cannot communicate with each other

Port exposure

Only explicitly exposed ports are reachable from the internet:

// Expose port 3000 — generates a public URL
const port = await sandbox.exposePort(3000);
console.log(port.url); // https://3000-abc123.box.runra.dev

See Exposing Ports for the full port exposure guide.

Timeout and lifecycle controls

Prevent runaway sandboxes with automatic lifecycle controls:

const sandbox = await runra.sandboxes.create({
  image: "node:22",
  timeoutMs: 300_000,    // Auto-terminate after 5 minutes (hard limit)
  idleTimeoutMs: 120_000, // Auto-pause after 2 minutes of inactivity
});

Timeout types

TimeoutTriggerAction
timeoutMsTotal sandbox lifetime exceededForce terminate
idleTimeoutMsNo exec calls for specified durationAuto-pause
Per-command timeoutIndividual exec() takes too longAbort command, sandbox stays running
// Per-command timeout
const result = await sandbox.exec("npm run long-build", {
  timeoutMs: 60_000, // Kill if build takes more than 60 seconds
});

Disposable environments

Every sandbox is disposable by design. Terminate cleans up all resources immediately:

await sandbox.terminate();
// VM destroyed, disk wiped, ports released, IP recycled

No data persists after termination. If you need state to survive, use pause instead.

Security guarantees

Runra Sandbox provides these security guarantees:

  1. No cross-sandbox access: Sandbox A cannot read Sandbox B's files, processes, or network traffic
  2. No host escape: VM isolation prevents escape to the host node
  3. No resource stealing: Hard resource limits prevent one sandbox from starving others
  4. No persistent side effects: Termination wipes everything
  5. Network control: You control what each sandbox can reach

Next steps