Skip to main content
WASM tools run inside a WebAssembly sandbox powered by wasmtime. They have access to IronClaw’s host functions (logging, time, workspace), but all other capabilities — network, filesystem, credentials — must be explicitly declared in a capabilities.json file. This is IronClaw’s recommended approach for custom integrations that need stronger isolation than a built-in Rust tool provides.

How It Works

LLM selects tool

IronClaw loads WASM module (from cache or disk)

Tool executes inside wasmtime sandbox

Network requests route through the network proxy

Proxy validates domain against allowlist

Proxy injects credentials from encrypted store

Response returns to WASM module

Tool output passes through Safety Layer

LLM receives sanitized result

Sandbox Architecture

Fuel Metering

Every WASM instruction consumes “fuel.” When a module runs out of fuel, it is terminated immediately. This prevents infinite loops and runaway computation.
# Configure fuel limit (default: 100,000,000 instructions)
export WASM_FUEL_LIMIT=100000000

Memory Limits

WASM modules are allocated a fixed linear memory. Attempting to allocate beyond the limit traps and terminates the module.
# Configure memory limit (default: 16 MB)
export WASM_MEMORY_LIMIT=16777216

Rate Limiting

Each WASM tool has a per-tool rate limiter to prevent a misbehaving or compromised tool from making excessive API calls. Rate limits are declared in capabilities.json:
{
  "rate_limit": {
    "requests_per_minute": 60,
    "requests_per_day": 1000
  }
}

capabilities.json

Every WASM tool must include a capabilities.json alongside its .wasm binary. This file is the single source of truth for what the tool is allowed to do.
{
  "name": "my-tool",
  "version": "0.1.0",
  "description": "Fetches data from example.com API",

  "network": {
    "allowed_hosts": [
      "api.example.com",
      "auth.example.com"
    ]
  },

  "filesystem": {
    "read": ["/workspace/data/*"],
    "write": ["/workspace/output/*"]
  },

  "credentials": [
    {
      "name": "example_api_key",
      "inject_as": "Authorization",
      "format": "Bearer {value}"
    }
  ],

  "rate_limit": {
    "requests_per_minute": 30,
    "requests_per_day": 500
  }
}

Network allowlist

The network.allowed_hosts list controls which domains the tool can reach. Requests to any domain not in this list are rejected by the network proxy before the TCP connection is established. HTTPS traffic uses the CONNECT tunnel method. The proxy validates the target hostname against the allowlist before establishing the tunnel.

Filesystem access

WASM tools cannot access the host filesystem by default. Paths declared under filesystem.read and filesystem.write are mounted into the WASM module’s sandbox at the declared paths.

Credential injection

Credentials listed in capabilities.json are never passed into the WASM module’s memory. Instead, when the module makes an outbound HTTP request, the proxy intercepts the request and injects the specified header before forwarding it. The WASM module never sees the raw credential value — it only makes an unauthenticated HTTP request, and the proxy adds the auth header transparently.

Host Functions

WASM modules can call the following host functions provided by IronClaw:
FunctionDescription
log(level, message)Write to the IronClaw log at the given severity level
now_unix_secs()Return the current Unix timestamp
workspace_read(path)Read a document from the workspace
workspace_write(path, content)Write a document to the workspace
These are the only host capabilities available. A WASM tool cannot call arbitrary OS functions, fork processes, or access the network directly — all network access goes through the proxy.

Tool Discovery

WASM tools are discovered at startup from two locations:
  • ~/.ironclaw/tools/ — User-installed tools
  • <workspace>/tools/ — Per-workspace tools
Each tool directory must contain:
  • <toolname>.wasm — The compiled WebAssembly module
  • capabilities.json — The capability declaration

Installing WASM Tools

# Install from a local file
ironclaw tool install ./my-tool.wasm

# Install from a URL
ironclaw tool install https://example.com/tools/my-tool.wasm

# List installed tools
ironclaw tool list
Or via the extension_install tool in chat:
“Install the tool from https://example.com/tools/my-tool.wasm

Module Compilation and Caching

WASM modules are compiled by wasmtime on first load and cached. Subsequent loads use the compiled artifact, so only the first invocation of a new tool incurs compilation overhead. The cache is stored at ~/.ironclaw/wasm-cache/.

Security Notes

Review capabilities.json before installing any WASM tool from an untrusted source. The capability file determines exactly what the tool can access — network hosts, filesystem paths, and which credentials are injected.
The proxy injects credentials into outgoing requests. There is no mechanism for a WASM module to read stored secrets directly. Even if a WASM module is compromised, it cannot access the secrets store.
WASM modules cannot spawn child processes, execute shell commands, or load dynamic libraries. The WASI interface exposed to modules is minimal.
A buggy or malicious WASM tool that enters an infinite loop will be terminated when it exhausts its fuel allocation. This prevents a single tool from blocking the agent indefinitely.