mirror of
https://github.com/ruvnet/RuView
synced 2026-07-23 17:33:20 +00:00
0ca903b497
ADR-161 honestly relabelled the manifest's wasm_module_hash / wasm_module_sig / publisher_key as "(P4 — not yet enforced)" and the homecore_permissions claims as deferred P5 authority isolation. This makes both real and tested. P4 (signature/integrity verification, SECURITY): - New `verify` module: SHA-256 module-hash check + Ed25519 signature verification over the digest against publisher_key, with a PluginPolicy trust allowlist and an explicit AllowUnsigned dev escape hatch (loud warn). Secure default rejects unsigned / unknown-publisher / tampered modules. - Reuses the in-repo cog-ha-matter::witness_signing Ed25519 pattern; sha2 is a workspace dep, ed25519-dalek/hex/base64 already in the lock — no new external dep tree (only new edges in homecore-plugins). - WasmtimeRuntime::load_plugin verifies before instantiation; legacy load_wasm retained for trusted/test modules. P5 (authority/capability isolation, SECURITY): - New `permissions` module: PermissionSet distilled from homecore_permissions (state:write:<glob> or bare entity glob). hc_state_set now consults it and returns a typed -3 to the guest on an undeclared write (no host panic). Tests (fail on old code, which had no load_plugin/verify and an unchecked hc_state_set): tampered module rejected; valid sig from trusted key loads; valid sig from untrusted key rejected; unsigned rejected by default and loads only under AllowUnsigned; light.* plugin writes light.kitchen but is denied lock.front_door; no-permission plugin can write nothing. Real deterministic keypair signs real bytes. Manifest doc updated: P4/P5 now ENFORCED (was "not yet enforced"). homecore-plugins --features wasmtime: 32 passed (lib 23, integration 9), 0 failed. Co-Authored-By: claude-flow <ruv@ruv.net>
69 lines
2.6 KiB
Rust
69 lines
2.6 KiB
Rust
//! HOMECORE-PLUGINS — WASM integration plugin system.
|
|
//!
|
|
//! Implements [ADR-128](../../docs/adr/ADR-128-homecore-integration-plugin-system.md)
|
|
//! P1 scaffold: manifest parsing, the `HomeCorePlugin` async trait, the
|
|
//! `PluginRuntime` abstraction, and the `PluginRegistry`.
|
|
//!
|
|
//! ## What's here (P1)
|
|
//!
|
|
//! - [`manifest`] — `PluginManifest`: superset of HA `manifest.json`; serde
|
|
//! round-trip + required-field validation.
|
|
//! - [`plugin`] — `HomeCorePlugin` async trait, `PluginId` newtype.
|
|
//! - [`runtime`] — `PluginRuntime` trait + `InProcessRuntime` (native Rust,
|
|
//! first-party plugins compiled into the binary).
|
|
//! - [`registry`] — `PluginRegistry<R>`: load / unload / list plugins.
|
|
//! - [`error`] — `PluginError` typed error enum.
|
|
//!
|
|
//! ## What's NOT here yet (deferred)
|
|
//!
|
|
//! - `WasmtimeRuntime` (P2, `--features wasmtime`): Cranelift JIT sandbox on
|
|
//! Pi 5 / x86_64. The runtime-selection question (Wasmtime vs wasm3) is still
|
|
//! open (ADR-128 §8) and will be resolved in Q2 before P2 begins.
|
|
//! - Host ABI wiring: `hc_state_get`, `hc_state_set`, `hc_event_fire`, etc.
|
|
//! (P2 — requires ADR-127 state machine API freeze first).
|
|
//! - Config entry lifecycle + hot-load (P3).
|
|
//!
|
|
//! ## Now enforced (ADR-162)
|
|
//!
|
|
//! - **Ed25519 signature + SHA-256 integrity verification (P4)** — see
|
|
//! [`verify`]: the plugin load path hashes the real `.wasm` bytes, checks
|
|
//! the manifest `wasm_module_hash`, verifies `wasm_module_sig` against
|
|
//! `publisher_key`, and enforces a [`verify::PluginPolicy`] allowlist.
|
|
//! - **Permission / authority isolation (P5)** — see [`permissions`]: a
|
|
//! plugin's `hc_state_set` writes are gated against the entity domains/
|
|
//! globs it declared in `homecore_permissions`.
|
|
//!
|
|
//! ## Feature flags
|
|
//!
|
|
//! | Feature | Default | Description |
|
|
//! |---------|---------|-------------|
|
|
//! | `wasmtime` | off | Wasmtime Cranelift JIT runtime (P2) |
|
|
//! | `wasm3` | off | wasm3 interpreter runtime for constrained hardware (P3) |
|
|
|
|
pub mod error;
|
|
pub mod host_abi;
|
|
pub mod manifest;
|
|
pub mod permissions;
|
|
pub mod plugin;
|
|
pub mod registry;
|
|
pub mod runtime;
|
|
pub mod verify;
|
|
|
|
#[cfg(feature = "wasmtime")]
|
|
pub mod wasmtime_runtime;
|
|
|
|
pub use error::PluginError;
|
|
pub use host_abi::{ConfigEntryJson, StateChangedEventJson};
|
|
pub use manifest::{IotClass, IntegrationType, PluginManifest};
|
|
pub use permissions::PermissionSet;
|
|
pub use plugin::{HomeCorePlugin, PluginId};
|
|
pub use registry::PluginRegistry;
|
|
pub use runtime::{InProcessRuntime, LoadedPlugin, PluginRuntime};
|
|
pub use verify::{verify_module, PluginPolicy};
|
|
|
|
#[cfg(feature = "wasmtime")]
|
|
pub use wasmtime_runtime::{WasmPlugin, WasmtimeRuntime};
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|