mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-29 17:09:31 +00:00
Add WASM sandbox secure API extension
Extends the WASM sandbox with HTTP API capabilities, secrets management, tool aliasing, and leak detection. Key security principle: WASM never sees credentials, injection happens at host boundary. New modules: - secrets: AES-256-GCM encrypted storage with HKDF key derivation - leak_detector: Aho-Corasick + regex pattern matching for secret exfiltration - capabilities: Extended capability system (HTTP, ToolInvoke, Secrets) - allowlist: HTTP endpoint validation with glob patterns - credential_injector: Host-boundary credential injection - rate_limiter: Sliding window per-tool rate limiting - storage: WASM binary storage with BLAKE3 integrity verification Leak detection happens at two points: 1. Before HTTP request (prevents exfiltration via URL/headers/body) 2. After response (prevents exposure in outputs returned to WASM) Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
45bbfa026d
commit
32bfd24154
+73
-1
@@ -9,7 +9,8 @@ use crate::llm::ToolDefinition;
|
||||
use crate::tools::builtin::{EchoTool, HttpTool, JsonTool, TimeTool};
|
||||
use crate::tools::tool::Tool;
|
||||
use crate::tools::wasm::{
|
||||
Capabilities, ResourceLimits, WasmError, WasmToolRuntime, WasmToolWrapper,
|
||||
Capabilities, ResourceLimits, WasmError, WasmStorageError, WasmToolRuntime, WasmToolStore,
|
||||
WasmToolWrapper,
|
||||
};
|
||||
|
||||
/// Registry of available tools.
|
||||
@@ -152,6 +153,77 @@ impl ToolRegistry {
|
||||
tracing::info!(name = reg.name, "Registered WASM tool");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Register a WASM tool from database storage.
|
||||
///
|
||||
/// Loads the WASM binary with integrity verification and configures capabilities.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```ignore
|
||||
/// let store = PostgresWasmToolStore::new(pool);
|
||||
/// let runtime = Arc::new(WasmToolRuntime::new(WasmRuntimeConfig::default())?);
|
||||
///
|
||||
/// registry.register_wasm_from_storage(
|
||||
/// &store,
|
||||
/// &runtime,
|
||||
/// "user_123",
|
||||
/// "my_tool",
|
||||
/// ).await?;
|
||||
/// ```
|
||||
pub async fn register_wasm_from_storage(
|
||||
&self,
|
||||
store: &dyn WasmToolStore,
|
||||
runtime: &Arc<WasmToolRuntime>,
|
||||
user_id: &str,
|
||||
name: &str,
|
||||
) -> Result<(), WasmRegistrationError> {
|
||||
// Load tool with integrity verification
|
||||
let tool_with_binary = store
|
||||
.get_with_binary(user_id, name)
|
||||
.await
|
||||
.map_err(WasmRegistrationError::Storage)?;
|
||||
|
||||
// Load capabilities
|
||||
let stored_caps = store
|
||||
.get_capabilities(tool_with_binary.tool.id)
|
||||
.await
|
||||
.map_err(WasmRegistrationError::Storage)?;
|
||||
|
||||
let capabilities = stored_caps.map(|c| c.to_capabilities()).unwrap_or_default();
|
||||
|
||||
// Register the tool
|
||||
self.register_wasm(WasmToolRegistration {
|
||||
name: &tool_with_binary.tool.name,
|
||||
wasm_bytes: &tool_with_binary.wasm_binary,
|
||||
runtime,
|
||||
capabilities,
|
||||
limits: None,
|
||||
description: Some(&tool_with_binary.tool.description),
|
||||
schema: Some(tool_with_binary.tool.parameters_schema.clone()),
|
||||
})
|
||||
.await
|
||||
.map_err(WasmRegistrationError::Wasm)?;
|
||||
|
||||
tracing::info!(
|
||||
name = tool_with_binary.tool.name,
|
||||
user_id = user_id,
|
||||
trust_level = %tool_with_binary.tool.trust_level,
|
||||
"Registered WASM tool from storage"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Error when registering a WASM tool from storage.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum WasmRegistrationError {
|
||||
#[error("Storage error: {0}")]
|
||||
Storage(#[from] WasmStorageError),
|
||||
|
||||
#[error("WASM error: {0}")]
|
||||
Wasm(#[from] WasmError),
|
||||
}
|
||||
|
||||
/// Configuration for registering a WASM tool.
|
||||
|
||||
Reference in New Issue
Block a user