Skip to content

Custom Filters (WASM Rules Engine) Open-Core

This page documents how the WebAssembly (WASM) Rules Engine is structured, compiled, synchronized, and executed on the request interception hot-path.


1. Overview & Sandboxing

The WASM Rules Engine enables developers to write custom, high-performance policy rules in AssemblyScript (a TypeScript subset), compile them to WebAssembly, and run them inside a sandboxed wasmtime environment inside the Intutic Proxy.

To guarantee that custom user code cannot degrade proxy performance or compromise host security, each rule is strictly constrained:

  • Memory Cap: Limited to 1MB of linear memory.
  • CPU Fuel Limit: Bound to 1,000,000 fuel units to prevent infinite loops.
  • Execution Timeout: 5ms budget per request. If a rule exceeds 5ms, it is immediately terminated and fails open to maintain low latency.

2. Rule Lifecycle

The workflow from code creation to hot-path enforcement is as follows:

[Developer: AS Code] ──(asc)──► [WASM Binary] ──(Dashboard Upload)──┐

                                                             [PostgreSQL]

                                                           (Valkey Pub/Sub)


                                                             [Rust Proxy]
                                                      (wasmtime module compile)
  1. Compilation: Rules are compiled to WebAssembly binaries (.wasm) using the AssemblyScript compiler (asc).
  2. Registry Storage: Rules are uploaded via the dashboard (POST /api/v1/wasm-rules) and stored in the wasm_rule_bundles database table.
  3. Hot-Reload Sync:
    • The Rust proxy maintains an in-memory WasmRegistry thread that periodically checks for updates in the Valkey cache.
    • Additionally, when a rule is added or updated, the control plane publishes a Valkey Pub/Sub event.
    • The Rust proxy immediately subscribes, retrieves the modified rule, and instantiates a new wasmtime::Module on the fly without requiring a service restart.

3. Host-Guest Interception Interface

When an LLM or tool request is intercepted, the Rust proxy executes the rule using a guest-host contract:

A. Context Serialization

The Rust host normalizes the intercepted request context (tool calls, arguments, tokens, user role, etc.) and serializes it into a JSON string format:

json
{
  "workspaceId": "wk_abc",
  "model": "claude-3-5-haiku",
  "toolName": "bash",
  "toolArgs": { "command": "rm -rf /" },
  "userRole": "developer",
  "tokenCount": 1200
}

B. Memory Allocation & Injection

Because WASM sandboxes have isolated linear memory, the host must inject the context:

  1. The host calls the exported WASM function __allocate(len) to allocate buffer memory within the guest instance.
  2. The host writes the serialized JSON string directly to that allocated offset in the guest's memory.

C. Execution

The host calls the guest's main evaluation entrypoint:

typescript
export function evaluate(requestContextJson: ArrayBuffer): i32

D. Host Logging

Guest rules can write log entries back to the host console using the imported host function log_info(msg_ptr, len). These logs are piped directly into the Rust proxy's structured tracing::info! output.


4. Gating Verdicts

The guest function returns an integer verdict that dictates how the proxy gates the request:

ValueVerdictAction Taken
0ALLOWThe request is marked clean and continues down the pipeline.
1BLOCKThe request is rejected immediately. The proxy short-circuits the connection and returns a block response: { "error": "Blocked by WASM rule policy" }.
2REDACTThe proxy filters/strips out matching sensitive parameters or credentials before forwarding the payload to the provider.

Note: If multiple rules are active, the runner evaluates all instances sequentially and returns the most restrictive verdict.

The active firewall for AI agents