Microsoft MXC: a policy-driven sandbox runner for untrusted code
Policy-driven, layered isolation and containment
At a glance
- What is it?
- MXC wraps OS-native sandboxes and micro-VMs behind one JSON schema and a TypeScript SDK. The repository calls itself an early preview, and its own README says no MXC profile should be treated as a security boundary yet.
- Who is it for?
- Adopt MXC if you need to run model output, plugins or tool calls on Windows, Linux or macOS and you want one JSON policy schema plus a TypeScript SDK instead of three platform-specific integrations.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What MXC is for, and who ends up using it
MXC, short for Microsoft eXecution Container, runs code you do not trust. The README names the audience directly: model output, plugins and tools. That is a narrower brief than a general container runtime. Docker and Podman assume you own the image and the workload; MXC assumes the workload is hostile or at least unknown, and that the caller wants to describe the allowed surface in a config file rather than hand-write a sandbox invocation per platform.
The practical user is an application developer embedding an agent or a plugin host. They have a string of code from a model, or a third-party tool bundle, and they need it to touch a scratch directory and nothing else. MXC gives them a versioned JSON schema for that, a native binary to execute it, and a TypeScript SDK to drive it from Node. The Rust workspace underneath is an implementation detail unless you are building a backend.
One caveat shapes everything else. The README carries a warning that this is an early preview, that the underlying sandboxes are under ongoing development, and that there are known cases where policies generated by the MXC SDK are overly permissive. It also states that no MXC profiles should be treated as security boundaries currently. Treat MXC as a containment layer you are evaluating, not one you are relying on.
One schema, many backends: how containment is actually wired
The architecture is a dispatcher over platform-native isolation primitives. You write one JSON document describing filesystem paths, network behaviour and UI access. MXC picks a backend for your platform and translates that document into whatever the backend understands.
The backend list is the clearest statement of intent. Windows has processcontainer as the default, with windows_sandbox, wslc, microvm, hyperlight and isolation_session as alternatives. Linux defaults to bubblewrap, with lxc, microvm and hyperlight available. macOS uses seatbelt, and the platform table notes that macOS support requires schema 0.7.0-alpha or later. The spread runs from OS-native process sandboxes up to full VMs, which is why the same policy document can mean very different things depending on which backend executes it.
Policy is split into three groups. Filesystem policy is read-only and read-write path lists, and the README notes that denied paths are not yet supported on Windows. Network policy covers proxy support (described as cooperative on Linux and macOS), allow or block outbound, and host filtering that depends on the backend. UI policy covers clipboard, display and GUI access. The word cooperative matters: a proxy-based network control assumes the code inside the sandbox chooses to honour it.
Lifecycle is the other axis. One-shot backends run and exit. Session backends follow provision, start, exec, stop, deprovision, which is what the state-aware API in the SDK exists for.
Installing MXC and running a first sandbox
The README does not publish a prebuilt installer. You build from source. The requirements are a Rust toolchain pinned to 1.93 via src/rust-toolchain.toml (rustup selects it automatically), Node.js 18 or newer, and npm. Clone the repository and run the platform build script.
On Linux, build.sh produces a release build and copies the Rust binary into sdk/node/bin/<arch>/ for SDK bundling:
./build.sh
./build.sh --debug
./build.sh --rust-onlyThe Windows equivalent is build.bat, and macOS uses build-mac.sh. All three follow the same three steps: build the platform Rust binary, copy it into sdk/node/bin/<arch>/, then build the TypeScript SDK. If you only want the Rust binaries, --rust-only skips the SDK and CLI.
Linux hosts also need the runtime for the backend you choose. The README states that bwrap (Bubblewrap) is required for the default backend, or the lxc toolset for the lxc backend. Without the matching runtime installed, the backend has nothing to delegate to.
For the SDK, install the npm package and import the helpers:
npm install @microsoft/mxc-sdkimport {
spawnSandboxFromConfig, createConfigFromPolicy,
getAvailableToolsPolicy, getTemporaryFilesPolicy,
getPlatformSupport,
} from '@microsoft/mxc-sdk';
if (!getPlatformSupport().isSupported) {
throw new Error('MXC not available on this host');
}The README gives this import block as the entry point. The pattern it shows is to check getPlatformSupport().isSupported before anything else, then build a config from policy helpers such as getTemporaryFilesPolicy and getAvailableToolsPolicy, or load a config file and pass it to spawnSandboxFromConfig. The truncated README does not show the full spawn call, so read sdk/node/README.md for the complete API before wiring it in.
From the command line, the native binary takes a config file path, a base64-encoded config, or a debug flag:
wxc-exec.exe config.json
wxc-exec.exe --config-base64 <base64-encoded-json>
wxc-exec.exe --debug config.jsonOn Linux the binary is ./lxc-exec config.json. On macOS it is ./mxc-exec-mac --experimental config.json. Note the --experimental flag in that macOS line: experimental backends (windows_sandbox, wslc, microvm, isolation_session, hyperlight) require either { experimental: true } in SandboxSpawnOptions or the --experimental CLI flag.
Where MXC will disappoint you
Start with the README's own warning. It says there are known cases where policies generated by the MXC SDK are overly permissive, that these will be addressed before wider availability, and that no MXC profiles should be treated as security boundaries currently. That is the project telling you its policy layer is not yet trustworthy as a hard boundary. If your threat model requires a boundary you can defend in review, MXC in its current state is the wrong tool.
Policy coverage is uneven by platform. Denied paths are not supported on Windows at all, so a filesystem policy that blocks a path on Linux may not block it there. Network proxy support is cooperative on Linux and macOS, which means it depends on the sandboxed code cooperating. Host filtering is backend-dependent. The repository points to docs/process-container/os-version-support.md for the matrix of which policy aspects the Windows processcontainer backend can enforce on each Windows 11 release, and that document exists precisely because the answer varies by build.
Version floors are real constraints. processcontainer needs Windows 11 build 26100 (24H2) or later, and isolation_session needs build 26340.9212 from an Insider Preview. On Linux, picking the lxc backend means installing the lxc toolset rather than relying on bwrap. macOS support carries a schema floor of 0.7.0-alpha.
The compatibility promise is also soft. The README says the sandboxes in this early preview are expected to change and that the team will aim to minimize compatibility impact as functionality evolves. Aim is not a guarantee. Pin a release tag if you build on this.
How MXC differs from running Bubblewrap or Docker yourself
The obvious alternative on Linux is calling bwrap directly. MXC's default Linux backend is Bubblewrap, so the isolation primitive is the same; the difference is that you get a JSON policy document and a TypeScript API instead of assembling bwrap flags per call site. If your application only ever runs on Linux and you already have a bwrap invocation you trust, MXC adds a schema layer and a Node dependency without adding isolation. That is a fair reason to skip it.
Against Docker, the difference is the trust model and the surface. Docker sandboxes a workload you built; MXC sandboxes code you did not write and cannot inspect, and its policy vocabulary is built around that (read-only versus read-write paths, outbound allow or block, clipboard and display controls). Docker's model is a container image plus a runtime; MXC's is a per-invocation policy plus a backend chosen by platform. Docker also gives you a registry, networking and orchestration story that MXC does not attempt.
The place MXC is genuinely doing something else is the micro-VM backends. microvm (NanVix) and hyperlight sit alongside the process sandboxes behind the same schema, so a caller can move from a process sandbox to a VM-backed one without rewriting the policy document. That portability is the argument for the abstraction. Whether it holds up across all nine backends is exactly what the early-preview warning leaves open.
Maintenance, versioning and what the MIT licence leaves you
The last push to main was on 2026-08-22, the same day v0.8.0 (MXC SDK v0.8.0) was released. Before that came v0.7.0-rc1 on 2026-06-13 and v0.6.1 on 2026-06-02. The cadence is recent and the version numbers are still in the 0.x range, which matches the preview framing in the README: the schema is versioned, and the macOS support note ties a feature to schema 0.7.0-alpha, so schema versions are part of the contract you are coding against.
Upgrade cost is the thing to budget for. Every backend is described as under ongoing development, and the README says compatibility impact will be minimized rather than avoided. A version bump can change which policy fields a backend enforces, which is the kind of change that only shows up when a path you thought was blocked is not. Pin the SDK version and re-run your policy tests on upgrade.
The repository is MIT licensed. That is permissive and places few conditions on redistribution or modification. It says nothing about the security properties of the code, and this project in particular ships with an explicit statement that its profiles are not security boundaries. Read LICENSE.md for the actual terms; nothing here is legal advice.
Editorial conclusion
Adopt MXC if you need to run model output, plugins or tool calls on Windows, Linux or macOS and you want one JSON policy schema plus a TypeScript SDK instead of three platform-specific integrations. Do not adopt it as a security boundary, and do not ship it to production on the strength of the containment backend names alone: the README states that current policies generated by the SDK are in known cases overly permissive and that no MXC profile should be treated as a security boundary. Verify first that your host meets the backend minimums (Windows 11 24H2 build 26100 for processcontainer, build 26340.9212 for isolation_session, bwrap or the lxc toolset on Linux), that the experimental flag is required for any backend you plan to use, and that the policy aspects you depend on are actually enforced on your OS release, since the repository points to docs/process-container/os-version-support.md for exactly that question.
Frequently asked questions
What is Microsoft MXC?
MXC (Microsoft eXecution Container) is a sandboxed code execution system for running untrusted code such as model output, plugins and tools on Windows, Linux and macOS. It puts multiple containment backends behind a unified JSON configuration schema and a TypeScript SDK.
Which containment backends does Microsoft MXC support?
The README lists ProcessContainer, Windows Sandbox, LXC, Bubblewrap, Seatbelt (macOS), MicroVM (NanVix), Hyperlight, IsolationSession and WSLC. Windows defaults to processcontainer, Linux to bubblewrap, and macOS to seatbelt.
Does Microsoft MXC require a specific Rust or Node version?
Yes. The Rust toolchain is pinned to 1.93 via src/rust-toolchain.toml and rustup selects it automatically, and Node.js 18 or newer is required, with npm for the SDK and CLI builds.
Is Microsoft MXC safe to use as a security boundary?
No. The README states that there are known cases where the current policies generated by the MXC SDK are overly permissive and that no MXC profiles should be treated as security boundaries currently.
How do I install the Microsoft MXC SDK?
The SDK is published as @microsoft/mxc-sdk on npm. Building from source requires running build.bat on Windows, build.sh on Linux or build-mac.sh on macOS, which builds the Rust binary, copies it into sdk/node/bin/<arch>/ and then builds the TypeScript SDK.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/microsoft-mxc)