You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+25-2Lines changed: 25 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,7 +49,7 @@ This project enables running Linux applications (Python, Node.js, Go, Rust, C/C+
49
49
50
50
### Key Features
51
51
52
-
-**Thin, opt-in host surface** — by default, the guest has no access to the host filesystem, network, or any host functions. When you enable features like `--mount`, `--net`, or `--enable-tools`, a single `__dispatch` JSON-RPC bridge is registered as the only guest→host channel. See [HOST_FUNCTIONS.md](HOST_FUNCTIONS.md) for the full list of dispatchable operations
52
+
-**Thin, opt-in host surface** — by default, the guest has no access to the host filesystem, network, or any host functions. When you enable features like `--mount`, `--net`, `--enable-tools`, or `--tool`, a single `__dispatch` JSON-RPC bridge is registered as the only guest→host channel. See [host_functions.md](docs/host_functions.md) for the full list of dispatchable operations
The guest still calls the existing `__dispatch` envelope, for example `{"name":"greet","args":{"who":"Ada"}}`. The Wasm handler runs on the host in Wasmtime, receives that request JSON on stdin, and writes either a raw JSON result or `{"result": ...}` / `{"error": "..."}` to stdout. WASI filesystem and environment access are off unless granted with `--tool-wasi-dir`, `--tool-wasi-dir-ro`, `--tool-wasi-env`, or `--tool-wasi-env-inherit`.
| Custom tools |**Off**|`--enable-tools`, `--tool NAME=WASM` with `wasm-host-fns`, or`SandboxBuilder::tool()`|
19
19
20
20
With **no flags**, the guest cannot reach the host filesystem or network through dispatch. Only internal plumbing (`__hl_exit`, `__hl_sleep`) is wired.
|`--net-block HOST_OR_IP`| Block-list; all other destinations allowed (implies `--net`). Mutually exclusive with `--net-allow`. |
87
87
|`--port PORT`| Allow `net_bind` / listen on `PORT` (implies `--net`). Without `--port`, outbound-only: bind is rejected. |
88
-
|`--enable-tools`| Enables custom tool registration. Registers a built-in `echo` tool (used by the `python-tools` example). Library users add their own tools via `SandboxBuilder::tool()`. |
88
+
|`--enable-tools`| Registers a built-in `echo` tool (used by the `python-tools` example). Library users add their own tools via `SandboxBuilder::tool()`. |
89
+
|`--tool NAME=WASM`| With the Cargo feature `wasm-host-fns`, registers `WASM` as a WASIp1 custom tool named `NAME`. Repeatable. |
90
+
|`--tool-wasi-dir HOST[:GUEST]`| Preopens a read-write host directory for all Wasm tools. Default guest path is `/host`. Repeatable. |
91
+
|`--tool-wasi-dir-ro HOST[:GUEST]`| Preopens a read-only host directory for all Wasm tools. Default guest path is `/host`. Repeatable. |
92
+
|`--tool-wasi-env KEY=VALUE`| Sets an environment variable for all Wasm tools. Repeatable. |
93
+
|`--tool-wasi-env-inherit KEY`| Copies one host environment variable into all Wasm tools. Repeatable. |
94
+
|`--tool-wasi-fuel FUEL`| Sets the instruction-fuel budget for each Wasm tool call. Default `100000000`. |
95
+
|`--tool-wasi-output-limit SIZE`| Caps captured stdout and stderr per Wasm tool call. Default `1Mi`. |
89
96
90
97
**Mount rules (host-enforced before boot):**
91
98
@@ -189,7 +196,34 @@ Sockets are host-side (`socket2`); the guest sees opaque numeric **`fd`** handle
189
196
190
197
## Custom tools
191
198
192
-
**CLI:**`--enable-tools` registers a built-in `echo` tool (returns `args` unchanged) used by the [`python-tools` example](../examples/python-tools). The primary purpose of `--enable-tools` is to demonstrate custom host function registration via the API.
199
+
**CLI built-in:**`--enable-tools` registers a built-in `echo` tool (returns `args` unchanged) used by the [`python-tools` example](../examples/python-tools).
200
+
201
+
**CLI Wasm tools:** build with the optional feature and pass one or more `--tool` flags:
Each `--tool NAME=WASM` module is compiled and linked before VM boot, then invoked as a fresh WASIp1 command for every matching guest `__dispatch` call. The handler receives the existing dispatch request on stdin:
209
+
210
+
```json
211
+
{"name":"NAME","args":<json_value>}
212
+
```
213
+
214
+
The handler writes JSON to stdout. It may write either a raw JSON result value or the normal dispatch envelope:
215
+
216
+
```json
217
+
{"result":<json_value>}
218
+
```
219
+
220
+
```json
221
+
{"error":"message"}
222
+
```
223
+
224
+
A raw value is treated as the tool result. A single-key `result` envelope is unwrapped. A single-key `error` envelope becomes the outer `__dispatch` error response. Empty stdout returns JSON null.
225
+
226
+
WASI capabilities are denied by default except stdio used for the protocol, clocks, and random. Use `--tool-wasi-dir`, `--tool-wasi-dir-ro`, `--tool-wasi-env`, and `--tool-wasi-env-inherit` to grant explicit filesystem and environment access to handlers. Tool names beginning with `__`, `fs_`, or `net_` are reserved.
193
227
194
228
**Library:**
195
229
@@ -214,6 +248,8 @@ Custom handlers run with the same JSON request/response envelope as built-in too
214
248
|`fs_list` entries | 100 000 |
215
249
|`net_send` / `net_sendto`| 1 MiB decoded bytes |
216
250
|`__hl_sleep`| 60 s |
251
+
| Wasm tool fuel | 100 000 000 instructions per call by default; configurable with `--tool-wasi-fuel`|
252
+
| Wasm tool stdout / stderr | 1 MiB each per call by default; configurable with `--tool-wasi-output-limit`|
217
253
| Open host sockets | 1024 per sandbox |
218
254
| AllowList learned DNS IPs | 256 |
219
255
@@ -242,6 +278,13 @@ Custom handlers run with the same JSON request/response envelope as built-in too
242
278
- A compromised guest can invoke any **registered** tool name; do not register powerful custom tools unless needed.
243
279
- Payload size is capped; malformed JSON fails closed with an error response.
244
280
281
+
**When `--tool` is used with `wasm-host-fns`:**
282
+
283
+
- Handler code runs on the host inside Wasmtime, not inside the Unikraft VM.
284
+
- WASI filesystem and environment access are capability-based and off unless explicitly granted with `--tool-wasi-*` flags.
285
+
- Fuel limits bound Wasm instruction execution, but do not turn filesystem operations into a full wall-clock timeout.
286
+
- Handlers are untrusted code from the host operator's filesystem; only load modules you intend to grant these capabilities to.
287
+
245
288
**Not exposed via dispatch:** Host shell, arbitrary process spawn, unrestricted host `exec`, or kernel modules — only the tools listed above.
246
289
247
290
**Operators should:** Use minimal flags, allow-lists over `--net` where possible, mount least-privilege directories, and run guests with the smallest initrd/runtime required.
0 commit comments