3 stable releases
| 1.1.0 | Mar 10, 2026 |
|---|---|
| 1.0.1 | Feb 23, 2026 |
| 1.0.0 | Jan 21, 2026 |
#148 in WebAssembly
125,722 downloads per month
Used in smg
190KB
4K
SLoC
WebAssembly (WASM) Extensibility for Shepherd Model Gateway
This module provides WebAssembly-based extensibility for Shepherd Model Gateway (SMG), enabling dynamic, safe, and portable middleware execution without requiring router restarts or recompilation.
Overview
The WASM module allows you to extend SMG 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
- SMG 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:
./smg --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
- wasm-guest-storage-hook - Multi-tenant storage hook with audit trail extra columns
- wasm-guest-storage-hook-passthrough - Minimal passthrough storage hook for testing
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: "../../../wasm/src/interface",
world: "smg",
});
use exports::smg::gateway::middleware_on_request::Guest as OnRequestGuest;
use smg::gateway::middleware_types::{Request, Action};
struct Middleware;
impl OnRequestGuest for Middleware {
fn on_request(req: Request) -> Action {
// Your logic here
Action::Continue
}
}
export!(Middleware);
Dependencies
~45–66MB
~1M SLoC