Skip to content

feat: sandboxed WASM security checks behind wasm-plugins feature - #2

Open
rifkyputra wants to merge 3 commits into
mainfrom
feat/wasm-security-plugins
Open

feat: sandboxed WASM security checks behind wasm-plugins feature#2
rifkyputra wants to merge 3 commits into
mainfrom
feat/wasm-security-plugins

Conversation

@rifkyputra

Copy link
Copy Markdown
Owner

Summary

Adds an optional WASM plugin boundary for security checks, gated behind the off-by-default wasm-plugins feature so the standard build stays wasmtime-free (the dep only lands in Cargo.lock).

The Security screen's findings list transparently merges native + WASM-reported findings when the feature is on and plugins are present — no screen or app.rs change.

What's included

  • wit/security-check.wit — canonical plugin contract (host grants read-file; plugin exports scan). The host bindgen! consumes it as the single source of truth.
  • cli/src/core/plugins/mod.rs
    • PluginHost — wasmtime engine, fuel-metered per scan, deny-by-default read allowlist (plugins may only read under /etc).
    • WasmAuditor / CompositeAuditor — implement SecurityAuditor; merge native + WASM findings. A failing plugin is logged and skipped, never masking the native audit. apply() stays native-only (plugins propose, only trusted code writes).
  • cli/src/core/platform.rs — wraps the native auditor via plugins::security_auditor when the feature is on; falls back to native if no plugins load or the host is unavailable.
  • examples/wasm-check-sshd/ — example guest component (PermitRootLogin check) generating against the same WIT.
  • make wasm-example — builds + componentizes the example.

Testing

  • make check — clean (default build, wasmtime not compiled).
  • make test — 52 passing.
  • cargo clippy -p postlab --features wasm-plugins -- -D warnings — clean (host compiles against wasmtime 27 and the WIT file).

Not verified

The example guest is not built/loaded end-to-end — this environment has no wasm32 target or wasm-tools. Host side is fully verified; the guest source + make wasm-example are unproven until run on a machine with the wasm toolchain. Open items before production: confirm the guest wit-bindgen symbol names and component-ABI load compat with the wasmtime-27 host, and decide how the plugin dir is provisioned/trusted.

🤖 Generated with Claude Code

rifkyputra and others added 3 commits June 28, 2026 03:05
Add an optional WASM plugin boundary for security checks, gated behind
the off-by-default `wasm-plugins` feature so the standard build stays
wasmtime-free.

- wit/security-check.wit: canonical plugin contract (host grants read-file;
  plugin exports scan); host bindgen consumes it as the single source of truth
- core/plugins: PluginHost (wasmtime engine, fuel-metered, deny-by-default
  read allowlist under /etc) + WasmAuditor + CompositeAuditor that merges
  native and WASM findings; apply() stays native-only
- platform.rs: wrap the native auditor via plugins::security_auditor when the
  feature is on, transparent to the Security screen; falls back to native if
  no plugins load
- examples/wasm-check-sshd: example guest component (PermitRootLogin check)
- make wasm-example: build + componentize the example

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All SUDO_USER-based home directory resolution (~5 divergent copies, some
with /home/{user} convention broken on macOS, one in main.rs ignoring
SUDO_USER entirely) now routes through core::real_home() which uses
nix::unistd::User::from_name for a correct passwd lookup on all platforms.

Also: fix plugin sandbox symlink escape — resolve canonical path before
authorizing reads under allowed roots (plugins run as root).
- backup_file(): was duplicated in security/checks.rs (format-based)
  and ssh/mod.rs (with_extension-based, fragile for files with dots).
  Single canonical version in core/mod.rs using AsRef<Path>, timestamp
  pattern {path}.bak.{timestamp}. Removes chrono::Local and Path imports
  from both modules.

- expand_home(): was duplicated as expand_tilde() in main.rs (~/ only)
  and expand_home() in projects/mod.rs (~ any). Single version in
  core/mod.rs with shell-correct starts_with("~/") matching. Re-exported
  from projects for existing callers including tui/app.rs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant