Something went wrong. Try again.
Flatpak-style launcher for sandboxed WebAssembly tools. Install, verify, and run .wasm binaries with explicit capability grants. Single binary, local-first, zero telemetry. wasmbox.orbiter.website
wasm rust wasmbox
Something went wrong. Try again.
14 kB · 246 lines
HTML
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247<!doctype html><html lang="en" data-theme="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="generated" content="2026-05-19T19:41:01Z"><title>WasmBox — API</title><style>:root { --bg:#0a0a0a; --fg:#e8e8e8; --muted:#888; --accent:#7dd3fc; --code-bg:#141414; --border:#222; --mono:ui-monospace,SFMono-Regular,Menlo,monospace; --sans:system-ui,-apple-system,sans-serif; --ok:#86efac; --warn:#fde047; --bad:#fca5a5; }@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) { --bg:#fafafa; --fg:#111; --muted:#555; --accent:#0369a1; --code-bg:#f0f0f0; --border:#ddd; --ok:#16a34a; --warn:#a16207; --bad:#b91c1c; } }html { background: var(--bg); color: var(--fg); font-family: var(--sans); }body { max-width:1100px; margin:0 auto; padding:2rem 1.5rem 6rem; line-height:1.6; }header { display:flex; justify-content:space-between; align-items:baseline; border-bottom:1px solid var(--border); padding-bottom:1rem; margin-bottom:2rem; }header nav a { color:var(--muted); text-decoration:none; margin-right:1rem; }h1,h2,h3 { font-weight:600; line-height:1.2; }h1 { font-size:2rem; margin:0 0 0.5rem; }h2 { font-size:1.4rem; margin-top:3rem; border-bottom:1px solid var(--border); padding-bottom:0.4rem; }h2 a.anchor, h3 a.anchor { color:var(--muted); text-decoration:none; opacity:0; margin-left:0.5rem; font-size:0.85em; }h2:hover a.anchor, h3:hover a.anchor { opacity:1; }h3 { font-size:1.1rem; margin-top:2rem; color:var(--accent); font-family:var(--mono); }a { color:var(--accent); }code, pre { font-family:var(--mono); font-size:0.9em; }pre { background:var(--code-bg); border:1px solid var(--border); padding:1rem; overflow-x:auto; border-radius:4px; }code:not(pre code) { background:var(--code-bg); padding:0.1em 0.4em; border-radius:3px; }table { border-collapse:collapse; width:100%; margin:1rem 0; }th, td { text-align:left; padding:0.6rem 0.8rem; border-bottom:1px solid var(--border); vertical-align:top; }th { color:var(--muted); font-weight:500; font-size:0.85em; text-transform:uppercase; letter-spacing:0.05em; }td code { font-size:0.85em; }footer { margin-top:6rem; padding-top:1rem; border-top:1px solid var(--border); color:var(--muted); font-size:0.85em; }#toc { background:var(--code-bg); border-left:2px solid var(--accent); padding:0.8rem 1.2rem; margin:2rem 0; }#toc ol { margin:0; padding-left:1.2rem; }#toc a { color:var(--fg); text-decoration:none; }.cmd { border:1px solid var(--border); border-radius:6px; padding:1rem 1.2rem; margin:1.2rem 0; background:var(--code-bg); }.cmd .sig { font-family:var(--mono); color:var(--accent); font-size:1.05em; }.cmd .desc { color:var(--muted); margin:0.4rem 0 0.8rem; }.cmd dl { margin:0; }.cmd dt { font-family:var(--mono); color:var(--fg); font-size:0.85em; margin-top:0.5rem; }.cmd dd { margin:0.1rem 0 0 1.2rem; color:var(--muted); font-size:0.9em; }.exit-table td:first-child { font-family:var(--mono); width:6em; color:var(--accent); }</style></head><body><header> <nav> <a href="./index.html">WasmBox</a> <span style="color:var(--muted)">/ api</span> </nav> <button onclick="document.documentElement.dataset.theme = document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark'" style="background:none;border:1px solid var(--border);color:var(--fg);padding:0.3em 0.6em;cursor:pointer;border-radius:3px;font-size:0.8em">theme</button></header>
<h1>API</h1><p style="color:var(--muted)">Complete CLI surface and registry protocol. Every command supports <code>--json</code>; global flags are <code>--home <path></code> and <code>--json</code>.</p>
<nav id="toc"> <ol> <li><a href="#tools">Tool lifecycle</a></li> <li><a href="#exec">Execution</a></li> <li><a href="#perms">Permissions</a></li> <li><a href="#compliance">Compliance (FSL)</a></li> <li><a href="#registry">Registry management</a></li> <li><a href="#util">Utilities</a></li> <li><a href="#protocol">Registry protocol</a></li> <li><a href="#exit">Exit codes</a></li> </ol></nav>
<h2 id="tools">Tool lifecycle <a class="anchor" href="#tools">#</a></h2>
<div class="cmd"> <div class="sig">wasmbox install <name> [--registry URL] [--allow CAP]... [--allow-all]</div> <p class="desc">Resolve <code>name</code> across configured registries, fetch the manifest, download the binary, verify SHA-256, prompt for capabilities, cache.</p> <dl> <dt>--registry URL</dt><dd>Pin source registry instead of searching all configured.</dd> <dt>--allow CAP</dt><dd>Pre-grant a capability (<code>stdin</code>, <code>stdout</code>, <code>filesystem:<path></code>, <code>network:<host></code>, <code>env:<NAME></code>). Repeat for multiple.</dd> <dt>--allow-all</dt><dd>Grant every capability the manifest requests without prompting. Used by <code>install.sh</code> and CI scripts.</dd> </dl></div>
<div class="cmd"> <div class="sig">wasmbox list [--json]</div> <p class="desc">List installed tools with version, install date, and registry source. <code>--json</code> emits an array of objects.</p></div>
<div class="cmd"> <div class="sig">wasmbox search <query> [--json]</div> <p class="desc">Search the cached index of each configured registry. Index cache TTL is 1 hour. <code>--json</code> emits matching tools.</p></div>
<div class="cmd"> <div class="sig">wasmbox info <name> [--json]</div> <p class="desc">Show manifest metadata, capabilities, and the <code>[agent]</code> block. JSON output includes <code>agent.modes</code> and <code>agent.exit_codes</code> for agent consumption.</p></div>
<div class="cmd"> <div class="sig">wasmbox verify <name></div> <p class="desc">Recompute SHA-256 of the cached binary and compare in constant time against the manifest. Exit 0 on match, exit 3 on mismatch.</p></div>
<div class="cmd"> <div class="sig">wasmbox update <name></div> <p class="desc">Fetch latest manifest, show old vs new hash and any new capabilities, prompt to apply. Previous version kept for rollback. Never automatic.</p></div>
<div class="cmd"> <div class="sig">wasmbox remove <name>[@<version>]</div> <p class="desc">Remove all versions, or a specific pinned version. Permissions for the removed version are also dropped from <code>permissions.toml</code>.</p></div>
<h2 id="exec">Execution <a class="anchor" href="#exec">#</a></h2>
<div class="cmd"> <div class="sig">wasmbox run <name> [--sandbox] [--allow CAP]... [--allow-all] [-- <tool args>]</div> <p class="desc">Run an installed tool. Hash is re-verified before every execution. Arguments after <code>--</code> are forwarded to the guest. Stdin/stdout are wired through when those capabilities are granted.</p> <dl> <dt>--sandbox</dt><dd>Force zero capabilities regardless of stored grants — useful for dry-running an untrusted tool.</dd> <dt>--allow CAP</dt><dd>Add a capability for this run only. Not persisted to <code>permissions.toml</code>.</dd> <dt>--allow-all</dt><dd>Skip prompts when stdin isn't a TTY. Exits 2 if grants are missing and prompts are unavailable.</dd> </dl></div>
<div class="cmd"> <div class="sig">wasmbox run --file <path.wasm> [--sandbox] [--allow CAP]... [-- <tool args>]</div> <p class="desc">Run a local <code>.wasm</code> file directly without registry lookup. No manifest, no hash check — explicit caller responsibility.</p></div>
<h2 id="perms">Permissions <a class="anchor" href="#perms">#</a></h2>
<div class="cmd"> <div class="sig">wasmbox permissions <name> [show|revoke] [--json]</div> <p class="desc">Show currently granted capabilities for a tool, or revoke all of them. <code>show</code> is the default.</p></div>
<div class="cmd"> <div class="sig">wasmbox revoke <name> <capability></div> <p class="desc">Revoke a single capability (e.g. <code>wasmbox revoke crypts network</code>). Next run will re-prompt or fail with exit 2.</p></div>
<div class="cmd"> <div class="sig">wasmbox audit [--json] [--export PATH] [--format json|md|csv] [--sign] [--init-key] [--verify FILE]</div> <p class="desc">List all granted permissions across all tools. With <code>--export</code> generates a compliance report combining tool inventory, run log, and policy status. <code>--sign</code> adds Ed25519 signature; <code>--init-key</code> generates a keypair under <code>~/.wasmbox/</code>; <code>--verify</code> validates a signed report.</p></div>
<h2 id="compliance">Compliance (FSL) <a class="anchor" href="#compliance">#</a></h2>
<div class="cmd"> <div class="sig">wasmbox log [--tool NAME] [--blocked] [--stats] [--export PATH] [--rotate] [--json]</div> <p class="desc">Inspect the append-only run log at <code>~/.wasmbox/run.log</code>. Filter by tool, show only blocked attempts, compute statistics, export for evidence, or rotate to start fresh.</p></div>
<div class="cmd"> <div class="sig">wasmbox policy init [--name LABEL] [--approved-by EMAIL] [--enforcement enforce|warn|disabled]</div> <p class="desc">Create <code>~/.wasmbox/policy.toml</code> from currently installed tools — captures name, hash, capability set per tool.</p></div>
<div class="cmd"> <div class="sig">wasmbox policy check | add <name> | diff | enforce</div> <p class="desc"><code>check</code> verifies installed tools match policy. <code>add</code> approves a new tool. <code>diff</code> shows changes since last approval. <code>enforce</code> switches mode to blocking.</p></div>
<div class="cmd"> <div class="sig">wasmbox policy agent --enable | wasmbox policy shell</div> <p class="desc">Enable the agent shell wrapper that blocks raw system commands (<code>jq</code>, <code>yq</code>, <code>base64</code>, <code>sha256sum</code>, <code>date</code>, <code>trufflehog</code>, <code>python -c</code>, <code>node -e</code>) and redirects to sandboxed WasmBox equivalents. <code>shell</code> prints the wrapper script to stdout for installation.</p></div>
<h2 id="registry">Registry management <a class="anchor" href="#registry">#</a></h2>
<div class="cmd"> <div class="sig">wasmbox registry add <url> | list [--json] | remove <url></div> <p class="desc">Manage configured registries stored in <code>~/.wasmbox/registries.toml</code>. URLs must be HTTPS; HTTP is rejected.</p></div>
<h2 id="util">Utilities <a class="anchor" href="#util">#</a></h2>
<div class="cmd"> <div class="sig">wasmbox hash <file> [--json]</div> <p class="desc">Compute SHA-256 of a file. Output format <code>sha256:<hex></code>. Use to fill the <code>hash</code> field of a tool manifest before publishing.</p></div>
<h2 id="protocol">Registry protocol <a class="anchor" href="#protocol">#</a></h2><p>A registry is any static HTTPS host serving these endpoints. No auth, no cookies, no tracking. Any S3 bucket, GitHub Pages site, or plain nginx works.</p>
<table> <thead><tr><th>Endpoint</th><th>Returns</th><th>Notes</th></tr></thead> <tbody> <tr><td><code>GET /index.json</code></td><td><code>{ registry, tools: [...] }</code></td><td>List of <code>{name, version, description}</code>. Cached 1h client-side.</td></tr> <tr><td><code>GET /tools/<name>.json</code></td><td>Manifest TOML as text</td><td>Strict parser — unknown fields rejected. <code>hash</code> field is mandatory.</td></tr> <tr><td><code>GET /tools/<name>.wasm</code></td><td>Raw <code>wasm32-wasip2</code> binary</td><td>SHA-256 must match manifest. Verified in constant time.</td></tr> <tr><td><code>GET /tools/<name>.md</code></td><td>Agent skill file (Markdown)</td><td>Optional. Documents modes, examples, exit codes for agent consumption.</td></tr> </tbody></table>
<p>Demo registry: <a href="https://qstorage.quilibrium.com/wasmbox"><code>https://qstorage.quilibrium.com/wasmbox</code></a>. Add with <code>wasmbox registry add <url></code>.</p>
<h3>Manifest example</h3><pre>[tool]name = "fantasma"version = "0.1.0"description = "Message anonymiser. Strips PII locally."author = "Aunova"license = "MIT"homepage = "https://aunova.net/fantasma"
[binary]wasm = "fantasma.wasm"hash = "sha256:a1b2c3d4..."
[capabilities]stdin = truestdout = truenetwork = ["api.example.com", "cdn.example.com:443"]filesystem = [{ path = "~/Documents", read = true, write = false }]env = ["LANG"]
[ui]type = "cli"
[agent]prompt = "Pipe text through stdin; redacted output to stdout."skill = "fantasma.md"
[[agent.modes]]flag = "--strict"description = "Treat any ambiguous match as PII."example = "echo 'call me at 555-1234' | wasmbox run fantasma -- --strict"
[agent.exit_codes]0 = "Success"1 = "Input error"</pre>
<h2 id="exit">Exit codes <a class="anchor" href="#exit">#</a></h2><table class="exit-table"> <thead><tr><th>Code</th><th>Meaning</th></tr></thead> <tbody> <tr><td><code>0</code></td><td>Success.</td></tr> <tr><td><code>1</code></td><td>General error: invalid args, malformed manifest, registry unreachable, IO failure.</td></tr> <tr><td><code>2</code></td><td>Permission denied: a required capability was missing and could not be prompted (non-TTY stdin without <code>--allow-all</code> or matching <code>--allow</code>).</td></tr> <tr><td><code>3</code></td><td>Hash verification failed: cached binary's SHA-256 does not match the manifest. Binary is not executed.</td></tr> </tbody></table>
<footer> <time datetime="2026-05-19T19:41:01Z">2026-05-19</time> · WasmBox · <code>f36febc</code></footer></body></html>