How WASI Standardizes WebAssembly OS Interactions
WebAssembly (Wasm) was originally designed to run securely inside web browsers, isolated from the host operating system. To run WebAssembly outside the browser—on servers, edge devices, and desktops—it requires a safe way to interact with system resources like files, folders, and networks. This article explains how the WebAssembly System Interface (WASI) standardizes these operating system interactions, enabling highly portable and secure non-browser Wasm applications.
The Challenge of Non-Browser WebAssembly
Traditionally, software applications interact with the host operating system using system calls (syscalls). Because different operating systems (such as Windows, Linux, and macOS) have different system calls, developers must compile their code specifically for each target platform.
WebAssembly aims for write-once, run-anywhere portability. If a Wasm binary relied directly on Linux-specific syscalls, it would fail to run on Windows. To maintain portability, WebAssembly needed a standardized, platform-independent system interface. WASI fills this gap by acting as a universal abstraction layer between Wasm applications and the host operating system.
How WASI Standardizes OS Access
WASI provides a standardized set of APIs that Wasm programs use to request operating system services. Instead of targeting a specific OS, developers compile their source code (written in languages like Rust, C++, or Go) to target WASI.
1. Abstracting System Calls
When a program is compiled to the WASI target, its system calls are
mapped to WASI’s standardized functions. For example, instead of using a
Linux-specific open or Windows-specific
CreateFile API, the Wasm binary calls the WASI standard
function path_open.
2. The Role of the WebAssembly Runtime
To run a WASI-compliant Wasm binary, you need a WebAssembly runtime (such as Wasmtime, Wasmer, or WasmEdge) installed on the host machine.
The runtime acts as the translator. When the Wasm application calls a
WASI function like path_open, the runtime intercepts this
call and translates it into the appropriate native system call for the
host operating system. Because the runtime handles the platform-specific
translation, the same Wasm binary can run unmodified on any operating
system where a compatible runtime exists.
Capability-Based Security
Standard operating systems rely on user-based security. If a user runs a program, that program inherits all of the user’s permissions, meaning a malicious program could theoretically access or delete any file the user owns.
WASI implements a strict capability-based security model. By default, a Wasm application running via WASI has no access to the outside world—no file system access, no network access, and no environment variables.
To grant access, the host runtime must explicitly pass “capabilities” to the Wasm module when launching it. For example, if a program needs to write to a specific folder, the runtime must pre-open that folder and pass the file descriptor to the program. The Wasm program cannot traverse up the directory tree or access any files outside of that explicitly granted folder, ensuring complete sandboxing.
WASI Evolution: From Preview 1 to WASI 0.2 (Preview 2)
WASI has evolved from its initial prototype to a production-ready standard built on the WebAssembly Component Model:
- WASI Preview 1: The original version, heavily modeled after POSIX standards. While effective, it was monolithic and lacked modularity.
- WASI 0.2 (Preview 2): Built on the WebAssembly
Component Model, this version introduces modular “worlds” and
“interfaces” written in WebAssembly Interface Type (WIT) files. It
categorizes system access into distinct APIs, such as
wasi-cli(for command-line tools),wasi-http(for sending and receiving HTTP requests), andwasi-filesystem(for file system access).
By decoupling the APIs into distinct modules, WASI allows runtimes to implement only the features they need. For example, an IoT sensor runtime might implement basic input/output APIs but omit HTTP support to save memory.