-
Notifications
You must be signed in to change notification settings - Fork 20
[go-fan] Go Module Review: tetratelabs/wazeroΒ #2829
Description
πΉ Go Fan Report: tetratelabs/wazero
Module Overview
wazero is a zero-dependency, pure-Go WebAssembly runtime β no cgo, no external libraries. It runs WASM modules in-process, making it ideal for sandboxed plugins and security guards. This project uses it (v1.11.0, latest) to execute DIFC (Decentralized Information Flow Control) guards: WASM modules that label MCP tool calls and responses with secrecy/integrity tags.
Current Usage in gh-aw-mcpg
- Files: 2 files (
internal/guard/wasm.go,internal/guard/wasm_test.go) - Instantiation sites: 3 (
proxy/proxy.go,server/guard_init.goΓ2) - Key APIs Used:
NewRuntimeConfigCompiler().WithCloseOnContextDone(true)β JIT mode with context-driven cancellationwasi_snapshot_preview1.Instantiate()β full WASI supportruntime.NewHostModuleBuilder("env")β exposescall_backendandhost_loghost functionsNewModuleConfig().WithStartFunctions().WithStdin(...)β disables auto-start, isolates stdinruntime.InstantiateWithConfig()β one-step compile + instantiatemodule.ExportedFunction()β runtime function lookupm.Memory().Read()/.Write()/.Grow()β linear memory I/O- WASM allocator integration via exported
alloc/dealloc(preferred path)
The usage is sophisticated and correct β trap poisoning, adaptive output buffers (4MBβ16MB in 3 retries), context.WithoutCancel for cleanup, and mutex serialization are all well-implemented.
Research Findings
Best Practices Already In Use β
WithCloseOnContextDone(true)β timeout/cancellation propagates into WASM executionWithStartFunctions()(no args) β correctly suppresses_startauto-call for library-style guardscontext.WithoutCancel(ctx)for deferredwasmDeallocβ cleanup runs even after request cancel- Trap detection via
strings.Contains(err, "wasm error:")with permanentfailedflag
Notable Feature: Compilation Cache
wazero has a compilation cache API (wazero.NewCompilationCache()) that caches JIT-compiled native artifacts and can be shared safely across multiple Runtime instances. Currently the project creates a fresh Runtime per guard and re-JITs every WASM binary on each instantiation. For large guards (the Rust-compiled github-guard WASM can be several MB), this adds measurable startup latency.
Improvement Opportunities
π Quick Wins
-
Consistent
Close()error handling βmodule.Close(ctx)errors are logged and swallowed whileruntime.Close(ctx)errors are returned. These should be treated consistently (e.g.,errors.Joinboth, or log both and return the runtime error). -
Buffer retry strategy comment β The adaptive 4MBβ16MB retry logic with the
-2error-code convention is non-obvious. A// Strategy:comment block at the top ofcallWasmFunctionexplaining the protocol would help future contributors.
β¨ Feature Opportunities
-
Process-level compilation cache β Add a package-level
wazero.NewCompilationCache()shared across allWasmGuardinstances:// In internal/guard/wasm.go var globalWasmCompilationCache = wazero.NewCompilationCache() // In NewWasmGuardWithOptions: runtimeConfig := wazero.NewRuntimeConfigCompiler(). WithCloseOnContextDone(true). WithCompilationCache(globalWasmCompilationCache)
wazero's cache is goroutine-safe and shared across runtimes. Impact: eliminates redundant JIT compilation when multiple guards load the same WASM binary (e.g., tests, restarts).
-
Test-suite compilation cache via
TestMainβ The test suite instantiatesWasmGuardmany times. Each call re-compiles the WASM binary. ATestMainwith a shared cache would cut test setup time significantly:func TestMain(m *testing.M) { testWasmCache = wazero.NewCompilationCache() defer testWasmCache.Close(context.Background()) os.Exit(m.Run()) }
-
Disk-backed compilation cache for production β
wazero.NewCompilationCacheContext(ctx, dir)persists compiled native code to disk. For deployments where startup time matters (e.g., containers that restart frequently), this would eliminate JIT compilation overhead entirely after the first run.
π Best Practice Alignment
WasmGuardOptionsmissingCompilationCachefield β The options struct supportsStdout/Stderrcustomization but has no way to inject a customCompilationCache. Adding this would make the cache injectable for both production sharing and test isolation:type WasmGuardOptions struct { Stdout io.Writer Stderr io.Writer CompilationCache wazero.CompilationCache // optional shared cache }
π§ General Improvements
ExportedFunction("label_agent")called twice β InLabelAgent, the function is checked for nil at the top (module.ExportedFunction("label_agent") == nil) and then looked up again insidecallWasmFunctionβmodule.ExportedFunction(funcName). The first check is redundant sincecallWasmFunctionhandles the nil case. Minor cleanup opportunity.
Recommendations
| Priority | Action | Effort |
|---|---|---|
| High | Add process-level wazero.NewCompilationCache() shared across WasmGuard instances |
Low |
| Medium | Add CompilationCache field to WasmGuardOptions |
Low |
| Medium | Add TestMain with shared cache in wasm_test.go |
Low |
| Low | Fix Close() error handling asymmetry |
Trivial |
| Low | Add strategy comment in callWasmFunction |
Trivial |
| Future | Evaluate disk-backed cache for production deployments | Medium |
Next Steps
- Implement process-level compilation cache (Lpcox/initial implementationΒ #3 above) β highest ROI, minimal risk
- Add
CompilationCachetoWasmGuardOptionsto enable injection (Updated Dockerfile to run 'go mod tidy'Β #6) - Add
TestMaincache inwasm_test.goto speed up tests (Lpcox/add difcΒ #4)
Generated by Go Fan πΉ
Module summary saved to: /tmp/gh-aw/agent/wazero.md (note: specs/mods/ directory does not yet exist in repo)
Round-robin cache updated: next review will skip tetratelabs/wazero for 7 days
Note
π Integrity filter blocked 16 items
The following items were blocked because they don't meet the GitHub integrity level.
- BurntSushi/toml@8685fba
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - stretchr/testify@5f80e4a
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - wazero/wazero@929e400
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - itchyny/gojq@183cbec
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - santhosh-tekuri/jsonschema@d3bf053
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - modelcontextprotocol/go-sdk@150bca7
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - spf13/cobra@61968e8
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/BurntSushi/toml/releases/tag/v1.6.0
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/stretchr/testify/releases/tag/v1.11.1
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/spf13/cobra/releases/tag/v1.10.2
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/santhosh-tekuri/jsonschema/releases/tag/v6.0.2
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/modelcontextprotocol/go-sdk/releases/tag/v1.4.1
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/itchyny/gojq/releases/tag/v0.12.18
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/wazero/wazero/releases/tag/v1.11.0
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - list_tags
list_tags: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - get_file_contents
get_file_contents: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | none
- expires on Apr 6, 2026, 7:46 AM UTC