Capsa is experimental software. APIs may change without notice.
Skip to content

Core Concepts ​

This page explains the key concepts in Capsa and when to use each approach.

Sandbox vs Raw VM ​

Capsa offers two ways to run code in a VM:

AspectSandboxRaw VM
SetupZero configBring your own kernel/initrd
Command executionAgent RPCConsole scraping
File operationsagent.read_file(), agent.write_file()Manual via console
Shared directoriesAuto-mountedManual mount required
Best forMost use casesCustom OS, specialized kernels

Use Sandbox When You Need ​

  • Isolated code execution (AI agents, untrusted code)
  • Integration testing
  • Build environments
  • Structured command output (exit codes, stdout, stderr)

Use Raw VM When You Need ​

  • Custom kernel configuration
  • Non-Linux operating systems
  • Specific kernel modules
  • Full control over the boot process

Agent vs Console ​

The agent and console serve different purposes:

The agent is a built-in RPC service that runs inside sandboxes:

rust,no_run
// Structured command execution
let result = agent.exec("ls").arg("/").run().await?;
println!("stdout: {}", result.stdout);
println!("stderr: {}", result.stderr);
println!("exit_code: {}", result.exit_code);

// Direct file operations
let data = agent.read_file("/etc/hostname").await?;
agent.write_file("/tmp/output.txt", b"hello").await?;

Advantages:

  • Structured output (no parsing required)
  • Proper exit codes
  • File read/write operations
  • System information queries
  • Clean shutdown

Console ​

The console provides raw serial port access:

rust,no_run
// Wait for boot
console.wait_for("login:", Duration::from_secs(30)).await?;

// Manual interaction
console.write_line("root").await?;
let output = console.read_available().await?;

Use for:

  • Waiting for boot output
  • Interactive troubleshooting
  • VMs without agent support

Boot Configurations ​

Linux Direct Boot ​

Boots a Linux kernel directly without a bootloader:

rust,no_run
let boot = LinuxDirectBoot::new("./kernel", "./initrd")
    .with_root_disk("./rootfs.raw");

let vm = capsa::vm(boot)
    .cmdline_arg("console", "ttyS0")
    .build()
    .await?;

Used by both sandboxes (internally) and raw VMs.

UEFI Boot (macOS only) ​

Boots from a disk image using UEFI:

rust,no_run
let boot = UefiBoot::new("./disk.img");

Networking ​

VirtualNetwork ​

Provides NAT networking with optional policies:

rust,no_run
let policy = NetworkPolicy::deny_all()
    .allow_domain("api.github.com")
    .allow_domain("*.rust-lang.org");

let network = VirtualNetwork::with_gateway(
    Gateway::new("10.0.2.0/24").unwrap().policy(policy).unwrap()
);

No Network ​

Completely isolated - no network access:

rust,no_run
let vm = capsa::sandbox()
    .no_network()
    .build()
    .await?;

Shared Directories ​

Share host directories with the VM using virtio-fs:

rust,no_run
let vm = capsa::sandbox()
    .share("./src", "/mnt/src", AccessMode::ReadOnly)
    .share("./output", "/mnt/output", AccessMode::ReadWrite)
    .build()
    .await?;

In sandbox mode, directories are automatically mounted. In raw VMs, you must mount them manually inside the guest.

Next Steps ​

Released under the MIT License.