spike: hermetic wasm tool execution via single preopened root (wasi-testsuite#264)#531
Draft
avrabe wants to merge 1 commit into
Draft
spike: hermetic wasm tool execution via single preopened root (wasi-testsuite#264)#531avrabe wants to merge 1 commit into
avrabe wants to merge 1 commit into
Conversation
Proof-of-concept answering: with WASI's single-root filesystem direction (WebAssembly/wasi-testsuite#264), can we map Bazel's hermetic file model onto wasmtime and call tools-as-wasm hermetically — which the old multi-preopen / absolute-host-path approach couldn't do cleanly? Answer: yes. Adds an experimental wasm_tool_run rule (single-root `wasmtime run --dir root::/`), a tiny wasip2 WASI command that transforms a file and probes hermeticity, and a diff_test that's green only if the tool read + wrote through the single root AND its probe of /etc/hostname,/etc/passwd was denied. `bazel test //test/spike_wasmtime_hermetic:all` passes. Key finding (SPIKE.md): the single-root model works and hermeticity is the intersection of Bazel's sandbox and WASI's deny-by-default capabilities. The one Bazel-specific obstacle: Bazel stages declared inputs as symlinks pointing outside the sandbox, and WASI refuses to traverse a preopen-escaping symlink (errno 63 = ENOTCAPABLE; reproduced + root-caused). Fix: materialize inputs as real files inside the root (the preopen dir itself may be a symlink — wasmtime canonicalizes it). That is exactly why absolute-host-path multi-preopen fought Bazel, and why one materialized root + guest-absolute paths is the clean shape. SPIKE-ONLY: input staging uses run_shell (cp) for brevity; production should use a hermetic copy (bazel-lib copy_to_directory / a launcher) per RULE #1, plus AOT(.cwasm)+Wizer and a benchmark for the efficiency claim. Not for merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft / spike — not for merge. Answers the question from the wasi-testsuite#264 discussion: now that WASI is moving to a single-root filesystem model, can we map Bazel's hermetic file model onto wasmtime and call tools-as-wasm hermetically — the thing the old multi-preopen / absolute-host-path approach couldn't do cleanly?
Answer: yes — and the spike pins down the one Bazel-specific caveat.
What's here
transform.rs— a tiny WASI command (wasm32-wasip2viarust_wasm_binary) that reads→uppercases→writes a file and probes hermeticity (tries to read/etc/hostname,/etc/passwd, exits non-zero if either succeeds).//wasm/private:wasm_tool_run.bzl— experimental rule running the tool as a hermetic Bazel action through one preopened root (wasmtime run --dir root::/).transform_output_test—diff_test, green only if the tool transformed through the single root and the probe was denied.bazel test //test/spike_wasmtime_hermetic:all→ passes (ok: /sample.txt -> /out … sandbox confirmed).Findings (full write-up in
SPIKE.md)os error 63= WASIENOTCAPABLE. Root cause (confirmed two ways): Bazel stages declared inputs as symlinks pointing outside the sandbox, and WASI refuses to traverse a preopen-escaping symlink. wasmtime has no flag to relax this.Not done (spike scope)
run_shell(cp) for brevity — production must use a hermetic copy (copy_to_directory/ a launcher) per RULE export\! macro not accessible in rust_wasm_component_bindgen #1, no shell..cwasm) + Wizer + a benchmark to back the efficiency claim with a number (native vs JIT vs AOT+wizer).Opening as a draft to capture the finding and the working invocation; happy to turn it into a real
wasm_tool_runrule (hermetic staging + AOT/wizer + benchmark) if we want to pursue it.🤖 Generated with Claude Code