Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/agentd/lib/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -927,7 +927,7 @@ mod tests {
cmd: "/bin/sh".to_string(),
args: vec![
"-c".to_string(),
"i=0; while [ $i -lt 1024 ]; do printf AAAA; i=$((i+1)); done; printf SECOND; sleep 1; printf '<END>\\n'; sleep 1; exit 0"
"i=0; while [ $i -lt 1024 ]; do printf AAAA; i=$((i+1)); done; printf SECOND; sleep 0.1; printf '<END>\\n'; sleep 0.1; exit 0"
.to_string(),
],
env: vec!["PATH=/usr/local/bin:/usr/bin:/bin".to_string()],
Expand All @@ -943,7 +943,7 @@ mod tests {
let mut stdout = Vec::new();
let mut exit = None;

let recv_result = timeout(Duration::from_secs(5), async {
let recv_result = timeout(Duration::from_secs(15), async {
while let Some((id, output)) = rx.recv().await {
assert_eq!(id, 7);
match output {
Expand Down
136 changes: 136 additions & 0 deletions docs/configuration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
title: config.json
description: Global config.json reference
icon: "gear"
---

microsandbox reads its global configuration from `~/.microsandbox/config.json`. All fields are optional. A missing file or empty JSON object is equivalent to using the defaults.

<Accordion title="Full example">
```json
{
"home": "/custom/path/.microsandbox",
"log_level": "info",
"database": {
"url": "sqlite:///tmp/msb.db",
"max_connections": 10
},
"paths": {
"msb": "/usr/local/bin/msb",
"libkrunfw": "/usr/local/lib/libkrunfw.so",
"cache": "/mnt/fast/msb-cache",
"sandboxes": null,
"volumes": null,
"logs": null,
"secrets": null
},
"sandbox_defaults": {
"cpus": 2,
"memory_mib": 1024,
"shell": "/bin/bash",
"workdir": "/app"
},
"registries": {
"auth": {
"ghcr.io": {
"username": "octocat",
"store": "keyring"
},
"registry.example.com": {
"username": "deploy",
"password_env": "REGISTRY_TOKEN"
},
"docker.io": {
"username": "user",
"secret_name": "dockerhub-token"
}
}
}
}
```
</Accordion>

## Top-level fields

| Field | Default | Description |
|-------|---------|-------------|
| `home` | `~/.microsandbox` | Root directory for all microsandbox data |
| `log_level` | `null` (silent) | Log level for sandbox processes: `error`, `warn`, `info`, `debug`, `trace` |
| `database` | [reference](#database) | Database connection settings |
| `paths` | [reference](#paths) | Path overrides for binaries and directories |
| `sandbox_defaults` | [reference](#sandbox_defaults) | Defaults applied to every sandbox |
| `registries` | [reference](#registries) | Container registry authentication |

## `database`

| Field | Default | Description |
|-------|---------|-------------|
| `url` | `null` | Database URL. Uses SQLite under `home` when null |
| `max_connections` | `5` | Maximum connection pool size |

## `paths`

All path fields are optional. When `null`, they resolve relative to `home`.

| Field | Default | Description |
|-------|---------|-------------|
| `msb` | `{home}/bin/msb` | `msb` binary. Resolved via: `MSB_PATH` env, this field, default path, `PATH` |
| `libkrunfw` | `{home}/lib/libkrunfw` | Path to a custom VM kernel (`.so` on Linux, `.dylib` on macOS) |
| `cache` | `{home}/cache` | Image layer cache |
| `sandboxes` | `{home}/sandboxes` | Per-sandbox state |
| `volumes` | `{home}/volumes` | Named volumes |
| `logs` | `{home}/logs` | Sandbox logs |
| `secrets` | `{home}/secrets` | Secrets. Registry secrets live under `secrets/registries/` |

## `sandbox_defaults`

Defaults applied to every sandbox unless overridden per-sandbox.

| Field | Default | Description |
|-------|---------|-------------|
| `cpus` | `1` | Number of vCPUs |
| `memory_mib` | `512` | Guest memory in MiB |
| `shell` | `"/bin/sh"` | Shell for interactive sessions and scripts |
| `workdir` | `null` | Working directory inside the sandbox |

## `registries`

### `registries.auth`

A map of registry hostnames to authentication entries. Each entry specifies a username and exactly **one** credential source.

```json
{
"registries": {
"auth": {
"ghcr.io": {
"username": "octocat",
"store": "keyring"
}
}
}
}
```

#### Auth entry fields

| Field | Required | Description |
|-------|----------|-------------|
| `username` | Yes | Registry username |
| `store` | No | Credential store. Only `"keyring"` is supported (macOS Keychain, Windows Credential Manager, Linux Secret Service) |
| `password_env` | No | Environment variable containing the password or token |
| `secret_name` | No | Filename under `{home}/secrets/registries/` containing the password or token |

<Note>
Exactly one of `store`, `password_env`, or `secret_name` must be set per entry. Setting none or more than one is an error.
</Note>

### Auth resolution order

When pulling from a registry, credentials are resolved in this order:

1. **Explicit SDK auth** via `.registry_auth()` on the sandbox builder
2. **OS keyring** entries created by `msb registry login`
3. **Config file** `registries.auth` entries in `config.json`
4. **Docker config** `~/.docker/config.json` credential helpers
5. **Anonymous** (no authentication)
7 changes: 7 additions & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
"quickstart"
]
},
{
"group": "Configuration",
"icon": "gear",
"pages": [
"configuration"
]
},
{
"group": "Sandboxes",
"icon": "box",
Expand Down
Loading