wasm

package
v0.3.5-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 14, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

README

WASM Runtime Package

This package provides the WebAssembly runtime infrastructure for Reglet plugins using wazero.

Overview

All Reglet plugins are WASM modules (including embedded ones). This package:

  • Loads and executes WASM plugins
  • Enforces capability-based sandboxing
  • Provides host functions for filesystem, network, and system access
  • Manages plugin lifecycle and resource cleanup

Architecture

Runtime
  ├── wazero.Runtime (WASM engine)
  ├── CapabilityManager (security enforcement)
  └── Map<name, Plugin> (loaded plugins)

Plugin
  ├── CompiledModule (WASM bytecode)
  ├── Instance (running module)
  ├── Cached PluginInfo (from describe())
  └── Cached ConfigSchema (from schema())

Key Types

Runtime

Main runtime manager. Create one per Reglet execution:

ctx := context.Background()
runtime, err := wasm.NewRuntime(ctx)
defer runtime.Close()
Plugin

Wrapper around a WASM module. Provides methods to call WIT interface functions:

// Load plugin
plugin, err := runtime.LoadPlugin("file", wasmBytes)

// Get metadata
info, err := plugin.Describe()

// Get config schema
schema, err := plugin.Schema()

// Execute observation
result, err := plugin.Observe(config)
Type Mappings

Go types map to WIT interface types:

Go Type WIT Type
PluginInfo plugin-info
Capability capability
Config config
Evidence evidence
PluginError error
ConfigSchema config-schema

Current Status

Phase 1a - Basic Infrastructure:

✅ Runtime initialization with wazero ✅ Plugin loading and module compilation ✅ Type definitions matching WIT interface ✅ Basic tests

TODO - WIT Bindings:

The current implementation has placeholder TODOs for WIT bindings:

  1. Marshal/Unmarshal: Need to implement proper data serialization between Go and WASM memory
  2. Host Functions: Need to implement capability-enforced host functions
  3. Memory Management: Need to handle WASM linear memory for passing complex data structures

This will be completed after we build a simple plugin to validate the approach.

Host Functions (Planned)

Host functions will provide sandboxed access to system resources:

Filesystem
  • fs_read(path: string) -> result<bytes, error>
  • fs_write(path: string, data: bytes) -> result<void, error>
  • Enforces fs:read:<glob> and fs:write:<glob> capabilities
Network
  • net_connect(host: string, port: u16) -> result<connection, error>
  • Enforces network:outbound:<ports> capability
Environment
  • env_get(name: string) -> result<string, error>
  • Enforces env:<pattern> capability
Execution
  • exec_run(command: string, args: []string) -> result<output, error>
  • Enforces exec:<commands> capability

Security Model

Capability Enforcement
  1. Plugin declares required capabilities in describe()
  2. System config grants capabilities to plugins
  3. Runtime checks capabilities on every host function call
  4. Unauthorized access is denied with clear error
Sandboxing
  • WASM provides memory isolation (plugins can't access host memory directly)
  • wazero is pure Go (no CGO, no OS syscalls from plugins)
  • All system access goes through capability-checked host functions
  • Timeouts prevent infinite loops

Testing

Run tests:

make test

Current test coverage:

  • Runtime initialization
  • Plugin loading with invalid WASM
  • Plugin cache/retrieval

TODO: Add tests with actual WASM plugins once we build the file plugin.

Dependencies

  • github.com/tetratelabs/wazero - Pure Go WASM runtime
  • github.com/stretchr/testify - Testing framework

Next Steps

  1. Build a simple file plugin in Go that compiles to WASM
  2. Implement WIT bindings for data marshaling
  3. Test end-to-end: load plugin, call describe/observe
  4. Implement host functions with capability checking
  5. Add comprehensive tests with real plugins

Documentation

Overview

Package wasm provides WebAssembly runtime infrastructure for Reglet plugins. It manages plugin loading, execution, and capability-based sandboxing using wazero.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Values map[string]interface{}
}

Config represents plugin configuration Maps to the WIT config record

type ConfigSchema

type ConfigSchema struct {
	Fields    []FieldDef
	RawSchema []byte // Raw JSON Schema data from plugin
}

ConfigSchema represents the JSON Schema for plugin configuration Maps to the WIT config-schema record

type Evidence

type Evidence = execution.Evidence

Evidence is re-exported from domain for backward compatibility in this package. Use execution.Evidence from domain layer.

type FieldDef

type FieldDef struct {
	Name        string
	FieldType   string
	Description string
	Required    bool
}

FieldDef represents a configuration field definition Maps to the WIT field-def record

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin manages the lifecycle and execution of a compiled WASM module.

func (*Plugin) Close

func (p *Plugin) Close() error

Close performs any necessary cleanup. Currently a no-op as instances are ephemeral.

func (*Plugin) Describe

func (p *Plugin) Describe(ctx context.Context) (*PluginInfo, error)

Describe executes the plugin's 'describe' function to retrieve metadata.

func (*Plugin) Name

func (p *Plugin) Name() string

Name returns the unique identifier of the plugin.

func (*Plugin) Observe

func (p *Plugin) Observe(ctx context.Context, cfg Config) (*PluginObservationResult, error)

Observe executes the main validation logic of the plugin.

func (*Plugin) Schema

func (p *Plugin) Schema(ctx context.Context) (*ConfigSchema, error)

Schema executes the plugin's 'schema' function to retrieve configuration definitions.

type PluginError

type PluginError = execution.PluginError

PluginError is re-exported from domain for backward compatibility in this package. Use execution.PluginError from domain layer.

type PluginInfo

type PluginInfo struct {
	Name         string
	Version      string
	Description  string
	Capabilities []capabilities.Capability
}

PluginInfo contains metadata about a plugin Maps to the WIT plugin-info record

type PluginObservationResult

type PluginObservationResult struct {
	Evidence *execution.Evidence
	Error    *execution.PluginError
}

PluginObservationResult is the result of running an observation through a WASM plugin. This is a low-level boundary type.

type Runtime

type Runtime struct {
	// contains filtered or unexported fields
}

Runtime manages WASM execution.

func NewRuntime

func NewRuntime(ctx context.Context, version build.Info, opts ...RuntimeOption) (*Runtime, error)

NewRuntime creates a runtime with optional configuration. By default, creates a runtime with no capabilities, no redaction, 256MB memory limit, and shared compilation cache.

Example usage:

// Simple case (defaults)
runtime, err := NewRuntime(ctx, version)

// With capabilities and redaction
runtime, err := NewRuntime(ctx, version,
    WithCapabilities(caps),
    WithRedactor(redactor),
    WithMemoryLimit(512),
)

// Test isolation (separate cache)
runtime, err := NewRuntime(ctx, version,
    WithCompilationCache(wazero.NewCompilationCache()),
)

func (*Runtime) Close

func (r *Runtime) Close(ctx context.Context) error

Close closes the runtime and cleans up resources

func (*Runtime) GetPlugin

func (r *Runtime) GetPlugin(name string) (*Plugin, bool)

GetPlugin retrieves a loaded plugin by name.

func (*Runtime) GetPluginSchema

func (r *Runtime) GetPluginSchema(ctx context.Context, pluginName string) ([]byte, error)

GetPluginSchema implements config.PluginSchemaProvider. It loads the plugin (if not already loaded) and retrieves its JSON Schema.

func (*Runtime) LoadPlugin

func (r *Runtime) LoadPlugin(ctx context.Context, name string, wasmBytes []byte) (*Plugin, error)

LoadPlugin compiles and caches a plugin, and is safe for concurrent use.

The first call for a given plugin name compiles the provided WASM bytes, creates a Plugin, and stores it in an internal cache keyed by name. Subsequent calls with the same name return the previously cached Plugin instance; the WASM module is not recompiled.

To reduce contention while remaining thread-safe, LoadPlugin uses a double-checked locking pattern around the plugin cache: it first checks the cache under a read lock, and only acquires a write lock if the plugin is not yet present, re-checking the cache under the write lock before compiling. Callers do not need to provide additional synchronization when calling LoadPlugin from multiple goroutines.

type RuntimeOption

type RuntimeOption func(*runtimeConfig)

RuntimeOption configures a Runtime.

func WithCapabilities

func WithCapabilities(caps map[string][]capabilities.Capability) RuntimeOption

WithCapabilities sets the granted capabilities.

func WithCompilationCache

func WithCompilationCache(cache wazero.CompilationCache) RuntimeOption

WithCompilationCache provides a custom compilation cache for this runtime. This is useful for:

  • Tests: Isolate cache between tests to prevent interference
  • Servers: Multiple isolated runtime pools with separate caches
  • Advanced use cases: Custom cache lifecycle management

If not provided, uses the default shared cache for the process.

func WithMemoryLimit

func WithMemoryLimit(mb int) RuntimeOption

WithMemoryLimit sets the WASM memory limit in MB. 0 = default (256MB), -1 = unlimited, >0 = explicit limit.

func WithRedactor

func WithRedactor(redactor *sensitivedata.Redactor) RuntimeOption

WithRedactor enables secret redaction for plugin output.

Directories

Path Synopsis
Package hostfuncs provides host functions for WASM plugins
Package hostfuncs provides host functions for WASM plugins

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL