# Microsoft eXecution Container (MXC) MXC is a **sandboxed code execution system** for running untrusted code (model output, plugins, tools) on Windows, Linux, and macOS. It provides multiple containment backends — from OS-native process sandboxes to full VMs — behind a unified JSON configuration schema and TypeScript SDK. > [!WARNING] > This repository contains an early preview of code published to enable early integration and feedback from developers on Microsoft Execution Containers. The underlying sandboxes in this early preview are expected to change as they are under ongoing development however we will aim to minimize compatibility impact as functionality evolves. There are known cases where the current policies generated by the MXC SDK in this repository are overly permissive and will be addressed before this is made more generally available. Security researcher partnership while MXC matures is welcome, however no MXC profiles should be treated as security boundaries currently. ## Features - **Cross-platform**: Windows, Linux, and macOS support with platform-appropriate containment backends - **JSON-based Configuration**: Define execution parameters and security policies via a versioned JSON schema - **Multiple Containment Backends**: ProcessContainer, Windows Sandbox, LXC, Bubblewrap, Seatbelt (macOS), MicroVM (NanVix), Hyperlight, IsolationSession, and WSLC - **Policy-driven Sandboxing**: - **Filesystem Policy**: Read-only and read-write path lists (denied paths not yet supported on Windows) - **Network Policy**: Proxy support (cooperative on Linux/macOS), allow/block outbound, and backend-dependent host filtering - **UI Policy**: Clipboard, display, and GUI access controls - **State-aware Lifecycle**: Multi-step sandbox lifecycle (provision → start → exec → stop → deprovision) for session sandboxes - **TypeScript SDK**: [`@microsoft/mxc-sdk`](https://www.npmjs.com/package/@microsoft/mxc-sdk) npm package with one-shot and state-aware APIs - **Diagnostics**: Debug logging and Event Tracing for Windows (ETW) for troubleshooting ## Building MXC ships a native container wrapper plus a TypeScript SDK — see the [SDK README](./sdk/node/README.md) for full API documentation. ### Platforms | Platform | Default backend | Other backends | Minimum build | | --- | --- | --- | --- | | Windows 11 24H2+ (verified on 25H2) | `processcontainer` | `windows_sandbox`, `wslc`, `microvm`, `hyperlight`, `isolation_session` | `processcontainer`: 26100 (24H2)
`isolation_session`: 26340.9212 ([Insider Preview](https://learn.microsoft.com/en-us/windows-insider/release-notes/experimental/preview-build-26340-9212)) | | Linux x64 / ARM64 | `bubblewrap` | `lxc`, `microvm`, `hyperlight` | — | | macOS ARM64 / x64 (schema `0.7.0-alpha`+) | `seatbelt` | — | — | The stable one-shot backends (`processcontainer`, `bubblewrap`, `lxc`, `seatbelt`, `wslc`, and `isolation_session`) do not require experimental mode; Linux hosts also need the matching runtime installed: bwrap (Bubblewrap) for the default backend, or the lxc toolset for the lxc backend. **Experimental backends** (`windows_sandbox`, `microvm`, and `hyperlight`) require `{ experimental: true }` in `SandboxSpawnOptions` or the `--experimental` CLI flag. For which filesystem, network, and UI-restriction policy aspects the Windows `processcontainer` backend can enforce on each Windows 11 release (23H2 / 24H2 / 25H2 / 25H2+), see [Windows OS-version policy support](./docs/process-container/os-version-support.md). ### Requirements - [Rust toolchain](https://rustup.rs/) — version pinned to **1.93** via `src/rust-toolchain.toml` (auto-selected by `rustup`) - Node.js **≥ 24** (Windows requires **24.21.0+ within Node.js 24, or 26.8.0+**; **26.8.0+ is recommended**) - npm (for SDK and CLI builds) ### Project Structure ``` src/ Rust workspace (native binaries + shared library crates) sdk/ TypeScript SDK (@microsoft/mxc-sdk npm package) schemas/ JSON configuration schemas (stable + dev) docs/ Documentation (schema reference, backend guides, design docs) tests/ Test collateral (configs, examples, scripts) scripts/ Build and utility scripts ``` See [Repository architecture](docs/architecture.md) for the Rust workspace layout, crate responsibilities, dependency direction, and execution surfaces. ### Full Build #### Windows ```bash build.bat # Release build for current architecture build.bat --debug # Debug build build.bat --all # Release build for both x64 and ARM64 build.bat --with-microvm # Include NanVix micro-VM binaries ``` #### Linux ```bash ./build.sh # Release build ./build.sh --debug # Debug build ./build.sh --rust-only # Only Rust binaries, skip SDK/CLI ``` #### macOS ```bash ./build-mac.sh # Release build for native architecture ./build-mac.sh --all # Both Apple Silicon and Intel ./build-mac.sh --debug # Debug build ./build-mac.sh --rust-only # Only Rust binary, skip SDK ``` All build scripts: 1. Build the platform-appropriate Rust binary 2. Copy the binary into `sdk/node/bin//` (for example, `x64` or `arm64`) for SDK bundling 3. Build the TypeScript SDK ### Building Components Individually ```bash # Rust workspace (from src/) cargo build --release --target x86_64-pc-windows-msvc # Windows x64 cargo build --release --target aarch64-pc-windows-msvc # Windows ARM64 cargo build --release -p lxc # Linux — lxc-exec (serves both LXC and Bubblewrap) cargo build --release -p mxc_darwin --target aarch64-apple-darwin # macOS # SDK (from sdk/node/) npm install && npm run build ``` ### Lint and Format ```bash # Windows Rust (from src/) cargo clippy --workspace --all-targets -- -D warnings # Linux Rust (from src/; matches build.sh's platform-compatible crate set) cargo clippy -p lxc -p lxc_common -p wxc_common -p bwrap_common -p unix_test_proxy --all-targets -- -D warnings # macOS Rust (from src/) cargo clippy -p mxc_darwin -p seatbelt_common --all-targets -- -D warnings ``` ### Tests ```bash # Rust unit tests (from src/) cargo test --workspace cargo test -p wxc_common # Single crate cargo test -p wxc_common -- config_parser # Filter by test name # SDK (from sdk/node/) npm test # Unit tests npm run test:integration # Integration tests # E2E (from src/) cargo test -p wxc_e2e_tests ``` Host-dependent backend suites and their prerequisites are documented in [`tests/scripts/README.md`](tests/scripts/README.md). ## Usage MXC uses a JSON configuration to define execution parameters. See the [schema documentation](docs/schema.md) for full reference. ### Native Binary On Windows, `wxc-exec.exe --version` (or `-V`) prints the executor version and exits successfully without requiring a configuration file or starting a sandbox. ```bash # File path wxc-exec.exe config.json # Base64-encoded config wxc-exec.exe --config-base64 # Debug output wxc-exec.exe --debug config.json # Supply or replace process.commandLine from trailing arguments wxc-exec.exe config.json -- python --version ``` For `wxc-exec.exe`, arguments after the required `--` separator are rendered for the selected backend and spliced into `process.commandLine` before the request is parsed. They may supply a missing command or replace the policy's command. This form is supported for one-shot requests and state-aware `exec`; other state-aware phases reject it. A policy that relies on trailing arguments is a CLI template rather than a complete request that can be executed independently. On Linux: `./lxc-exec config.json` On macOS: `./mxc-exec-mac --experimental config.json` ### TypeScript SDK ```bash npm install @microsoft/mxc-sdk ``` ```typescript import { spawnSandboxFromConfig, createConfigFromPolicy, getAvailableToolsPolicy, getTemporaryFilesPolicy, getPlatformSupport, } from '@microsoft/mxc-sdk'; if (!getPlatformSupport().isSupported) { throw new Error('MXC not available on this host'); } const tools = getAvailableToolsPolicy(process.env); const temp = getTemporaryFilesPolicy(); const config = createConfigFromPolicy({ version: '0.6.0-alpha', filesystem: { readonlyPaths: tools.readonlyPaths, readwritePaths: temp.readwritePaths, }, network: { allowOutbound: false }, timeoutMs: 30_000, }); config.process!.commandLine = 'python -c "print(\'hello from sandbox\')"'; const child = spawnSandboxFromConfig(config, { usePty: false }); child.stdout!.on('data', (d) => process.stdout.write(d)); child.on('close', (code) => console.log('exit:', code)); ``` The SDK also provides a **state-aware lifecycle** API for long-lived sandboxes: ```typescript import { provisionSandbox, startSandbox, execInSandboxAsync, stopSandbox, deprovisionSandbox, } from '@microsoft/mxc-sdk'; ``` See the [SDK README](sdk/node/README.md) for full API documentation. ## Schema Versions Released, immutable stable schemas live in [`schemas/stable/`](schemas/stable); the in-progress dev schema (experimental backends, state-aware lifecycle) lives in [`schemas/dev/`](schemas/dev). The current stable and dev versions are tracked canonically in [`schemas/schema-version.json`](schemas/schema-version.json). Pick the latest stable schema for new code on any supported platform. See [docs/versioning.md](docs/versioning.md) for the full versioning design. ## Debugging ### Debug Console Mode By default, native binaries run in **silent mode** — stdin/stdout/stderr is coupled directly to the container. Use `--debug` for verbose output: ```bash wxc-exec.exe --debug config.json ``` See [docs/diagnostics.md](docs/diagnostics.md) for full diagnostics reference. ### Audit Mode (Permissive Learning Mode) `--audit` is a compatibility wrapper over `processContainer.captureDenials` in allow mode with ETL retention forced on. It injects `permissiveLearningMode`, so denied operations are recorded but allowed to proceed. On hosts with the complete PSEC/V2 Learning Mode API set, the selected ProcessContainer runner uses native capture without launching PLM or prompting for elevation. Older or policy-incompatible tiers use the guarded-WPR fallback: `wxc-exec.exe` remains unelevated and starts a session-scoped UAC-elevated PLM guardian only for the privileged WPR lifecycle, communicating over an authenticated local named pipe. It is rejected for Windows Sandbox, WSLC, IsolationSession, and every other containment backend. ```bash wxc-exec.exe --audit policy.json ``` Successful non-dry-run audits require capture metadata, actionable denials JSON, its verbose diagnostic sibling, and a retained ETL. The CLI relocates the backend-selected paths to `denials.json`, `denials.verbose.json`, and `trace.etl` in the per-user audit directory, then generates a source-config snapshot and `Adjusted_*.json` from the actionable JSON without decoding the ETL again. Base64-only input keeps both JSON files and the ETL but has no source config to snapshot or adjust. Truncated analysis keeps both JSON files, the ETL, and the source snapshot but skips adjusted-config generation. Use `--audit-verbose` to print learned-policy details. > **Warning:** `--audit` injects `permissiveLearningMode` — AppContainer restrictions are **not** enforced for the duration of the run. Use only for policy authoring. It cannot be combined with `processContainer.captureDenials`; use `captureDenials.mode: "allow"` for permissive application-driven capture. `learningModeLogging` and `permissiveLearningMode` are reserved internal capability names and are rejected in `processContainer.capabilities`. See [docs/learning-mode/capabilities.md](docs/learning-mode/capabilities.md) for the three learning-mode flows. ## Telemetry MXC supports optional TraceLogging ETW telemetry for execution observability. When enabled, structured events (`MXC.Execution`, `MXC.Error`, and the sanitized Learning Mode artifact event `MXC.VerboseDenials`) are emitted by the `Microsoft.MXC` provider to the local ETW subsystem via the Rust [`tracelogging`](https://crates.io/crates/tracelogging) crate. Every event includes common fields (Version, Channel, IsDebugging, `UTCReplace_AppSessionGuid`) as Part C custom event data. Telemetry requires: 1. Top-level `"telemetry": { "enabled": true }` in the JSON config 2. Explicit per-user telemetry consent on Windows 3. An administrative policy that permits collection, when a policy is configured The configuration flag is an additional per-run opt-in; it cannot grant consent or bypass an administrative block. Telemetry remains off unless every applicable gate is open. MXC does not use the Windows Diagnostics & feedback setting as a substitute for application consent. On non-Windows platforms, all telemetry functions are no-ops. ### Data Collection The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft's privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. #### How to turn telemetry off Telemetry is **off by default**. To keep it off, do not set `"telemetry": { "enabled": true }` for the run. If telemetry is enabled in config, collection still does not occur unless Windows user consent is granted and administrative policy allows collection. #### What official builds send Official/shipped Microsoft builds set a TraceLogging provider group GUID at build time and route `MXC.Execution`, `MXC.Error`, and `MXC.VerboseDenials` events to Microsoft through the UTC pipeline when telemetry is enabled — that same build-time setting also selects the correct Measures keyword and Product-and-Service-Usage privacy tag for the events, so telemetry routing and event classification always agree. **Local and open-source builds send nothing to Microsoft by default** — the public source ships without a provider group GUID, so events are emitted to the local ETW subsystem only, use a provider-local keyword with no UTC meaning, and carry no privacy classification tag, and are not routed to any Microsoft collection pipeline. Internal builds that set the `MXC_TELEMETRY_PROVIDER_GROUP_GUID` environment variable at build time enable the Microsoft-routed path. No PII is collected. Execution/error events contain only execution metrics (duration, backend type, exit code) and a bounded error category (`error_type`). When a ProcessContainer run successfully produces a Learning Mode verbose artifact, `MXC.VerboseDenials` can include sanitized provider/event identifiers, process IDs, closed outcome reasons, access/resource classifications, occurrence counts, and truncation state. The telemetry projection derives provider GUIDs from a closed provider enum and drops all verbose property names and values. MXC never emits commands, credentials, complete file paths, usernames, workload-derived properties, sandbox output, raw ETL, actionable denial documents, general logger text, or free-form error text. The verbose-event data inventory requires explicit privacy/release review before shipment. If you use the SDK to build applications, you are responsible for providing appropriate telemetry notices to your own users. Privacy information can be found at https://privacy.microsoft.com and in the Microsoft privacy statement at https://go.microsoft.com/fwlink/?LinkID=824704. ## Documentation | Document | Description | |----------|-------------| | [docs/architecture.md](docs/architecture.md) | Repository layout, crate boundaries, and execution surfaces | | [docs/schema.md](docs/schema.md) | Full JSON configuration schema reference | | [docs/versioning.md](docs/versioning.md) | Schema versioning and experimental feature lifecycle | | [docs/examples.md](docs/examples.md) | Annotated configuration examples | | [docs/ci-validation-infrastructure.md](docs/ci-validation-infrastructure.md) | Scheduled backend validation matrix and CI dispatch | | [tests/scripts/README.md](tests/scripts/README.md) | Local and CI backend test suites | | [docs/host-prep.md](docs/host-prep.md) | Windows host preparation (`wxc-host-prep.exe`) | | [docs/diagnostics.md](docs/diagnostics.md) | Diagnostic logging and ETW | | [docs/sandbox-policy/0.7.0/policy.md](docs/sandbox-policy/0.7.0/policy.md) | Sandbox policy 0.7.0 specification | | [docs/process-container/guide.md](docs/process-container/guide.md) | Windows AppContainer / BaseContainer guide | | [docs/lxc-support/lxc-backend.md](docs/lxc-support/lxc-backend.md) | LXC backend (Linux) | | [docs/bwrap-support/bubblewrap-backend.md](docs/bwrap-support/bubblewrap-backend.md) | Bubblewrap backend (Linux) | | [docs/seatbelt/seatbelt-backend.md](docs/seatbelt/seatbelt-backend.md) | Seatbelt backend (macOS) | | [docs/windows-sandbox/windows-sandbox.md](docs/windows-sandbox/windows-sandbox.md) | Windows Sandbox backend | | [docs/hyperlight/hyperlight-backend.md](docs/hyperlight/hyperlight-backend.md) | Hyperlight backend (Linux, Windows) | | [docs/state-aware-lifecycle/mxc-state-aware-sandbox-api.md](docs/state-aware-lifecycle/mxc-state-aware-sandbox-api.md) | State-aware sandbox lifecycle API | | [docs/telemetry/telemetry.md](docs/telemetry/telemetry.md) | TraceLogging telemetry architecture | | [docs/telemetry/telemetry-consent-design.md](docs/telemetry/telemetry-consent-design.md) | Telemetry consent contract | | [docs/telemetry/telemetry-administrative-policy.md](docs/telemetry/telemetry-administrative-policy.md) | Administrative telemetry controls | ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. ## License See [LICENSE.md](LICENSE.md) for details.