> ## Documentation Index
> Fetch the complete documentation index at: https://docs.microsandbox.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Sandbox commands

> Create, run, and interact with sandboxes from the CLI

## msb run

Create a sandbox and optionally run a command. Without `--name`, the sandbox is ephemeral and removed when the command finishes. With `--name`, it persists for later use.

```bash theme={null}
# Ephemeral: runs and cleans up
msb run python -- python -c "print('hello')"

# Named: persists after exit
msb run --name devbox ubuntu -- bash

# With volumes, ports, and environment
msb run --name api \
  -v ./src:/app \
  -v pydata:/data \
  -p 8000:8000 \
  -e DEBUG=true \
  --label user.id=alice \
  -w /app \
  python

# Detached (boots in background; run work later with exec)
msb run -d --name worker python
msb exec worker -- python worker.py

# Publish on all IPv4 host interfaces instead of the default 127.0.0.1
msb run --name public-api -p 0.0.0.0:8000:8000 python
```

Common flags:

| Flag                                                           | Description                                                                                                                                                                                                   |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-n`, `--name`                                                 | Sandbox name. If omitted, the sandbox is ephemeral                                                                                                                                                            |
| `-c`, `--cpus`                                                 | Virtual CPU limit                                                                                                                                                                                             |
| `-m`, `--memory`                                               | Memory limit, such as `512M` or `1G`                                                                                                                                                                          |
| `-v`, `--volume`                                               | Mount a host path or named volume, such as `./src:/app:ro`                                                                                                                                                    |
| `--mount-dir`, `--mount-file`, `--mount-disk`, `--mount-named` | Mount a source with an explicit kind (`SOURCE:DEST[:OPTIONS]` or `NAME:DEST[:OPTIONS]`). `--mount-named` creates missing named volumes idempotently and accepts `kind=dir\|disk`, `size=...`, and `quota=...` |
| `-p`, `--port`                                                 | Publish a port, such as `8000:8000` or `0.0.0.0:8000:8000`                                                                                                                                                    |
| `-e`, `--env`                                                  | Set an environment variable                                                                                                                                                                                   |
| `--label`                                                      | Attach a label for metric attribution (`KEY=VALUE`, or bare `KEY`). Repeatable                                                                                                                                |
| `-w`, `--workdir`                                              | Set the working directory                                                                                                                                                                                     |
| `-d`, `--detach`                                               | Boot in the background. Run work later with `msb exec`                                                                                                                                                        |
| `--replace`                                                    | Replace an existing sandbox with the same name                                                                                                                                                                |
| `--no-net`                                                     | Disable network access                                                                                                                                                                                        |
| `--net-rule`                                                   | Add a network policy rule                                                                                                                                                                                     |
| `--secret`                                                     | Inject a host-held secret for an allowed destination                                                                                                                                                          |
| `--tmpfs`                                                      | Mount an in-memory filesystem                                                                                                                                                                                 |
| `--copy`, `--copy-file`, `--copy-dir`, `--mkdir`, `--rm`       | Patch the rootfs before boot                                                                                                                                                                                  |

Use `msb run --help` for the full flag list.

### Network rule syntax

`--net-rule` takes one or more comma-separated rule tokens. The token grammar is:

```
<action>[:<direction>]@<target>[:<proto>[:<ports>]]
```

| Field       | Values                                            |
| ----------- | ------------------------------------------------- |
| `action`    | `allow`, `deny`                                   |
| `direction` | `egress` (default), `ingress`, `any`              |
| `target`    | See *Targets* below                               |
| `proto`     | `tcp`, `udp`, `icmpv4`, `icmpv6`, `any` (default) |
| `ports`     | `<port>`, `<lo>-<hi>`, or `any` (default)         |

**Targets**

| Form           | Example                                                                       | Notes                                                                                                                                                             |
| -------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| IP / CIDR      | `198.51.100.5`, `10.0.0.0/8`, `[2001:db8::]/32`                               | IPv6 must be bracketed                                                                                                                                            |
| Domain (exact) | `example.com`                                                                 | Use `domain=public` to disambiguate from the `public` group                                                                                                       |
| Domain suffix  | `*.example.com`, `suffix=example.com`                                         | Matches the apex and any subdomain at any depth. Suffixes must be at least two labels: `*.com` and `suffix=local` are rejected to prevent accidental blast radius |
| Group          | `public`, `private`, `multicast`, `loopback`, `link_local`, `metadata`, `any` | Pre-defined IP groups                                                                                                                                             |

Wildcard quoting: the rule grammar uses `@`, `:`, and `,` which are shell-significant, so always quote `--net-rule` values. The `*.` in suffix shorthand mirrors the syntax already used by `--tls-bypass` and `--secret`.

**Common compositions**

```bash theme={null}
# Allowlist: deny by default, allow specific destinations
msb run alpine --net-default deny --net-rule "allow@github.com,allow@*.githubusercontent.com"

# Blocklist: allow by default, deny specific destinations
msb run alpine --net-default allow --net-rule "deny@*.tracking.com,deny@*.ads.example"

# Airgapped: equivalent to `--net-default deny`
msb run alpine --no-net

# Airgapped except one host (allowlist with --no-net sugar)
msb run alpine --no-net --net-rule "allow@api.internal.corp"
```

## msb create

Create and boot a sandbox without running a command. Takes the same flags as `msb run` (except `--detach`).

```bash theme={null}
msb create python --name worker -c 2 -m 1G
msb create --replace python --name worker            # Replace existing
msb create --replace-with-timeout 30s python --name worker  # Give the old one 30s to exit
msb create --replace-with-timeout 0 python --name worker    # SIGKILL immediately
```

## msb start

Resume a stopped sandbox. Name one or more sandboxes, or select them by label.

```bash theme={null}
msb start devbox
msb start --label app=engine          # start every sandbox labelled app=engine
```

| Flag            | Description                                                                                                      |
| --------------- | ---------------------------------------------------------------------------------------------------------------- |
| `--label`       | Start every sandbox carrying this label (`KEY=VALUE`). Repeatable; AND-matched. Unioned with any named sandboxes |
| `-q`, `--quiet` | Suppress progress output                                                                                         |

## msb stop

```bash theme={null}
msb stop devbox                # Graceful shutdown (10s grace)
msb stop --force devbox        # Force kill immediately
msb stop -t 30 devbox          # 30s grace before force kill
msb stop --label app=engine    # stop every sandbox labelled app=engine
```

Graceful shutdown gives the sandbox a chance to finish writing any
pending data to disk before it exits, so files written inside the
sandbox aren't lost across a later `msb start`. If the sandbox is
still running after the timeout, it is force-killed.

`--force` and a timeout that elapses both end in a force-kill. Pending
writes that the workload hasn't `fsync`'d at that point may be lost —
same durability semantics as a sudden power loss on a physical
machine. For durable writes, workloads should `fsync` important data
themselves.

| Flag              | Description                                                                                                     |
| ----------------- | --------------------------------------------------------------------------------------------------------------- |
| `--label`         | Stop every sandbox carrying this label (`KEY=VALUE`). Repeatable; AND-matched. Unioned with any named sandboxes |
| `-f`, `--force`   | Force terminate immediately. Pending writes may be lost                                                         |
| `-t`, `--timeout` | Seconds to wait for graceful shutdown before force-killing. Defaults to 10                                      |
| `-q`, `--quiet`   | Suppress progress output                                                                                        |

## msb exec

Execute a command inside a running sandbox.

```bash theme={null}
msb exec devbox -- python -c "print('hello')"
msb exec devbox -- ls -la /app
```

| Flag              | Description                                                   |
| ----------------- | ------------------------------------------------------------- |
| `-t`, `--tty`     | Allocate a pseudo-terminal (enables colors, line editing)     |
| `-e`, `--env`     | Set an environment variable (`KEY=VALUE`)                     |
| `-w`, `--workdir` | Override working directory                                    |
| `-u`, `--user`    | Run the command as the specified guest user                   |
| `--timeout`       | Kill the command after this duration (e.g. `30s`, `5m`, `1h`) |
| `--rlimit`        | Set a POSIX resource limit (e.g. `nofile=1024`, `nproc=64`)   |
| `-q`, `--quiet`   | Suppress progress output                                      |

<Tip>
  The CLI auto-detects whether stdin is a terminal. When interactive, `msb exec` uses `attach` mode (TTY, line editing). When piped, it captures output. No `-i` flag is needed.
</Tip>

## msb copy

Copy files between the host and a sandbox.

```bash theme={null}
msb copy ./local.txt devbox:/tmp/local.txt
msb copy devbox:/tmp/out.txt ./out.txt
msb copy devbox:/tmp/a devbox:/tmp/b
msb copy devbox:/tmp/a otherbox:/tmp/a
```

Host-to-sandbox and sandbox-to-host forms follow `docker cp` syntax. Same-sandbox and cross-sandbox forms are microsandbox extensions.

`msb copy` connects to an existing sandbox and starts it temporarily if needed, following the same lifecycle ownership behavior as `msb exec`. The shorter `msb cp` form is available as an alias.

| Flag            | Description              |
| --------------- | ------------------------ |
| `-q`, `--quiet` | Suppress progress output |

## msb logs

Read captured output from a sandbox. Each sandbox stores its captured stdio under `<sandbox-dir>/logs/exec.log` as JSON Lines, plus runtime/kernel diagnostics in `runtime.log`/`kernel.log`. The command works on running and stopped sandboxes alike — there is no protocol traffic, just a file read.

```bash theme={null}
# Captured user-program output (default sources: stdout + stderr + output)
msb logs devbox

# Tail and follow
msb logs devbox --tail 100
msb logs devbox -f --grep ERROR

# Time-bounded
msb logs devbox --since 5m
msb logs devbox --since 2026-04-30T20:00:00Z --until 5m

# JSON Lines passthrough — feed to jq, vector, etc.
msb logs devbox --json | jq 'select(.s == "stderr")'

# Multi-session view: prefix each line with [id:N] so you can tell sessions apart
msb logs devbox --show-id

# Color each session's output a distinct color (implies --show-id)
msb logs devbox --color-sessions

# Include runtime/kernel diagnostics
msb logs devbox --source system
msb logs devbox --source all                # everything, chronologically merged
```

| Flag               | Description                                                                                                                  |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `--tail`           | Show only the last N entries                                                                                                 |
| `--since`          | Show entries at or after this time (RFC 3339 or relative `5m`/`2h`/`1d`)                                                     |
| `--until`          | Show entries strictly before this time (same formats)                                                                        |
| `-f`, `--follow`   | Follow in real time (200 ms polling, rotation-aware)                                                                         |
| `--timestamps`     | Prefix each line with the entry timestamp                                                                                    |
| `--source`         | Sources to include: `stdout`, `stderr`, `output`, `system`, `all`. Repeat or comma-separate. Default: `stdout,stderr,output` |
| `--grep`           | Client-side regex filter on the entry body                                                                                   |
| `--json`           | Emit raw JSON Lines without decoding (one entry per line)                                                                    |
| `--raw`            | Opt into base64 encoding for non-UTF-8 bytes                                                                                 |
| `--show-id`        | Prefix each line with `[id:N]` (the session correlation id)                                                                  |
| `--color-sessions` | Color each session's lines a distinct color (implies `--show-id`)                                                            |
| `--color`          | ANSI handling: `auto` (default), `always`, `never`                                                                           |
| `--no-color`       | Alias for `--color=never`                                                                                                    |

**Source tags** (the `s` field in `--json` output):

* `stdout` / `stderr` — captured from the session's pipes when running in **pipe mode** (streams stay separated end to end).
* `output` — captured from the session in **pty mode**. pty allocation merges stdout and stderr at the kernel level inside the guest, so they arrive as a single stream — tagged `output` rather than mislabelled as `stdout`.
* `system` — synthetic lifecycle markers (`--- sandbox started ---` / `--- sandbox stopped ---`) plus diagnostic lines from `runtime.log`/`kernel.log` when `--source system` is requested.

<Tip>
  If a sandbox failed to start, `msb logs` prepends a styled error block reconstructed from `boot-error.json`. The block tells you the failure stage, errno, and a hint — even though no user-program output was ever captured.
</Tip>

## msb ls

List all stored sandboxes.

```bash theme={null}
msb ls                    # All sandboxes (running and stopped)
msb ls --running          # Running sandboxes only
msb ls --stopped          # Stopped sandboxes only
msb ls --label app=engine # Only sandboxes labelled app=engine
msb ls --format json      # JSON output
msb ls -q                 # Names only
```

| Flag            | Description                                                                    |
| --------------- | ------------------------------------------------------------------------------ |
| `--running`     | Show only running sandboxes                                                    |
| `--stopped`     | Show only stopped sandboxes                                                    |
| `--label`       | Show only sandboxes carrying this label (`KEY=VALUE`). Repeatable; AND-matched |
| `--format`      | Output format (`json`)                                                         |
| `-q`, `--quiet` | Show only sandbox names                                                        |

## msb status / ps

Show sandbox status with process details.

```bash theme={null}
msb ps                    # Running sandboxes
msb ps my-app             # Single sandbox
msb ps -a                 # All sandboxes (including stopped)
msb ps --format json      # JSON output
```

| Flag            | Description                                                                                                        |
| --------------- | ------------------------------------------------------------------------------------------------------------------ |
| `-a`, `--all`   | Show all sandboxes, not just running ones                                                                          |
| `--label`       | Show only sandboxes carrying this label (`KEY=VALUE`). Repeatable; AND-matched. Not combinable with a sandbox name |
| `--format`      | Output format (`json`)                                                                                             |
| `-q`, `--quiet` | Show only sandbox names                                                                                            |

## msb metrics

Show live CPU, memory, disk, and network metrics for running sandboxes.

```bash theme={null}
msb metrics               # All running sandboxes
msb metrics my-app        # Single sandbox
msb metrics --format json # JSON output
```

| Flag       | Description            |
| ---------- | ---------------------- |
| `--format` | Output format (`json`) |

## msb inspect

Show detailed configuration and status.

```bash theme={null}
msb inspect devbox
msb inspect devbox --format json
```

| Flag       | Description            |
| ---------- | ---------------------- |
| `--format` | Output format (`json`) |

## msb rm

Remove one or more sandboxes and their associated state.

```bash theme={null}
msb rm devbox
msb rm --force devbox            # Stop and remove in one step
msb rm worker-1 worker-2         # Remove multiple
msb rm --force --label app=engine  # Remove every sandbox labelled app=engine
```

| Flag            | Description                                                                                                       |
| --------------- | ----------------------------------------------------------------------------------------------------------------- |
| `--label`       | Remove every sandbox carrying this label (`KEY=VALUE`). Repeatable; AND-matched. Unioned with any named sandboxes |
| `-f`, `--force` | Stop the sandbox if running, then remove it                                                                       |
| `-q`, `--quiet` | Suppress progress output                                                                                          |

## msb install

Install a sandbox as a system command. Creates an executable in `~/.microsandbox/bin/` that launches `msb run` with the specified image and options.

```bash theme={null}
msb install ubuntu                   # Install as 'ubuntu' command
msb install --name nodebox node      # Custom command name
msb install --tmp alpine             # Fresh sandbox every invocation
msb install -c 2 -m 1G python  # With resource limits
msb install --list                   # List installed commands
```

| Flag                                                           | Description                                                                                                                                                                                                   |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-n`, `--name`                                                 | Command name for the alias (defaults to image name)                                                                                                                                                           |
| `-c`, `--cpus`                                                 | Number of virtual CPUs to allocate                                                                                                                                                                            |
| `-m`, `--memory`                                               | Amount of memory (e.g. `512M`, `1G`)                                                                                                                                                                          |
| `-v`, `--volume`                                               | Mount a host path or named volume (`SOURCE:DEST[:OPTIONS]`, e.g. `./src:/app:ro,noexec`)                                                                                                                      |
| `--mount-dir`, `--mount-file`, `--mount-disk`, `--mount-named` | Mount a source with an explicit kind (`SOURCE:DEST[:OPTIONS]` or `NAME:DEST[:OPTIONS]`). `--mount-named` creates missing named volumes idempotently and accepts `kind=dir\|disk`, `size=...`, and `quota=...` |
| `--security`                                                   | In-guest security profile (`default` or `restricted`)                                                                                                                                                         |
| `-w`, `--workdir`                                              | Working directory inside the sandbox                                                                                                                                                                          |
| `--shell`                                                      | Shell for interactive sessions                                                                                                                                                                                |
| `-e`, `--env`                                                  | Set an environment variable (`KEY=VALUE`)                                                                                                                                                                     |
| `-f`, `--force`                                                | Overwrite an existing alias with the same name                                                                                                                                                                |
| `--no-pull`                                                    | Don't pull the image before installing                                                                                                                                                                        |
| `--tmp`                                                        | Create a fresh sandbox on every invocation (no persistent state)                                                                                                                                              |
| `-l`, `--list`                                                 | List all installed sandbox commands                                                                                                                                                                           |

## msb uninstall

Remove an installed sandbox command.

```bash theme={null}
msb uninstall nodebox
msb uninstall ubuntu alpine   # Remove multiple
```

## msb self

Manage the msb installation itself.

```bash theme={null}
msb self update               # Update msb and libkrunfw to latest
msb self update --force       # Re-download even if up to date
msb self uninstall            # Remove msb (with confirmation prompt)
msb self uninstall --yes      # Skip confirmation
```

| Subcommand                  | Description                                                              |
| --------------------------- | ------------------------------------------------------------------------ |
| `update` (alias: `upgrade`) | Update msb and libkrunfw to the latest release and refresh command links |
| `uninstall`                 | Remove msb, libkrunfw, and command links                                 |

| Flag            | Subcommand  | Description                                       |
| --------------- | ----------- | ------------------------------------------------- |
| `-f`, `--force` | `update`    | Re-download even if already on the latest version |
| `-y`, `--yes`   | `uninstall` | Skip confirmation prompt                          |
