Plugin SDK and authoring
For the complete operator-facing guide, see WASM plugins. The source repository’s detailed Plugin Authoring Guide is the ABI reference; this page is the contributor workflow.
- Put a
plugin.tomlmanifest and one compiled.wasmmodule in one plugin directory. Declare a lowercase/hyphenated ID, module filename, ABI version, capabilities, and[limits]. - Use
crates/bearust-plugin-sdkas the guest contract. ABI v2 requires exported linear memory,bearust_alloc,bearust_dealloc,bearust_abi_version, andbearust_health_check_v2; hook exports use JSON input/output through the SDK’s packed pointer/length convention. - Build Rust plugins as
cdylibforwasm32-wasip1:cargo build --release --target wasm32-wasip1. The runtime provides no WASI, filesystem, network, or host imports despite that compilation target. - Use
tests/fixtures/plugins/for deterministic manifests/modules and add fixture-driven runtime tests. Do not commit generated compiler caches or arbitrary third-party WASM.
Capabilities include waf.detect, transform.request, transform.response, notify.waf_block, and balance.select, plus health checks. Each hook has a typed input/output contract and manifest output floor. Inputs/outputs, memory pages, fuel, and wall-clock execution are bounded; malformed output, traps, timeouts, fuel exhaustion, and unavailable hooks fail open for proxy traffic. A request transform’s returned headers are followed by BeaRust’s reassertion of Host, X-Forwarded-For, and X-Request-Id; WAF plugins can escalate, not lower, a built-in decision.
Plugin loading is disabled by default. The runtime loader loads only local reviewed directories under the configured plugins directory; separately, the CLI ships a client for a static HTTPS-hosted registry index in plugin_registry.rs. bearust plugin search <query> and bearust plugin install <id> --out <dir> (cli.rs) fetch the index, download a plugin tarball, verify its SHA-256 checksum and embedded signature against the index entry, and extract it into the plugins directory. The index is a catalog and transport-integrity check only, never a source of trust: an installed plugin still goes through the same reload and trust-on-first-use flow. No community/operator-hosted registry exists yet; the default index URL can be overridden with --registry-url or BEARUST_PLUGIN_REGISTRY_URL. Optional signing uses bearust plugin keygen --out <dir> and bearust plugin sign <plugin-dir> --key <key-path>. With require_signature, unsigned bundles are rejected. Trust-on-first-use pins the first signing key for a plugin ID in trusted-keys.json; a changed key fails closed. This protects a distribution channel, not a host where an attacker can already write the plugin directory.
Verify with tests/plugin_runtime.rs, tests/control_plane_plugins.rs, and the authoring guide’s authenticated reload/health-check flow.