How MXC's Fallback Policy Works When the BaseContainer API Is Unavailable

When the BaseContainer API is unreachable, MXC automatically switches to a fallback policy defined in sdk/src/policy.ts that constructs a sandbox filesystem description from environment variables and PATH directories, spawning a low-privilege process-container instead.

The microsoft/mxc repository provides a cross-container runtime that normally leverages the host's native BaseContainer API for optimal isolation and performance. When this low-level interface is unavailable—whether due to missing COM interfaces, absent runtimes, or insufficient process capabilities—MXC does not fail. Instead, it activates a sophisticated fallback mechanism that builds a sandbox filesystem policy from the current environment, ensuring workloads remain functional while preserving security boundaries.

From BaseContainer to Process-Container

By default, MXC attempts to create workloads inside the BaseContainer API, which offers hardware-level isolation through the host's container runtime. When getAvailableToolsPolicy detects that this API cannot be contacted—typically determined by platform checks in sdk/src/platform.ts—the SDK shifts to a process-container model. This fallback uses Windows AppContainer technology (or equivalent platform sandboxes) combined with a dynamically generated filesystem policy that grants access only to necessary tools and directories.

Step-by-Step Fallback Policy Generation

The fallback flow lives in sdk/src/policy.ts and follows a rigorous five-step validation process to construct a safe filesystem description without relying on the BaseContainer service.

1. Collecting Candidate Directories from Environment

The process begins by harvesting paths from the host environment. The function getAvailableToolsPolicy reads the PATH variable and a curated list of well-known development environment variables—including PYTHONPATH, VCINSTALLDIR, and DOTNET_ROOT—using internal helpers splitPathList and singlePath. These utilities parse semicolon-delimited strings (on Windows) or colon-delimited strings (on Linux) into individual directory entries.

2. Normalizing and Deduplicating Paths

Raw environment paths often contain duplicates or relative segments. MXC normalizes every entry using path.resolve and applies deduplicatePaths to eliminate redundancies. On Windows, this deduplication is case-insensitive to prevent C:\Tools and c:\tools from creating conflicting policy entries.

3. Filtering System-Critical Locations

Security hardening occurs through aggressive filtering. The isSystemCriticalPath function excludes directories like %WINDIR%, /bin, and /usr/sbin from the fallback policy. Additionally, if the caller specifies containerType: 'processcontainer', MXC invokes hasAllApplicationPackagesAccess to check directory ACLs via icacls. Any path already granting ALL_APPLICATION_PACKAGES access is omitted to prevent duplicate permissions and unnecessary brokering overhead.

4. Handling PowerShell-Specific Paths

Interactive shells require special handling to maintain user experience. When getPowerShellPolicy (lines 92-132 in sdk/src/policy.ts) detects pwsh.exe on the system PATH, it automatically appends the drive root (e.g., C:\) to readonlyPaths and the PSReadLine history folder to readwritePaths. This mirrors the volume mount behavior that the BaseContainer API would normally provide for interactive PowerShell sessions.

5. Returning the Composite Filesystem Policy

The final stage assembles a FilesystemPolicyResult object containing readonlyPaths and readwritePaths arrays. This policy fragment is consumed by sdk/src/sandbox.ts which constructs the actual container environment, ensuring compilers, SDKs, and user-profile tools remain accessible even without the BaseContainer service.

Security Guarantees and ACL Validation

The fallback policy maintains strict security through multiple validation layers. Tool discovery continues to function because the policy exposes development directories from environment variables while excluding system binaries. Directory filtering prevents exposure of critical OS paths, and the ACL checking mechanism ensures that directories with existing broad permissions are not double-brokered, avoiding permission inheritance conflicts in the Windows AppContainer sandbox.

Implementing Fallback Mode in Code

Developers can explicitly trigger or inspect the fallback behavior using the containerType parameter in getAvailableToolsPolicy:

import { getAvailableToolsPolicy } from 'mxc/sdk/src/policy';

// Standard operation when BaseContainer is available
const standardPolicy = getAvailableToolsPolicy();

// Explicit fallback mode for process-container creation
const fallbackPolicy = getAvailableToolsPolicy(undefined, { 
  containerType: 'processcontainer' 
});

console.log('Read-only paths:', fallbackPolicy.readonlyPaths);
console.log('Read-write paths:', fallbackPolicy.readwritePaths);

When constructing a sandbox with the fallback policy, integrate it alongside other policy fragments:

import { Sandbox } from 'mxc/sdk/src/sandbox';
import { getAvailableToolsPolicy, getUserProfilePolicy, getTemporaryFilesPolicy } from 'mxc/sdk/src/policy';

const policy = {
  ...getAvailableToolsPolicy(undefined, { containerType: 'processcontainer' }),
  ...getUserProfilePolicy(),
  ...getTemporaryFilesPolicy(),
};

const sb = new Sandbox({ filesystem: policy });
await sb.start(); // Launches process-container with fallback filesystem

Summary

  • MXC's fallback policy activates automatically in sdk/src/policy.ts when the BaseContainer API is unreachable, typically creating a Windows AppContainer instead.
  • Environment harvesting pulls paths from PATH and variables like PYTHONPATH, then normalizes and deduplicates entries via deduplicatePaths.
  • Security filtering excludes system-critical directories through isSystemCriticalPath and checks ACLs with hasAllApplicationPackagesAccess to avoid redundant permissions.
  • PowerShell compatibility is preserved through getPowerShellPolicy, which adds drive roots and history folders to the filesystem description.
  • Automatic recovery occurs when the host regains BaseContainer capabilities; the fallback policy serves only as a temporary safety net.

Frequently Asked Questions

What triggers MXC's fallback policy?

The fallback policy activates when the SDK cannot establish communication with the BaseContainer API, typically because the host OS lacks required COM interfaces, the container runtime is not installed, or the process lacks necessary capabilities. Detection logic in sdk/src/platform.ts determines API availability before getAvailableToolsPolicy constructs the filesystem description.

How does the fallback policy maintain security without the BaseContainer API?

Security is maintained through aggressive path filtering: isSystemCriticalPath blocks OS directories like %WINDIR% and /bin, while hasAllApplicationPackagesAccess (which queries icacls) prevents exposing directories that already grant broad container access. This ensures the resulting Windows AppContainer receives only the minimal necessary filesystem permissions.

Can I force MXC to use the fallback policy even when BaseContainer is available?

Yes. You can explicitly request fallback mode by passing containerType: 'processcontainer' as the second argument to getAvailableToolsPolicy. This is useful for testing compatibility or when you specifically require the environment-derived filesystem policy rather than the native container runtime's default mounts.

What happens to PowerShell functionality in fallback mode?

When pwsh.exe is detected on the system PATH, getPowerShellPolicy automatically adds the drive root to readonlyPaths and the PSReadLine history directory to readwritePaths. This ensures interactive PowerShell sessions retain access to command history and can execute scripts from the drive root, closely mirroring the behavior of a native BaseContainer environment.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →