WebAssembly (WASM) Extensibility for sgl-model-gateway
This module provides WebAssembly-based extensibility for sgl-model-gateway, enabling dynamic, safe, and portable middleware execution without requiring router restarts or recompilation.
Overview
The WASM module allows you to extend sgl-model-gateway functionality by deploying WebAssembly components that can:
- Intercept requests/responses at various lifecycle points (OnRequest, OnResponse)
- Modify HTTP headers and bodies before/after processing
- Reject requests with custom status codes
- Execute custom logic in a sandboxed, isolated environment
Architecture
Components
The WASM module consists of several key components:
src/wasm/
├── module.rs # Data structures (metadata, types, attach points)
├── module_manager.rs # Module lifecycle management (add/remove/list)
├── runtime.rs # WASM execution engine and thread pool
├── route.rs # HTTP API endpoints for module management
├── spec.rs # WASM interface types bindings and type conversions
├── types.rs # Generic input/output types
├── errors.rs # Error definitions
├── config.rs # Runtime configuration
└── interface/ # WebAssembly Interface Types definitions
Execution Flow
1. HTTP Request arrives at router
↓
2. Middleware chain checks for WASM modules attached to OnRequest
↓
3. For each module:
a. Module manager retrieves pre-loaded WASM bytes
b. Runtime executes component in isolated worker thread
c. Component processes request via WASM type interface
d. Returns Action (Continue/Reject/Modify)
↓
4. If Continue: proceed to next middleware/upstream
If Reject: return error response immediately
If Modify: apply changes (headers, body, status)
↓
5. After upstream response:
- Modules attached to OnResponse process response
- Apply modifications
↓
6. Return final response to client
WebAssembly Interface Types
The module uses the WebAssembly Component Model with WASM interface type for type-safe communication between host and WASM components:
- Request Processing:
middleware-on-request::on-request(req: Request) -> Action - Response Processing:
middleware-on-response::on-response(resp: Response) -> Action - Actions:
Continue,Reject(status), orModify(modify-action)
See interface/ for the complete interface definition.
Usage
Prerequisites
- sgl-model-gateway compiled with WASM support
- Rust toolchain (for building WASM components)
wasm32-wasip2target:rustup target add wasm32-wasip2wasm-tools:cargo install wasm-tools
Starting the Router
Enable WASM support when starting the router:
./sgl-model-gateway --enable-wasm --worker-urls=http://0.0.0.0:30000 --port=3000
Deploying a WASM Module
Use the /wasm POST endpoint to deploy modules:
curl -X POST http://localhost:3000/wasm \
-H "Content-Type: application/json" \
-d '{
"modules": [{
"name": "my-middleware",
"file_path": "/path/to/my-component.component.wasm",
"module_type": "Middleware",
"attach_points": [{"Middleware": "OnRequest"}]
}]
}'
Managing Modules
List all modules:
curl http://localhost:3000/wasm
Remove a module:
curl -X DELETE http://localhost:3000/wasm/{module-uuid}
Module Configuration
Each module requires:
- name: Unique identifier for the module
- file_path: Absolute path to the WASM component file
- module_type: Currently supports
"Middleware" - attach_points: List of attachment points, e.g.,
[{"Middleware": "OnRequest"}]
Supported attachment points:
{"Middleware": "OnRequest"}- Execute before forwarding to upstream{"Middleware": "OnResponse"}- Execute after receiving upstream response{"Middleware": "OnError"}- Not yet implemented
Examples
See examples/wasm/ for complete examples:
- wasm-guest-auth - API key authentication middleware
- wasm-guest-logging - Request tracking and status code conversion
- wasm-guest-ratelimit - Rate limiting middleware
Each example includes:
- Complete source code
- Build instructions
- Deployment examples
- Testing guidelines
Security and Resource Management
Sandboxing
WASM modules run in isolated environments provided by wasmtime, preventing:
- Direct system access
- Memory corruption of the host process
- Unauthorized network access
- File system access (unless explicitly granted via WASI)
Resource Limits
Runtime configuration allows setting limits:
WasmRuntimeConfig {
max_memory_pages: 1024, // 64MB limit
max_execution_time_ms: 1000, // 1 second timeout
max_stack_size: 1024 * 1024, // 1MB stack
thread_pool_size: 4, // Worker threads
module_cache_size: 10, // Cached modules per worker
}
Error Handling
- Failed module executions are logged and don't crash the router
- Invalid WASM components are rejected during load time
- Metrics track execution success/failure rates
Metrics
The module exposes execution metrics via the /wasm GET endpoint:
{
"modules": [...],
"metrics": {
"total_executions": 1000,
"successful_executions": 995,
"failed_executions": 5,
"total_execution_time_ms": 50000,
"max_execution_time_ms": 150,
"average_execution_time_ms": 50.0
}
}
Development
Building WASM Components
WASM components must be built using the Component Model. For Rust:
# 1. Build as WASM module
cargo build --target wasm32-wasip2 --release
# 2. Wrap into component format
wasm-tools component new target/wasm32-wasip2/release/my_module.wasm \
-o my_module.component.wasm
WASM Interface Type
Define your component using the WASM interface from interface/spec.*:
wit_bindgen::generate!({
path: "../../../src/wasm/interface",
world: "sgl-model-gateway",
});
use exports::sgl::model_gateway::middleware_on_request::Guest as OnRequestGuest;
use sgl::model_gateway::middleware_types::{Request, Action};
struct Middleware;
impl OnRequestGuest for Middleware {
fn on_request(req: Request) -> Action {
// Your logic here
Action::Continue
}
}
export!(Middleware);