e0e362d700
SDK Tests / changes (push) Successful in 2m29s
Real E2E Tests / changes (push) Successful in 2m29s
Deploy Docs Pages / build (push) Has been cancelled
Deploy Docs Pages / deploy (push) Has been cancelled
Real E2E Tests / JavaScript E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Python E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Java E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / C# E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Go E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Real E2E CI (push) Has been cancelled
SDK Tests / SDK CI (push) Has been cancelled
SDK Tests / CLI Tests (push) Has been cancelled
SDK Tests / Python SDK Quality (code-interpreter) (push) Has been cancelled
SDK Tests / Python SDK Quality (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (sandbox) (push) Has been cancelled
SDK Tests / CLI Quality (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Go SDK Quality And Tests (push) Has been cancelled
341 lines
21 KiB
Markdown
341 lines
21 KiB
Markdown
# OpenSandbox Server configuration reference
|
||
|
||
This document describes **all TOML configuration options** accepted by the OpenSandbox lifecycle server (`opensandbox-server`). The schema is defined in [`opensandbox_server/config.py`](opensandbox_server/config.py) (`AppConfig` and nested models).
|
||
|
||
- **Default config path:** `~/.sandbox.toml`
|
||
- **Override path:** set environment variable `SANDBOX_CONFIG_PATH` to an absolute or user-expandable path.
|
||
- **CLI:** `opensandbox-server --config /path/to/sandbox.toml` also sets `SANDBOX_CONFIG_PATH` for that process.
|
||
|
||
Example files in this repository:
|
||
|
||
| File | Purpose |
|
||
|------|---------|
|
||
| [`example.config.toml`](opensandbox_server/examples/example.config.toml) | Docker runtime (English) |
|
||
| [`example.config.zh.toml`](opensandbox_server/examples/example.config.zh.toml) | Docker runtime (中文) |
|
||
| [`example.config.k8s.toml`](opensandbox_server/examples/example.config.k8s.toml) | Kubernetes runtime (English) |
|
||
| [`example.config.k8s.zh.toml`](opensandbox_server/examples/example.config.k8s.zh.toml) | Kubernetes runtime (中文) |
|
||
|
||
---
|
||
|
||
## Table of contents
|
||
|
||
1. [Top-level sections](#top-level-sections)
|
||
2. [`[server]`](#server--lifecycle-api)
|
||
3. [`[log]`](#log)
|
||
4. [`[runtime]`](#runtime--required)
|
||
5. [`[docker]`](#docker--only-when-runtime--docker)
|
||
6. [`[kubernetes]`](#kubernetes--only-when-runtime--kubernetes)
|
||
7. [`[agent_sandbox]`](#agent_sandbox--only-with-kubernetes--agent-sandbox)
|
||
8. [`[ingress]`](#ingress)
|
||
9. [`[egress]`](#egress)
|
||
10. [`[storage]`](#storage)
|
||
11. [`[store]`](#store)
|
||
12. [`[secure_runtime]`](#secure_runtime)
|
||
13. [`[renew_intent]`](#renew_intent--experimental)
|
||
14. [Environment variables (outside TOML)](#environment-variables-outside-toml)
|
||
15. [Cross-field validation rules](#cross-field-validation-rules)
|
||
|
||
---
|
||
|
||
## Top-level sections
|
||
|
||
| Section | Required | When |
|
||
|---------|----------|------|
|
||
| `[server]` | No | Always (defaults apply if omitted) |
|
||
| `[log]` | No | Always (defaults apply if omitted) |
|
||
| `[runtime]` | **Yes** | Always |
|
||
| `[docker]` | No | `runtime.type = "docker"` |
|
||
| `[kubernetes]` | No | `runtime.type = "kubernetes"` (defaults are applied if missing) |
|
||
| `[agent_sandbox]` | No | Only when `kubernetes.workload_provider = "agent-sandbox"` |
|
||
| `[ingress]` | No | Optional; see [Ingress](#ingress) |
|
||
| `[egress]` | No | Required values when clients use `networkPolicy` on create |
|
||
| `[storage]` | No | Host bind mounts / OSSFS mount root |
|
||
| `[store]` | No | Server-managed persistent metadata backend |
|
||
| `[secure_runtime]` | No | gVisor / Kata / Firecracker |
|
||
| `[renew_intent]` | No | Experimental auto-renew on access |
|
||
|
||
---
|
||
|
||
## `[server]` — Lifecycle API
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `host` | string | `"0.0.0.0"` | Bind address for the HTTP API. |
|
||
| `port` | integer | `8080` | Listen port (1–65535). |
|
||
| `api_key` | string \| omitted | `null` | If set to a non-empty string, requests must send header `OPEN-SANDBOX-API-KEY` with this value (except documented public routes such as `/health`, `/docs`, `/redoc`). If omitted or empty, API key checks are skipped, but startup now requires explicit risk acknowledgment: interactive TTY confirmation (`YES`) or `OPENSANDBOX_INSECURE_SERVER=YES`. |
|
||
| `eip` | string \| omitted | `null` | Public IP or hostname used as the **host part** when the server returns sandbox endpoint URLs (notably Docker runtime). |
|
||
| `max_sandbox_timeout_seconds` | integer \| omitted | `null` | Upper bound on sandbox TTL in seconds for **create** requests that specify `timeout`. Must be ≥ **60** if set. Omit to disable the server-side cap. |
|
||
| `timeout_keep_alive` | integer | `30` | Idle keep-alive timeout (seconds) passed to uvicorn. |
|
||
| `timeout_graceful_shutdown` | integer | `5` | Seconds uvicorn waits for in-flight requests to finish before forcing shutdown. Ensures Ctrl+C terminates promptly even when a long-running operation (e.g. image pull) is in progress. |
|
||
| `limit_concurrency` | integer | `1024` | Maximum concurrent connections before returning 503. Provides backpressure protection under burst load. Set to `0` to disable the cap (TOML cannot express `null`). |
|
||
| `backlog` | integer | `2048` | Socket listen backlog passed to uvicorn. |
|
||
| `thread_pool_size` | integer | `200` | Maximum size of the anyio default threadpool used by FastAPI to run sync route handlers. The anyio default of 40 throttles bursts of blocking sandbox list/get/delete operations under high concurrency. |
|
||
| `loop` | `"auto"` \| `"uvloop"` \| `"asyncio"` | `"auto"` | Event loop implementation. `auto` prefers uvloop and falls back to asyncio. |
|
||
| `http` | `"auto"` \| `"httptools"` \| `"h11"` | `"auto"` | HTTP protocol parser. `auto` prefers httptools and falls back to h11. |
|
||
|
||
---
|
||
|
||
## `[log]`
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `level` | string | `"INFO"` | Python logging level for the server process (e.g. `"DEBUG"`, `"INFO"`, `"WARNING"`). |
|
||
| `file_enabled` | boolean | `false` | When `true`, logs are written to rotating files instead of stdout. |
|
||
| `file_path` | string \| omitted | `null` | Override path for the main log file. Defaults to `~/logs/opensandbox/server.log` when `file_enabled = true`. |
|
||
| `access_file_path` | string \| omitted | `null` | Override path for the HTTP access log file. Defaults to `~/logs/opensandbox/access.log` when `file_enabled = true`. |
|
||
| `file_max_bytes` | integer | `104857600` (100 MB) | Max bytes per log file before rotation. |
|
||
| `file_backup_count` | integer | `5` | Number of rotated log files to retain. |
|
||
|
||
---
|
||
|
||
## `[runtime]` — **required**
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `type` | string | — | **`docker`** or **`kubernetes`**. Selects which runtime implementation loads. |
|
||
| `execd_image` | string | — | OCI image containing the **execd** binary used to bootstrap command/file access inside the sandbox. |
|
||
|
||
---
|
||
|
||
## `[docker]` — only when `runtime.type = "docker"`
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `network_mode` | string | `"host"` | Docker network attachment for sandbox containers: **`host`**, **`bridge`**, or a **custom user-defined network name**. Egress sidecar + `networkPolicy` require **`bridge`** (see [Egress](#egress)). |
|
||
| `api_timeout` | integer \| omitted | `null` | Docker API timeout in **seconds**. If unset, the code uses default **180** s where applicable. |
|
||
| `host_ip` | string \| omitted | `null` | Hostname or IP used when **rewriting** bridge-mode endpoint URLs (e.g. server runs in Docker and clients need a host-reachable address). Often `host.docker.internal` or the host LAN IP on Linux. |
|
||
| `drop_capabilities` | list of strings | See `config.py` | Linux capabilities **dropped** from sandbox containers (security hardening). |
|
||
| `apparmor_profile` | string \| omitted | `null` | Optional AppArmor profile name (e.g. `"docker-default"`). Empty/unset lets Docker use its default. |
|
||
| `no_new_privileges` | boolean | `true` | Sets `no-new-privileges` to block privilege escalation. |
|
||
| `seccomp_profile` | string \| omitted | `null` | Seccomp profile name or **absolute path**; empty uses Docker default seccomp. |
|
||
| `pids_limit` | integer \| null | `4096` | Max PIDs per sandbox container; set to **`null`** to disable the limit. |
|
||
| `port_range_min` | integer | `40000` | Lower bound of the host port range used by bridge-mode sandbox port allocation. Must be less than `port_range_max`. Each sandbox needs 2–3 host ports (2 without egress, 3 with egress sidecar). Narrow this range to match your firewall policy — e.g., 100 concurrent sandboxes ≈ 300 ports. |
|
||
| `port_range_max` | integer | `60000` | Upper bound of the host port range. Range must span ≥ 100 ports for reliable allocation. |
|
||
|
||
---
|
||
|
||
## `[kubernetes]` — only when `runtime.type = "kubernetes"`
|
||
|
||
If `runtime.type = "kubernetes"` and the `[kubernetes]` table is absent, the server instantiates defaults from `KubernetesRuntimeConfig`.
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `kubeconfig_path` | string \| omitted | `null` | Path to kubeconfig (expandable, e.g. `~/.kube/config`). In-cluster configs often leave this unset and rely on in-cluster credentials. |
|
||
| `namespace` | string \| omitted | `null` | Namespace for sandbox workloads. |
|
||
| `workload_provider` | string \| omitted | `null` | One of: **`batchsandbox`**, **`agent-sandbox`**. If omitted, the **first registered** provider is used (currently **`batchsandbox`**). |
|
||
| `batchsandbox_template_file` | string \| omitted | `null` | Path to **BatchSandbox** CR YAML template when `workload_provider = "batchsandbox"`. |
|
||
| `image_pull_policy` | string \| omitted | `"IfNotPresent"` | Image pull policy for the BatchSandbox main container. Values: **`Always`**, **`IfNotPresent`**, **`Never`**. |
|
||
| `sandbox_create_timeout_seconds` | integer | `60` | Max time to wait for a new sandbox to become ready (e.g. IP assigned), in seconds. |
|
||
| `sandbox_create_poll_interval_seconds` | float | `1.0` | Poll interval while waiting for readiness. |
|
||
| `snapshot_create_timeout_seconds` | integer | `900` | Max time to wait for a Kubernetes public snapshot to become ready, in seconds. Set this greater than the controller snapshot `commitJobTimeout` / `--commit-job-timeout`. |
|
||
| `informer_enabled` | boolean | `true` | **[Beta]** Use informer/watch cache for reads to reduce API load. |
|
||
| `informer_resync_seconds` | integer | `300` | **[Beta]** Full resync period for the informer cache. |
|
||
| `informer_watch_timeout_seconds` | integer | `60` | **[Beta]** Watch stream restart interval. |
|
||
| `read_qps` | float | `0` | K8s API **get/list** rate limit (QPS). **0** = unlimited. |
|
||
| `read_burst` | integer | `0` | Burst for read limiter; **0** means use `read_qps` as burst (minimum 1 internally). |
|
||
| `write_qps` | float | `0` | K8s API **write** rate limit (QPS). **0** = unlimited. |
|
||
| `write_burst` | integer | `0` | Burst for write limiter. |
|
||
| `execd_init_resources` | table \| omitted | `null` | Optional resource requests/limits for the **execd init** container. |
|
||
|
||
### BatchSandbox vs agent-sandbox
|
||
|
||
Kubernetes workloads are created by a **workload provider**. There is **no** `[batchsandbox]` section in TOML — BatchSandbox is configured entirely under **`[kubernetes]`**, plus shared sections like `[egress]`, `[ingress]`, `[storage]`, `[secure_runtime]`.
|
||
|
||
| | **BatchSandbox** (default provider) | **agent-sandbox** ([kubernetes-sigs/agent-sandbox](https://github.com/kubernetes-sigs/agent-sandbox)) |
|
||
|--|--------------------------------------|--------------------------------------------------------------------------------------------------------|
|
||
| `kubernetes.workload_provider` | `"batchsandbox"` or **omit** (factory default is `batchsandbox`) | `"agent-sandbox"` |
|
||
| Template file | **`kubernetes.batchsandbox_template_file`** — path to **BatchSandbox** CR YAML | **`agent_sandbox.template_file`** in [`[agent_sandbox]`](#agent_sandbox--only-with-kubernetes--agent-sandbox) |
|
||
| Image pull policy | **`kubernetes.image_pull_policy`** — writes `imagePullPolicy` into the BatchSandbox pod template main container | Not currently used |
|
||
| Extra TOML table | None | **`[agent_sandbox]`** is required (see below) |
|
||
|
||
**BatchSandbox-only config keys in `config.py`:** `batchsandbox_template_file` and `image_pull_policy` on `KubernetesRuntimeConfig`. Everything else in the `[kubernetes]` table (namespace, kubeconfig, informer, API QPS, `sandbox_create_*`, `execd_init_resources`, …) applies to **whichever** provider you select.
|
||
|
||
### `kubernetes.execd_init_resources`
|
||
|
||
| Key | Type | Description |
|
||
|-----|------|-------------|
|
||
| `limits` | map string → string | e.g. `{ cpu = "100m", memory = "128Mi" }` |
|
||
| `requests` | map string → string | e.g. `{ cpu = "50m", memory = "64Mi" }` |
|
||
|
||
---
|
||
|
||
## `[agent_sandbox]` — only with `kubernetes.workload_provider = "agent-sandbox"`
|
||
|
||
Used with the **kubernetes-sigs/agent-sandbox** Sandbox CRD provider.
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `template_file` | string \| omitted | `null` | Path to **Sandbox CR** YAML template. |
|
||
| `shutdown_policy` | string | `"Delete"` | **`Delete`** or **`Retain`** when the sandbox expires. |
|
||
| `ingress_enabled` | boolean | `true` | Whether ingress routing to agent-sandbox pods is expected. |
|
||
|
||
---
|
||
|
||
## `[ingress]`
|
||
|
||
Controls how **ingress exposure** is described for sandbox endpoints (especially behind gateways). **When `runtime.type = "docker"`, only `mode = "direct"` is allowed.**
|
||
`secureAccess` is currently supported only for **Kubernetes** sandboxes when **`ingress.mode = "gateway"`**.
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `mode` | string | `"direct"` | **`direct`** — clients reach sandboxes without an L7 gateway configured here. **`gateway`** — use `[ingress.gateway]` for address and routing mode (Kubernetes-oriented deployments). |
|
||
|
||
### When `mode = "gateway"`
|
||
|
||
You must set **`[ingress.gateway]`** and omit gateway when `mode = "direct"`.
|
||
|
||
| Key | Type | Description |
|
||
|-----|------|-------------|
|
||
| `address` | string | Gateway host (**no `http://` or `https://`**). For `route.mode = "wildcard"`, must be a **wildcard domain** (e.g. `*.example.com`). Otherwise a normal domain, IP, or `IP:port`. |
|
||
| `route.mode` | string | **`wildcard`** — host-based routing; **`uri`** — path-prefix routing; **`header`** — header-based routing. |
|
||
|
||
Response URL shapes depend on `route.mode` (see server README / ingress component docs).
|
||
|
||
---
|
||
|
||
## `[egress]`
|
||
|
||
Configures the **egress sidecar** image and enforcement mode. The server only attaches the sidecar when a sandbox is created **with** a `networkPolicy` in the API request.
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `image` | string \| omitted | `null` | OCI image for the egress sidecar. **Required in config** when clients send **`networkPolicy`** (create request). |
|
||
| `mode` | string | `"dns"` | Passed to the sidecar as `OPENSANDBOX_EGRESS_MODE`. Values: **`dns`** — DNS-proxy-based enforcement (CIDR/static IP rules **not** enforced); **`dns+nft`** — adds nftables where available so **CIDR/IP** rules can be enforced. |
|
||
| `disable_ipv6` | bool | `true` | IPv6 egress is incomplete (especially on Kubernetes). **Default on**; set `false` only when you want IPv6 left up in the netns. Details in [IPv6 and egress](#ipv6-and-egress) below. |
|
||
|
||
### IPv6 and egress
|
||
|
||
OpenSandbox egress does **not** treat IPv6 as a first-class, fully covered path—gaps show up most often under **`runtime.type = "kubernetes"`** (pod networking, CNI). The default **`disable_ipv6 = true`** matches the usual need on **dual-stack** CNI: do not rely on incomplete IPv6 egress. Set **`false`** when the cluster is effectively **IPv4-only** and you deliberately want IPv6 enabled in the sandbox network namespace, or when you accept those gaps for experiments.
|
||
|
||
**Docker notes:**
|
||
|
||
- `egress.image` must be set when using `networkPolicy`.
|
||
- Outbound policy requires **`docker.network_mode = "bridge"`**; `networkPolicy` is rejected for incompatible network modes.
|
||
|
||
**Kubernetes notes:**
|
||
|
||
- When `networkPolicy` is set, the workload includes an egress sidecar built from `egress.image`.
|
||
|
||
See [`components/egress/README.md`](../components/egress/README.md) for sidecar behavior and limits.
|
||
|
||
---
|
||
|
||
## `[storage]`
|
||
|
||
Host-side storage related to **volume mounts** (host bind allowlist and OSSFS mount layout).
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `allowed_host_paths` | list of strings | `[]` | Absolute path **prefixes** allowed for **host** bind mounts. If **empty**, all host bind mounts are rejected (secure-by-default). |
|
||
| `ossfs_mount_root` | string | `"/mnt/ossfs"` | Host directory under which OSSFS-backed mounts are resolved (`<root>/<bucket>/...`). |
|
||
| `volume_default_size` | string | `"1Gi"` | Default storage size for auto-created Kubernetes PVCs when the caller does not specify a size in the PVC provisioning hints. |
|
||
|
||
Sandbox **volume** models (`host`, `pvc`, `ossfs`) in API requests are documented in the OpenAPI specs and OSEPs; this table only covers **server** storage settings.
|
||
|
||
---
|
||
|
||
## `[store]`
|
||
|
||
Configures the persistence backend for **server-managed resources**. This is a
|
||
server-wide store, not a snapshot-specific backend. Snapshot metadata is the
|
||
first resource persisted here; future persistent server resources should reuse
|
||
the same backend.
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `type` | string | `"sqlite"` | Server persistence backend type. Currently only **`sqlite`** is supported. |
|
||
| `path` | string | `"~/.opensandbox/opensandbox.db"` | Filesystem path to the SQLite database file used for server-managed metadata. Parent directories are created automatically when needed. |
|
||
|
||
**Notes**
|
||
|
||
- The default SQLite backend gives local and single-node deployments persistent
|
||
metadata without requiring an external database service.
|
||
- `memory` is intentionally **not** the default because server-managed snapshot
|
||
resources must survive process restarts.
|
||
- Higher-level components should depend on repository abstractions rather than
|
||
importing `sqlite3` directly.
|
||
|
||
---
|
||
|
||
## `[secure_runtime]`
|
||
|
||
Optional **strong isolation** runtimes (gVisor, Kata, Firecracker).
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `type` | string | `""` | **`""`** — default OCI runtime (runc). **`gvisor`**, **`kata`**, **`firecracker`**. **`firecracker`** is **Kubernetes-only**. |
|
||
| `docker_runtime` | string \| omitted | `null` | Docker **OCI runtime name** (e.g. `runsc` for gVisor, `kata-runtime` for Kata). |
|
||
| `k8s_runtime_class` | string \| omitted | `null` | Kubernetes **RuntimeClass** name (e.g. `gvisor`, `kata-qemu`, `kata-fc`). |
|
||
|
||
**Validation (summary):**
|
||
|
||
- If `type` is empty, **`docker_runtime`** and **`k8s_runtime_class`** must be omitted.
|
||
- If `type` is **`firecracker`**, **`k8s_runtime_class`** is **required** (`docker` runtime cannot use Firecracker).
|
||
- If `type` is **`gvisor`** or **`kata`**, at least one of **`docker_runtime`** or **`k8s_runtime_class`** must be set.
|
||
|
||
See [`docs/guides/secure-container.md`](../docs/guides/secure-container.md) for installation and node requirements.
|
||
|
||
---
|
||
|
||
## `[renew_intent]` — **experimental**
|
||
|
||
**🧪 Experimental:** auto-renew sandbox expiration when access is observed (lifecycle proxy and/or Redis queue). Off by default. Full design: [OSEP-0009](../oseps/0009-auto-renew-sandbox-on-ingress-access.md).
|
||
|
||
Use **dotted keys** under the same table for Redis (valid in TOML):
|
||
|
||
| Key | Type | Default | Description |
|
||
|-----|------|---------|-------------|
|
||
| `enabled` | boolean | `false` | Master switch for renew-on-access. |
|
||
| `min_interval_seconds` | integer | `60` | Minimum seconds between renewals for the same sandbox (cooldown). ≥ 1. |
|
||
| `redis.enabled` | boolean | `false` | Enable Redis list consumer for ingress-gateway renew intents. |
|
||
| `redis.dsn` | string \| omitted | `null` | Redis URL, e.g. `redis://127.0.0.1:6379/0`. **Required** when `redis.enabled = true`. |
|
||
| `redis.queue_key` | string | `"opensandbox:renew:intent"` | Redis list key for renew-intent payloads. |
|
||
| `redis.consumer_concurrency` | integer | `8` | Concurrent BRPOP workers (≥ 1). |
|
||
|
||
Per-sandbox enablement uses create request extensions (see OSEP-0009 and `example.config.toml` comments).
|
||
|
||
---
|
||
|
||
## Environment variables (outside TOML)
|
||
|
||
These are read by the server or runtime code in addition to the TOML file:
|
||
|
||
| Variable | Where used | Description |
|
||
|----------|------------|-------------|
|
||
| `SANDBOX_CONFIG_PATH` | `config.py`, CLI | Path to the TOML file. Overrides the default `~/.sandbox.toml` when set. |
|
||
| `OPENSANDBOX_SERVER_API_KEY` | `config.py` | Overrides the API key from the TOML file. |
|
||
| `DOCKER_HOST` | Docker service | Standard Docker daemon address (e.g. `unix:///var/run/docker.sock`). |
|
||
|
||
---
|
||
|
||
## Cross-field validation rules
|
||
|
||
Rules enforced when the full `AppConfig` is parsed (see `AppConfig.validate_runtime_blocks` in `config.py`):
|
||
|
||
1. **`runtime.type = "docker"`**
|
||
- Must **not** include `[kubernetes]` or `[agent_sandbox]`.
|
||
- If `[ingress]` is present, **`ingress.mode` must be `"direct"`**.
|
||
- **`secure_runtime.type = "firecracker"`** is not allowed.
|
||
|
||
2. **`runtime.type = "kubernetes"`**
|
||
- `[kubernetes]` is created with defaults if missing.
|
||
- `[agent_sandbox]` is **only** allowed when **`kubernetes.workload_provider`** (case-insensitive) is **`agent-sandbox`**.
|
||
|
||
3. **`ingress.mode = "gateway"`**
|
||
- `[ingress.gateway]` is **required**; address and `route.mode` must satisfy the validators (wildcard domain for `wildcard` route mode, no URL scheme in `address`, etc.).
|
||
|
||
4. **`secure_runtime`**
|
||
- See [Secure runtime](#secure_runtime) above.
|
||
|
||
---
|
||
|
||
## Source of truth
|
||
|
||
If this document and the running server disagree, prefer:
|
||
|
||
1. **`opensandbox_server/config.py`** — authoritative Pydantic schema and defaults.
|
||
2. **Example TOML files** in the `server/` directory — reviewed snapshots for Docker/K8s.
|
||
3. **Release notes** — for experimental flags and breaking changes.
|
||
|
||
For API request fields (create sandbox, `networkPolicy`, volumes, etc.), see the OpenAPI specs under [`specs/`](../specs/) and the main [Server README](README.md).
|