{"id":29419894,"url":"https://github.com/bytecodealliance/wasi-virt","last_synced_at":"2025-07-12T01:13:22.777Z","repository":{"id":179506663,"uuid":"656262216","full_name":"bytecodealliance/WASI-Virt","owner":"bytecodealliance","description":"Virtual implementations of WASI APIs","archived":false,"fork":false,"pushed_at":"2025-06-28T01:22:40.000Z","size":2231,"stargazers_count":184,"open_issues_count":9,"forks_count":20,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-06-28T01:31:41.287Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bytecodealliance.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-06-20T15:24:47.000Z","updated_at":"2025-06-28T01:22:42.000Z","dependencies_parsed_at":"2023-10-17T03:03:44.001Z","dependency_job_id":"db2f6033-51af-45ad-ac99-828475162db9","html_url":"https://github.com/bytecodealliance/WASI-Virt","commit_stats":null,"previous_names":["bytecodealliance/wasi-virt"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bytecodealliance/WASI-Virt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FWASI-Virt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FWASI-Virt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FWASI-Virt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FWASI-Virt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bytecodealliance","download_url":"https://codeload.github.com/bytecodealliance/WASI-Virt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bytecodealliance%2FWASI-Virt/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264922908,"owners_count":23683705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-12T01:13:19.844Z","updated_at":"2025-07-12T01:13:22.755Z","avatar_url":"https://github.com/bytecodealliance.png","language":"Rust","readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003e\u003ccode\u003eWASI Virt\u003c/code\u003e\u003c/h1\u003e\n\n  \u003cp\u003e\n    \u003cstrong\u003eVirtualization Component Generator for WASI Preview 2\u003c/strong\u003e\n  \u003c/p\u003e\n\n  \u003cstrong\u003eA \u003ca href=\"https://bytecodealliance.org/\"\u003eBytecode Alliance\u003c/a\u003e project\u003c/strong\u003e\n\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/bytecodealliance/wasi-virt/actions?query=workflow%3ACI\"\u003e\u003cimg src=\"https://github.com/bytecodealliance/wasi-virt/workflows/CI/badge.svg\" alt=\"build status\" /\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\nThe virtualized component can be composed into a WASI Preview2 component with `wasm-tools compose`, providing fully-configurable WASI virtualization with host pass through or full encapsulation as needed.\n\nSupports all of the current WASI subsystems:\n\n- [Clocks](#clocks): Allow / Deny\n- [Environment](#env): Set environment variables, configure host environment variable permissions\n- [Config](#config): Set configuration, configure host property permissions\n- [Exit](#exit): Allow / Deny\n- [Filesystem](#filesystem): Mount a read-only filesystem, configure host filesystem preopen remappings or pass-through.\n- [HTTP](#http): Allow / Deny\n- [Random](#random): Allow / Deny\n- [Sockets](#sockets): Allow / Deny\n- [Stdio](#stdio): Allow / Deny / Ignore\n\nWhile current virtualization support is limited, the goal for this project is to support a wide range of WASI virtualization configuration use cases.\n\nHave an unhandled use case? Post a virtualization [suggestion](https://github.com/bytecodealliance/WASI-Virt/issues/new).\n\n## Explainer\n\nWhen wanting to run WebAssembly Components depending on WASI APIs in other environments it can provide a point of friction having to port WASI interop to every target platform.\n\nIn addition having full unrestricted access to core operating system APIs is a security concern.\n\nWASI Virt allows taking a component that depends on WASI APIs and using a virtualized adapter to convert it into a component that no longer depends on those WASI APIs, or conditionally only depends on them in a configurable way.\n\nFor example, consider converting an application to a WebAssembly Component that assumes it can load read some files from the filesystem, but never needs to write.\n\nUsing WASI Virt, those specific file paths can be mounted and virtualized into the component itself as a post-compile operation, while banning the final component from being able to access the host's filesystem at all. The inner program still imports a wasi filesystem, but the filesystem implementation is provided by another component, rather than in the host environment. The composition of these two components no longer has a filesystem import, so it can be run in hosts (or other components) which do not provide a filesystem API.\n\n## Basic Usage\n\n```sh\ncargo install --git https://github.com/bytecodealliance/wasi-virt\n```\n\n```sh\n# Encapsulating a component\nwasi-virt component.wasm -o virt.wasm\n```\n\nBy default the virtualization will deny all subsystems, and will panic on any attempt to use any subsystem.\n\nIn all of the examples, the `component.wasm` is the component being virtualized and `virt.wasm` the output component with its virtualization. The `component.wasm` argument is optional. If omitted, then the virtualized adapter is output into `virt.wasm`, which can be composed into any arbitrary component with:\n\n```sh\nwasm-tools compose component.wasm -d virt.wasm -o component.virt.wasm\n```\n\nConfiguring a subsystem virtualization will enable it, or subsystems can be fully enabled via `--allow-fs`, `--allow-env` etc by subsystem. Allowing all subsystems can be achieved with `--allow-all`.\n\n### Clocks\n\n```sh\n# Create a component which just allows clocks, but no other interfaces\nwasi-virt component.wasm --allow-clocks -o virt.wasm\n```\n\n### Env\n\n```sh\n# Setting specific env vars (while disallowing all host env var access):\nwasi-virt component.wasm -e CUSTOM=VAR -o virt.wasm\n\n# Setting env vars with all host env vars allowed:\nwasi-virt component.wasm -e CUSTOM=VAR --allow-env -o virt.wasm\n\n# Setting env vars with restricted host env var access:\nwasi-virt component.wasm -e CUSTOM=VAR --allow-env=SOME,ENV_VARS -o virt.wasm\n```\n\n### Config\n\n_experimental_\n\n```sh\n# Setting specific config properties (while disallowing all host config property access):\nwasi-virt component.wasm -c custom=prop -o virt.wasm\n\n# Setting config properties with all host config properties allowed:\nwasi-virt component.wasm -c custom=prop --allow-config -o virt.wasm\n\n# Setting config properties with restricted host config property access:\nwasi-virt component.wasm -c custom=prop --allow-config=some,property -o virt.wasm\n```\n\n### Exit\n\n```sh\n# Create a component which is allowed to exit (terminate execution without a panic and unwind)\nwasi-virt component.wasm --allow-exit -o virt.wasm\n```\n\n### Filesystem\n\n```sh\n# Mounting a virtual directory\n# (Globs all files in local-dir and virtualizes them)\nwasi-virt component.wasm --mount /=./local-dir -o virt.wasm\n\n# Providing a host preopen mapping\nwasi-virt component.wasm --preopen /=/restricted/path -o virt.wasm\n\n# Providing both host and virtual preopens\nwasi-virt component.wasm --mount /virt-dir=./local --preopen /host-dir=/host/path -o virt.wasm\n```\n\n### HTTP\n\n```sh\n# Allow HTTP\nwasi-virt component.wasm --allow-http -o virt.wasm\n```\n\n### Random\n\n```sh\n# Allow random number generation\nwasi-virt component.wasm --allow-random -o virt.wasm\n```\n\n### Sockets\n\n```sh\n# Allow socket APIs\nwasi-virt component.wasm --allow-sockets -o virt.wasm\n```\n\n### Stdio\n\n```sh\n# Ignore all stdio entirely\nwasi-virt component.wasm --stdio=ignore -o virt.wasm\n\n# Throw an error if attempting any stdio\n# (this is the default)\nwasi-virt component.wasm --stdio=deny -o virt.wasm\n\n# Configure stderr / stdout / stdin individually\nwasi-virt component.wasm --stderr=allow -o virt.wasm\n```\n\n### Debugging\n\nThe `--debug` flag can be used to get tracing output of system calls.\n\n## API\n\nWhen using the virtualization API, subsystems are passthrough by default instead of deny by default.\n\n```rs\nuse std::fs;\nuse wasi_virt::{WasiVirt, FsEntry};\n\nfn main() {\n    let mut virt = WasiVirt::new();\n\n    // allow all subsystems initially\n    virt.allow_all();\n\n    // ignore stdio\n    virt.stdio().ignore();\n\n    virt.env()\n      // provide an allow list of host env vars\n      .allow(\u0026[\"PUBLIC_ENV_VAR\"])\n      // provide custom env overrides\n      .overrides(\u0026[(\"SOME\", \"ENV\"), (\"VAR\", \"OVERRIDES\")]);\n\n    virt.fs()\n        // deny arbitrary host preopens\n        .deny_host_preopens()\n        // mount and virtualize a local directory recursively\n        .virtual_preopen(\"/dir\", \"/local/dir\")\n        // create a virtual directory containing some virtual files\n        .preopen(\"/another-dir\", FsEntry::Dir(BTreeMap::from([\n          // create a virtual file from the given UTF8 source\n          (\"file.txt\", FsEntry::Source(\"Hello world\")),\n          // create a virtual file read from a local file at\n          // virtualization time\n          (\"another.wasm\", FsEntry::Virtualize(\"/local/another.wasm\"))\n          // create a virtual file which reads from a given file\n          // path at runtime using the runtime host filesystem API\n          (\"host.txt\", FsEntry::RuntimeFile(\"/runtime/host/path.txt\"))\n        ])));\n\n    // compose the virtualization with a component\n    virt.compose(\"path/to/component.wasm\");\n    // filter enabled subsystems by imports on the composed component\n    virt.filter_imports().unwrap();\n\n    let virt_component_bytes = virt.finish().unwrap();\n    fs::write(\"virt.component.wasm\", virt_component_bytes).unwrap();\n}\n```\n\nWhen calling a subsystem for the first time, its virtualization will be enabled. Subsystems not used or configured at all will be omitted from the virtualization entirely.\n\n### Selective Subsystem Virtualization\n\nBy default, when using the `wasi-virt` CLI command, all virtualizations are enabled. This way, not only is encapsulation the default, but composition with arbitrary components will always work out as all interfaces for WASI should always be available.\n\nSelective subsystem virtualization can be performed directly with the WASI Virt library as above (which does not virtualize all subsystems by default). This allows virtualizing just a single subsystem like `env`, where it is possible to virtualize only that subsystem and skip other virtualizations and end up creating a smaller virtualization component.\n\nWhen directly composing another component, individual subsystems are disabled if the composed component does not import that subsystem. This behavior reduces imports in the output component that are never actually used.\n\nThere is an important caveat to this: _as soon as any subsystem uses IO, all subsystems using IO need to be virtualized in order to fully subclass streams and polls in the virtualization layer_. In future this caveat requirement should weaken as these features lower into the core ABI in subsequent WASI versions.\n\n`wasm-tools compose` will error in these scenarios, and better [error messaging](https://github.com/bytecodealliance/wasm-tools/issues/1147) may be provided in future when performing invalid compositions like the above. Missing subsystems can be usually detected from the composition warnings list.\n\n## Contributing\n\n\u003e [!NOTE]\n\u003e You may need to install the `wasm32-wasip1` target if not already added (`rustup target add wasm32-wasip1`).\n\nTo build, run `./build-adapter.sh` which builds the master `virtual-adapter` component, followed by `cargo build` to build\nthe virtualization tooling (located in `src`).\n\nTests can be run with `cargo test`, which runs the tests in `tests/virt.rs`.\n\nTest components are built from the `tests/components` directory, and run against the configurations provided in `tests/cases`.\n\nTo update WASI, `lib/wasi_snapshot_preview1.reactor.wasm` needs\nto be updated to the latest Wasmtime build, and the `wit/deps` folder needs to be updated with the latest WASI definitions.\n\n# License\n\nThis project is licensed under the Apache 2.0 license with the LLVM exception.\nSee [LICENSE](LICENSE) for more details.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this project by you, as defined in the Apache-2.0 license,\nshall be licensed as above, without any additional terms or conditions.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytecodealliance%2Fwasi-virt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbytecodealliance%2Fwasi-virt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytecodealliance%2Fwasi-virt/lists"}