Kronos
Paper, 2026 · Rust
A multi-tenant WebAssembly runtime in Rust that refuses a module before it runs if the module imports file or network access its tenant was not granted.
Summary
Kronos runs untrusted WebAssembly modules for many tenants inside one process, on top of Wasmtime. A module can reach the host only through the functions it imports, so Kronos checks that import list against the tenant's capabilities before instantiating the module. If the module imports a file or network function the tenant was not granted, it is refused and none of its code runs. Every invocation also gets a fuel budget and a wall-clock deadline.
The paper describes the architecture: the runtime, the capability model, resource control, parallel execution, and the control plane. It also reports measurements and analyzes which properties the code enforced.
Design
- Import check before instantiation. File and network
functions require
AllowFilesystemorAllowNetworking, and WASI functions require the filesystem capability. The check runs before a store is created. - Metering. Wasmtime fuel bounds the instructions a guest executes, and an epoch counter advanced every millisecond enforces a wall-clock deadline.
- Threaded guests. Guests compiled with
-pthreadrun through a customwasi:thread-spawnhandler that puts workers on a shared Rayon pool and reports a worker trap as an error instead of exiting the host process.
What the analysis found
The check was enforced on the server's request path. A fast instantiation path in the library skipped it, the threaded path granted filesystem access unconditionally, and the thread handler stopped workers by advancing an epoch counter that every tenant shares, which could expire other tenants' deadlines. The paper covers each case and what would fix it.
Measurements
| Runtime | Memory per added isolate | Peak burst throughput |
|---|---|---|
| Kronos | 0.15 MiB | 14K req/s |
| Wasmtime (Go embedding) | 0.21 to 0.23 MiB | 103K to 164K req/s |
| wazero | 2.2 MiB | 157K to 171K req/s |
Two runs on one Apple Silicon Mac, with a small module and few trials. Kronos used less memory per added isolate than both Go-hosted runtimes and had 7 to 12 times lower burst throughput. A four-thread matrix multiply beat a build that called the host for every element, but a plain single-threaded module beat both, so the runs show no parallel speedup.
Status
This runtime is the research ancestor of the Kronos cloud, which uses a different authority model built on WASI preopened directories. The code is in a private repository and is available on request; the paper names the exact commits it describes.
Thanks to Ajax Li for the benchmark harnesses and evaluation runs, and to the architecture group at Penn for early feedback.