# How to Configure Filesystem Policies in MXC: A Complete Developer Guide

> Configure MXC filesystem policies by defining SandboxPolicy objects with readwrite, readonly, and denied paths. Learn how to use spawnSandbox and createConfigFromPolicy for secure container execution.

- Repository: [Microsoft/mxc](https://github.com/microsoft/mxc)
- Tags: how-to-guide
- Published: 2026-06-07

---

**To configure filesystem policies in MXC, define a `SandboxPolicy` object with `readwritePaths`, `readonlyPaths`, and optional `deniedPaths`, then pass it to `spawnSandbox()`; the SDK translates this into a `ContainerConfig` via `createConfigFromPolicy` in [`sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sandbox.ts) (lines 70-78) that the native `wxc-exec` executor enforces using OS-level isolation primitives.**

Microsoft MXC provides a secure sandbox environment where filesystem access is explicitly granted through policy declarations rather than inherited from the host. Configuring filesystem policies correctly ensures your sandboxed scripts can access necessary tools and directories while maintaining strict security boundaries. This article explains the architecture, implementation details found in [`sdk/src/types.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/types.ts) and [`sdk/src/sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/sandbox.ts), and practical code patterns for defining filesystem restrictions in the Microsoft MXC repository.

## Understanding the Filesystem Policy Architecture

The MXC SDK controls filesystem access through a declarative policy object that travels from the TypeScript API to the native executor. According to the Microsoft MXC source code, the journey begins with `SandboxPolicy.filesystem` defined in [`sdk/src/types.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/types.ts) (lines 96-104), which specifies exactly which directories the sandbox may read, write, or must avoid.

When `spawnSandbox()` is invoked, the SDK transforms this high-level policy into a concrete `ContainerConfig` via the `createConfigFromPolicy` function in [`sdk/src/sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/sandbox.ts) (lines 70-78). This translation layer merges user-defined paths with automatically discovered host resources before passing the configuration to the `wxc-exec` binary. The native executor then implements the actual restrictions using platform-specific primitives such as bind mounts on Linux or BFS (Windows Sandbox) APIs on Windows.

### Key Source Files in the Policy Chain

- **[`sdk/src/types.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/types.ts)**: Declares the `SandboxPolicy` interface and `FilesystemConfig` shape (lines 94-108).
- **[`sdk/src/sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/sandbox.ts)**: Contains `createConfigFromPolicy` that maps policies to container configurations (lines 70-78) and backend-specific handling for microVMs (lines 84-96).
- **[`sdk/src/policy.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/policy.ts)**: Provides environment discovery helpers that scan `PATH` and user directories, returning `FilesystemPolicyResult` objects (lines 23-28).

## Defining Core Filesystem Restrictions

At the heart of MXC’s security model is the `filesystem` property on the `SandboxPolicy` interface. As implemented in [`types.ts`](https://github.com/microsoft/mxc/blob/main/types.ts), this object requires a version string (typically `"0.5.0-alpha"`) and accepts four key arrays that define the sandbox boundary:

```typescript
import { SandboxPolicy } from "mxc/sdk";

const policy: SandboxPolicy = {
  version: "0.5.0-alpha",
  filesystem: {
    readwritePaths: ["/tmp/mxc-workspace"],  // Writable directories
    readonlyPaths: ["/usr", "/bin"],        // Read-only system access
    deniedPaths: ["/etc/secrets"],          // Explicitly blocked paths
    clearPolicyOnExit: true                 // Cleanup after execution
  }
};

```

The `clearPolicyOnExit` boolean determines whether the executor removes policy remnants after the sandbox terminates. This is particularly important for temporary directories and microVM backend configurations where you may want persistent state across invocations.

## Translating Policy to Container Configuration

The bridge between your TypeScript policy and the native executor occurs in `createConfigFromPolicy` within [`sdk/src/sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/sandbox.ts). This function copies the `filesystem` fields from your `SandboxPolicy` into a new `ContainerConfig.filesystem` object, handling default values and merging with other policy fragments such as tool discovery results.

For the **microVM backend** (Windows only), the translation logic at lines 84-96 applies additional constraints: the SDK injects a minimal filesystem block only when specific paths are present, ensuring the lightweight virtual machine receives only the necessary mount points rather than the full host filesystem view.

## Auto-Discovering Host Paths with Policy Helpers

Rather than hard-coding system paths that vary across environments, MXC provides three discovery functions in [`sdk/src/policy.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/policy.ts) that return `FilesystemPolicyResult` objects:

- **`getAvailableToolsPolicy()`**: Scans `PATH` and environment variables (`PYTHONPATH`, `NODE_PATH`, `VCINSTALLDIR`) to identify tool directories, filtering out system-critical locations and paths already accessible through Windows ACLs.
- **`getUserProfilePolicy()`**: Locates per-user installation directories such as `%LOCALAPPDATA%\Programs` on Windows or `~/.local/bin` and `~/.local/lib` on Linux.
- **`getTemporaryFilesPolicy()`**: Identifies writable temporary directories from `TEMP`, `TMP`, or `TMPDIR` environment variables.

These helpers return objects with `readwritePaths` and `readonlyPaths` arrays that can be spread into your `SandboxPolicy`:

```typescript
import { 
  getAvailableToolsPolicy, 
  getUserProfilePolicy, 
  getTemporaryFilesPolicy 
} from "mxc/sdk";

const toolPolicy = getAvailableToolsPolicy();
const userPolicy = getUserProfilePolicy();
const tempPolicy = getTemporaryFilesPolicy();

const policy: SandboxPolicy = {
  version: "0.5.0-alpha",
  filesystem: {
    readwritePaths: [...tempPolicy.readwritePaths],
    readonlyPaths: [
      ...toolPolicy.readonlyPaths, 
      ...userPolicy.readonlyPaths
    ],
    clearPolicyOnExit: true
  }
};

```

## Practical Implementation Examples

The following patterns demonstrate how to configure filesystem policies in MXC for common scenarios.

### Simple Sandbox with a Single Writable Folder

For scripts that need minimal filesystem access, explicitly define read-write and read-only paths:

```typescript
import { spawnSandbox, SandboxPolicy } from "mxc/sdk";

const policy: SandboxPolicy = {
  version: "0.5.0-alpha",
  filesystem: {
    readwritePaths: ["/tmp/mxc-workspace"],
    readonlyPaths: ["/usr"]
  }
};

await spawnSandbox(
  "python - <<'PY'\nimport os\nprint(os.listdir('/tmp/mxc-workspace'))\nPY",
  policy
);

```

The executor mounts `/tmp/mxc-workspace` as a writable bind mount while restricting all other filesystem access.

### Dynamic Tool Discovery for Development Environments

When you cannot predict where tools are installed, combine the discovery helpers to grant read-only access to the host's toolchains while keeping writes isolated to a temporary directory:

```typescript
const tools = getAvailableToolsPolicy();
const user = getUserProfilePolicy();
const temp = getTemporaryFilesPolicy();

const policy: SandboxPolicy = {
  version: "0.5.0-alpha",
  filesystem: {
    readwritePaths: temp.readwritePaths,
    readonlyPaths: [...tools.readonlyPaths, ...user.readonlyPaths]
  }
};

await spawnSandbox("node -e \"console.log('Hello from sandbox')\"", policy);

```

### Configuring the MicroVM Backend

For Windows microVM isolation, pass the `microvm` backend parameter and optionally persist the policy across executions:

```typescript
const policy: SandboxPolicy = {
  version: "0.5.0-alpha",
  filesystem: {
    readwritePaths: ["C:\\Temp\\MicroVM"],
    clearPolicyOnExit: false
  }
};

await spawnSandbox(
  "cmd /c echo hello", 
  policy, 
  { experimental: true }, 
  undefined, 
  undefined, 
  "microvm"
);

```

In this mode, [`sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sandbox.ts) (lines 84-96) ensures the filesystem configuration is only emitted when paths are explicitly defined, optimizing the microVM startup time.

## Summary

- **Define** filesystem boundaries using `SandboxPolicy.filesystem` with explicit `readwritePaths`, `readonlyPaths`, and optional `deniedPaths`.
- **Translate** high-level policies into executor-ready configurations via `createConfigFromPolicy` in [`sdk/src/sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/sandbox.ts) (lines 70-78).
- **Discover** portable paths using helpers from [`sdk/src/policy.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/policy.ts): `getAvailableToolsPolicy()`, `getUserProfilePolicy()`, and `getTemporaryFilesPolicy()`.
- **Optimize** microVM deployments by noting that [`sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sandbox.ts) lines 84-96 only inject filesystem blocks when paths are present.
- **Clean up** resources by setting `clearPolicyOnExit: true` unless you need persistent state across sandbox invocations.

## Frequently Asked Questions

### What is the difference between `readwritePaths` and `readonlyPaths` in MXC?

`readwritePaths` grants the sandboxed process full read and write access to specified directories, while `readonlyPaths` restricts the process to read-only operations. The native `wxc-exec` executor enforces these restrictions using OS-level primitives: bind mounts on Linux and BFS (Windows Sandbox) APIs on Windows. Both arrays accept absolute paths that are validated during the `createConfigFromPolicy` translation phase in [`sdk/src/sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/sandbox.ts).

### How does MXC discover available tools automatically?

The `getAvailableToolsPolicy()` function in [`sdk/src/policy.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/policy.ts) scans the host's `PATH` environment variable and well-known variables like `PYTHONPATH` and `NODE_PATH`. It filters out system-critical directories and paths that are already accessible through Windows ACLs, returning a `FilesystemPolicyResult` (lines 23-28) containing sanitized `readonlyPaths`. This allows sandboxes to access development tools without hard-coding installation directories that vary between machines.

### Can I use filesystem policies with the microVM backend on Windows?

Yes, but with specific constraints. When using the `microvm` backend parameter in `spawnSandbox()`, the SDK applies special logic at lines 84-96 of [`sdk/src/sandbox.ts`](https://github.com/microsoft/mxc/blob/main/sdk/src/sandbox.ts): it only injects the filesystem configuration block if you explicitly provide paths. This optimization prevents unnecessary mount operations in the lightweight virtual machine. You must also set `{ experimental: true }` in the options parameter when spawning microVM sandboxes.

### What happens when `clearPolicyOnExit` is set to false?

Setting `clearPolicyOnExit: false` in your `SandboxPolicy.filesystem` configuration instructs the `wxc-exec` executor to retain any sandbox-specific filesystem artifacts after the process terminates. This is useful for debugging microVM scenarios or when you need persistent state across multiple sandbox invocations. When set to `true` (the default), the executor removes temporary policy bindings and cleans up resources immediately after the sandbox exits.