How to Handle Communication Between the Main Thread and Microsandbox

The main thread communicates with a microsandbox through a private runtime control socket that accepts JSON commands for live CPU/memory resizing, secret rotation, and graceful shutdown without restarting the guest VM.

The microsandbox crate (maintained by SuperRad Company) implements an isolated, message-based control channel rather than direct inter-process communication. This design ensures that the host application can manage running sandboxes without breaking isolation boundaries. The source code reveals a structured protocol built on Unix sockets (or Windows named pipes) and JSON-line messaging.

Understanding the Runtime Control Socket

Each microsandbox exposes a runtime control socket that the host uses to issue live-update commands. This socket is created by the VM's control_handle and listened on by the sandbox agent inside the guest.

According to the source code in crates/runtime/lib/vm.rs, the control listener spawns alongside the VM, creating a private communication endpoint. The socket path derives from the agent socket via helpers in crates/runtime/lib/ipc.rs, ensuring each sandbox has its own isolated control channel.

Discovering and Connecting to the Control Socket

Before sending commands, the host must verify the sandbox is running and locate the active socket.

The live_control function in sdk/rust/lib/sandbox/modify.rs (lines 31-47) performs this validation:

  1. Checks sandbox status is running
  2. Verifies the control socket exists via control_socket_exists (lines 60-71)
  3. Queries supported operations via control_capabilities

Once validated, the connection flow differs by platform:

  • Unix: connect_control_socket (lines 114-127) builds candidate paths from sandbox_agent_socket_path_candidates and connects with tokio::net::UnixStream
  • Windows: connect_control_pipe (lines 62-71) creates a named-pipe client

Sending Control Requests

All control communication uses JSON-line protocol terminated by \n. The generic helper control_request in sdk/rust/lib/sandbox/modify.rs (lines 88-100) handles this:

// Writes request to stream, reads one response line
// Deserializes into ControlResponse and checks ok flag

The low-level control_request_over_stream (lines 136-152) implements the actual framing logic for reuse across transport types.

Supported Live Operations

The control protocol supports several operation types, each with dedicated Rust helper functions:

CPU Resize

The control_cpu_target function (lines 100-108) sends:

{"op":"cpu_target","online":N}

Returns CpuControlState indicating the new configuration.

Memory Resize

The control_memory_target function (lines 84-92) sends:

{"op":"memory_target","total_mib":M}

Returns MemoryControlState with the applied memory limit.

Secret Rotation

The control_secrets_update function (lines 71-78) sends a batch of SecretLiveChange operations:

{"op":"secrets_update","changes":[...]}

Supports rotate, remove, and allowed-hosts modifications.

Graceful Shutdown

The shutdown operation sends {"op":"shutdown"} and cleanly terminates the sandbox. This is exercised in the test suite at sdk/rust/tests/correlation_ids.rs (lines 14-22).

Applying Modifications Through the Builder API

The high-level SandboxModificationBuilder in sdk/rust/lib/sandbox/modify.rs orchestrates live changes. Its apply method (lines 22-44) implements the following decision logic:

// If change classified as Live and no restart required:
if !restart_required && let Some(target) = live_cpu_target {
    control_cpu_target(name, target).await?;
}
// Similar blocks for memory_target, secrets_update...

If any live request fails, the error propagates immediately and the sandbox state remains unchanged.

Practical Code Examples

Rust SDK Example

use microsandbox::sandbox::SandboxBuilder;

// Build and start a sandbox
let sandbox = SandboxBuilder::new("demo")
    .image("docker.io/library/ubuntu:latest")
    .start()
    .await?;

// Live CPU resize to 4 vCPUs
sandbox.modify()
    .cpus(4)
    .apply()
    .await?;

// Rotate a secret without restart
sandbox.modify()
    .secret(|s| s
        .env("API_KEY")
        .source(microsandbox::SecretSource::Env { 
            var: "API_KEY".into() 
        })
    )
    .apply()
    .await?;

TypeScript Client Example

For external consumers, the @microsandbox/agent-client package mirrors the Rust API:

import { AgentClient } from "@microsandbox/agent-client";

const client = new AgentClient(
  "unix:/var/run/microsandbox/worker/runtime/agent.sock"
);

// Resize memory live
await client.controlRequest({
  op: "memory_target",
  total_mib: 2048,
});

// Rotate a secret
await client.controlRequest({
  op: "secrets_update",
  changes: [
    { type: "rotate", name: "DB_PASSWORD", value: "new-secret" }
  ],
});

Architecture Isolation Guarantees

The control socket design maintains strict boundaries:

  • Per-sandbox sockets: Each VM has a unique control endpoint derived from its agent socket
  • JSON-only protocol: No arbitrary code execution possible through the control channel
  • Capability discovery: Host queries supported operations before attempting them
  • Atomic failure: Failed live updates leave the sandbox in its previous state

The host never communicates directly with guest userland; all messages route through the sandbox agent, which validates and applies changes internally.

Key Source Files

File Purpose
sdk/rust/lib/sandbox/modify.rs High-level modification API and control-socket workflow
crates/runtime/lib/ipc.rs Control socket path construction from agent socket
crates/runtime/lib/control.rs Request/response JSON structure definitions
crates/runtime/lib/vm.rs Control handle creation and listener spawning
packages/agent-client/typescript/src/client.ts TypeScript client implementation

Summary

  • Main thread to microsandbox communication uses a private runtime control socket, not direct VM access
  • Connection flow: discover capabilities → connect socket → send JSON-line requests → parse responses
  • Supported operations: CPU resize, memory resize, secret rotation, graceful shutdown
  • Platform abstraction: Unix sockets via tokio::net::UnixStream, Windows via named pipes
  • Failure handling: Live operations propagate errors immediately without changing sandbox state
  • Isolation: Each sandbox has a unique control endpoint; no cross-sandbox interference possible

Frequently Asked Questions

What protocol does microsandbox use for main thread communication?

Microsandbox uses a JSON-line protocol over Unix sockets (or Windows named pipes). Each request is a single JSON object terminated by \n, with a matching JSON response. The protocol is defined in crates/runtime/lib/control.rs and implemented in sdk/rust/lib/sandbox/modify.rs.

Can I resize CPU or memory without restarting the sandbox?

Yes, if the sandbox reports control_capabilities indicating support. The SandboxModificationBuilder.apply() method automatically attempts live updates when possible, falling back to restart only when necessary. CPU resize uses control_cpu_target; memory resize uses control_memory_target.

How do I know if a live operation succeeded?

Each control request returns a ControlResponse with an ok boolean flag. The control_request helper in modify.rs checks this flag and returns an error if ok is false. For builder API users, apply().await? propagates any failure as a Rust Result::Err.

Is the control socket accessible to other processes?

No. The control socket path derives from the sandbox's private agent socket directory, typically under /var/run/microsandbox/ or a configurable runtime directory. The socket permissions and path unpredictability prevent cross-sandbox or external process interference.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →