mirror of
https://github.com/ruvnet/RuView
synced 2026-08-10 20:31:42 +00:00
feat(homecore-plugins): enforce plugin signature + capability isolation (ADR-162 P4/P5)
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>
This commit is contained in:
@@ -22,8 +22,16 @@
|
||||
//! - 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).
|
||||
//! - Cog registry distribution + Ed25519 signature verification (P4).
|
||||
//! - Permission enforcement (P5).
|
||||
//!
|
||||
//! ## 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
|
||||
//!
|
||||
@@ -35,9 +43,11 @@
|
||||
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;
|
||||
@@ -45,9 +55,11 @@ 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};
|
||||
|
||||
Reference in New Issue
Block a user