Locara

Wasmtime + WASI

What it is: Wasmtime is a fast, secure, standards-compliant WebAssembly runtime by the Bytecode Alliance. WASI (WebAssembly System Interface) is the standardized capability-based API that lets sandboxed wasm modules interact with the host (filesystem, network, clocks, env) in a controlled way. Status: Mature, production-ready. Used by Fastly Compute@Edge, Shopify Functions, Fermyon, many others. Most relevant to Locara: The default sandbox for Locara’s tool execution capability. When a Locara app needs to run code (LLM-generated scripts, user logic, etc.), wasm via Wasmtime is the safe default.

Background

Wasmtime was created (2019) as a standalone reference runtime for WebAssembly outside the browser. It uses Cranelift (an optimizing JIT) for performance and has invested heavily in the security model — every wasm module starts with zero capabilities; the host explicitly grants what it needs.

WASI standardizes the host-import surface so wasm modules can be portable across runtimes. WASI 0.2 (preview 2, 2024) introduced the Component Model — a cleaner ABI for cross-language wasm components.

Key design decisions

  • Capability-based security. A wasm module starts with no syscalls available. The host (Wasmtime embedder) provides specific WASI imports, e.g., a Dir handle pointing at a specific directory.
  • No ambient authority. A wasm module cannot “open /etc/passwd” — there’s no concept of a global filesystem. It can only use handles given to it.
  • Cranelift JIT. Compiles wasm to native code on load; performance close to native for many workloads.
  • AOT compilation also supported — pre-compile wasm to native, ship that, no JIT cost at runtime.
  • Embeddable in Rust, C, Python, Go, .NET — wide language support.
  • Component Model lets wasm modules be composed; each component exports/imports a typed interface.
  • Resource limits — memory cap, fuel (instruction count), per-table limits all configurable.
  • Standards body governance (Bytecode Alliance) gives confidence that it’s not going away.
  • Apache 2.0.

What worked

  • Capability-based, no-ambient-authority is a great model. This is the cleanest implementation of “a sandbox is what the host says it is.”
  • Performance competitive with native for compute-heavy workloads. Cranelift is good.
  • Cross-language story. A wasm module compiled from Rust/C/Go/etc. all run via the same Wasmtime, so you can sandbox code from any language.
  • Production deployments at scale (Fastly, Shopify) prove the security and performance model works.
  • Lightweight startup — tens of microseconds for cold start vs. hundreds of ms for containers. Genuinely game-changing for short-lived sandboxes.
  • Standards-track APIs (WASI) mean modules are portable.

What failed / criticisms

  • Ecosystem maturity below browser wasm. Tooling (debugger, profiler) less developed.
  • WASI fragmentation across versions — preview 1 → preview 2 / Component Model has been a long migration. Modules compiled for one don’t always run on another.
  • No pip install pandas-like package model for sandboxed Python. Wasm-Python (Pyodide-like) exists but the experience is rough — most Python packages with native deps don’t work.
  • Filesystem performance over WASI is slower than native syscalls for I/O-heavy workloads.
  • Component Model adoption still patchy as of 2026; many tools target the older “core wasm + WASI preview 1” combo.
  • Memory limit per module is 4GB — fine for most workloads, hits the wall for large numerical computations.

Specific learnings for Locara

  1. Wasmtime is the right default sandbox for Locara’s tool.exec capability. Apps that need to execute code (e.g., LLM-generated Python, custom data transformations, user-defined tools) get a wasm module that can only see what the Locara runtime grants it.
  2. Capability-grant model maps cleanly to Locara manifest:
    tool.exec:
      runtime: wasm
      capabilities:
        - fs.read: $APP_DATA  # only the app's own data dir
        - net: false           # no network from inside the sandbox
        - env: {}              # no env vars
    
    The Locara runtime translates this into Wasmtime API calls when starting the module.
  3. WASI provides the portable surface — Locara’s tool-exec API can target WASI, so apps aren’t tied to Wasmtime specifically (could swap in Wasmer or other runtime later).
  4. Component Model for tool typing. Locara’s “tools” (runnable functions an LLM can call) can be modeled as wasm Components with typed interfaces. The LLM agent calls tool.invoke(name, args) → routed to the right component → runs in sandbox → returns. Clean abstraction.
  5. Don’t try to support arbitrary Python in wasm. Pyodide-style Python-in-wasm is too rough for Locara v1. Sandbox expectations: stateless data transforms, computations, format conversions. For Python with native deps, opt-in subprocess capability with explicit capability flag.
  6. Fuel-based execution limits. Wasmtime supports “run for N instructions then trap.” Use this to prevent infinite loops in LLM-generated code from hanging an app.
  7. AOT compilation for repeated use. When an app’s tool is invoked frequently, AOT-compile it once on install, reuse. Latency benefit.
  8. The “no ambient authority” mental model is the right one for Locara overall. Apply it not just to wasm tools, but to the whole framework: nothing is implicit, everything is granted explicitly via the manifest.

References