09 — Plugin System
Deep dive on the programmable pillar (flagship §1). A capability-secure WASM runtime that lets BitVault — and its users — be extended with sandboxed code in any language, at well-defined extension points.
1. Architecture
flowchart TB
classDef h fill:#bbf7d0,stroke:#15803d,color:#111827;
classDef p fill:#fde68a,stroke:#b45309,color:#111827;
classDef c fill:#c7d2fe,stroke:#3730a3,color:#111827;
host["BitVault host (Go) · wazero runtime"]:::h
pdk["PDK (Go/Rust/JS/Python via Extism-style) → .wasm"]:::p
reg["signed plugin registry (cosign, ADR-0032)"]:::p
subgraph INST["per-invocation instance (fuel · memory · wall-clock limits)"]
mod["plugin module"]:::p
end
pdk --> reg --> host --> INST
mod -->|"imports = ONLY granted host functions"| abi["Capability ABI:<br/>read_input · write_output · log ·<br/>scoped_http(allowlist) · scoped_kv · emit_event"]:::c
abi --> host
host -. "deny-by-default: no FS / no net / no syscalls" .-> mod
- Runtime: wazero — zero-dependency, CGO-free, embeds in
bitvaultd(ADR-0001); interpreter + compiler modes; safe concurrency + context propagation. - Capability ABI: a module imports only the host functions the host grants — there is no ambient filesystem, network, or syscall access. Network is an allow-listed scoped HTTP client; storage is a scoped reader/writer bound to the triggering tenant/path. Whitelist, not blacklist.
- Resource governance: fuel (CPU), memory ceiling, and wall-clock per invocation; a plugin panic is contained — it cannot crash the host (Envoy/Helm-4 model).
- Multi-language: an Extism-style PDK lets plugins be written in Go, Rust, JS,
Python, etc., and compiled to one
.wasmABI. - Distribution: modules are signed (cosign, reusing ADR-0032) and resolved from a registry; admission verifies signatures before load.
2. Extension points (the catalog)
| Extension point | A plugin can… | Powers |
|---|---|---|
| Content transform | take input bytes → emit derived output | thumbnails, transcode, OCR (04 S5) |
| Event handler | react to a domain event | Functions (01 §2), automations (06) |
| Storage provider | implement Put/Get/Head/… | custom/niche backends behind the storage abstraction (ADR-0005) |
| Auth provider | validate a token / map identity | bespoke SSO/identity sources |
| Policy hook | contribute an attribute/decision input | custom governance signals (07) |
| Search analyzer / preview | tokenize / render a custom format | better search + previews for niche file types |
Extension points are typed contracts (protobuf-defined, ADR-0003), so a plugin is just an implementation of a known interface — discoverable and testable.
3. Sub-features
PL-1 — WASM runtime + capability ABI ⭐ flagship
The core (01 §1).
| Why | Complexity | Dependencies | Resume |
|---|---|---|---|
| the substrate for all programmability | L | Go host, signing (ADR-0032) | Very high — language-runtime + capability security |
PL-2 — Extension-point framework
- The typed contracts + lifecycle (discover/load/instantiate/invoke/teardown) + a conformance test suite per extension point (mirrors the storage adapter conformance, ADR-0005).
| Why | Complexity | Dependencies | Resume |
|---|---|---|---|
| turns “a runtime” into “an extensible platform” | M | PL-1, proto contracts | High |
PL-3 — Plugin registry & marketplace
- Signed, versioned plugin distribution + (eventually) a marketplace; tenant-scoped install + capability grants reviewed per plugin.
| Why | Complexity | Dependencies | Resume |
|---|---|---|---|
| ecosystem/network effects; governance of third-party code | M | PL-1, signing, policy (07) | Medium |
4. Why WASM (tradeoffs / alternatives)
- vs native Go plugins (
pluginpkg): brittle (exact-version/toolchain coupling), no sandbox (runs with host privileges) — unacceptable for untrusted code. Rejected. - vs containers/microVMs (gVisor/Firecracker) per plugin: stronger isolation but far heavier (startup, memory, ops) — wrong granularity for per-file-event functions. WASM’s millisecond cold-start + in-process sandbox fits.
- vs an embedded scripting language (Lua/Starlark): simpler but single-language and weaker isolation/limits. WASM gives any language + true capability sandbox + resource limits.
The payoff: WASM is the rare choice that is simultaneously safe (capability sandbox), fast (near-native, ms cold start), polyglot, and embeddable in Go — the exact properties a multi-tenant plugin platform needs. It is also, not coincidentally, one of the highest-signal things on this entire list to have built.
Priorities within plugins
PL-1 is foundational (everything programmable depends on it). PL-2 makes it a platform. PL-3 (registry/marketplace) is the ecosystem play once the first two land.