MXC Network Allow/Block List Filtering for Outbound Connections: A Complete Guide

The MXC SDK enables granular control over outbound connections through the SandboxPolicy.network object, which translates declarative allow/block lists into platform-specific enforcement mechanisms including Windows Firewall rules, Linux iptables, and macOS Seatbelt profiles.

MXC network allow/block list filtering for outbound connections provides a cross-platform solution for restricting containerized application traffic. The microsoft/mxc repository implements this through a type-safe TypeScript SDK that validates policies at build time and enforces them through native system backends. Whether you need to block all external traffic, whitelist specific APIs, or blacklist malicious domains, the SDK handles the platform-specific complexity while exposing a consistent declarative interface.

How Network Filtering Works in MXC

The MXC SDK implements a three-stage pipeline for network security:

  1. Policy Definition – Developers specify network intent using the SandboxPolicy.network configuration object.
  2. SDK Translation – The createConfigFromPolicy() function in sdk/src/sandbox.ts converts high-level policy declarations into concrete ContainerConfig.network objects validated against schemas/stable/mxc-config.schema.0.6.0-alpha.json.
  3. Backend Enforcement – Native binaries (wxc-exec, lxc-exec, seatbelt, etc.) translate the configuration into OS-specific restrictions before the sandboxed process starts.

This architecture ensures that all network restrictions apply before any outbound connection can be made, maintaining a deny-by-default security posture unless explicitly overridden.

Defining Network Policies with SandboxPolicy

The SandboxPolicy.network property, defined in sdk/src/types.ts (lines 81-103), controls outbound connectivity through several key fields:

  • allowOutbound – Boolean flag that determines whether the sandbox can initiate external connections.
  • defaultPolicy – Either "allow" or "block"; when allowOutbound is true, the SDK defaults to "allow" (lines 84-89 in sdk/src/sandbox.ts).
  • allowedHosts – Array of hostnames to whitelist when operating in block-by-default mode.
  • blockedHosts – Array of hostnames to blacklist when operating in allow-by-default mode.

Validation Requirements

The SDK enforces strict validation rules in sdk/src/sandbox.ts (lines 319-321). If you specify allowedHosts or blockedHosts, you must explicitly set allowOutbound: true. Omitting this flag triggers a runtime error with the message: "allowedHosts/blockedHosts require allowOutbound to be true".

On Linux systems, the applyLinuxNetworkPolicy() helper in sdk/src/helper.ts (lines 20-38) automatically promotes the enforcementMode to 'firewall' whenever host-specific rules exist without a proxy configuration. This ensures that iptables rules are generated for granular filtering rather than relying on capability-based restrictions.

Platform-Specific Enforcement Mechanisms

Windows ProcessContainer and Firewall Rules

The Windows backend leverages AppContainer capabilities for broad "allow all" or "block all" policies. When allowedHosts or blockedHosts are specified, the SDK generates specific Windows Firewall rules to permit or deny connections to individual domains while maintaining the base policy for all other traffic.

Linux Bubblewrap with HTTP Proxy

For Linux environments using the bubblewrap backend without administrative privileges, MXC supports a cooperative HTTP proxy model. When network.proxy is configured (specifying a localhost port), the SDK leaves enforcementMode at 'capabilities' and relies on the proxy to perform hostname filtering. This approach, detailed in sdk/src/sandbox.ts (lines 89-102), enables host filtering in user-space without requiring iptables access.

Linux LXC with iptables Firewall

When using the lxc backend or any Linux configuration with host lists but no proxy, the applyLinuxNetworkPolicy() function elevates the enforcement to 'firewall' mode. This generates specific iptables rules that drop or accept packets based on the destination address, providing kernel-level enforcement of the allow/block lists.

macOS Seatbelt Profiles

The macOS backend generates TinyScheme sandbox profiles that translate MXC policies into (allow network-outbound) and (deny network-outbound) rules. As documented in docs/macos-support/seatbelt-backend.md (lines 197-200), the Seatbelt binary creates per-host rules that mirror the allowedHosts and blockedHosts configurations, integrating with the macOS sandboxing framework for system-level network control.

Practical Implementation Examples

Example 1: Block All Outbound Traffic Except Specific Hosts

This configuration implements a default-deny posture with a single whitelist exception:

import { spawnSandboxAsync, SandboxPolicy } from "@microsoft/mxc-sdk";

const policy: SandboxPolicy = {
  version: "0.5.0-alpha",
  network: {
    defaultPolicy: "block",
    allowOutbound: true,
    allowedHosts: ["api.github.com"]
  }
};

(async () => {
  const result = await spawnSandboxAsync(
    "curl https://api.github.com/zen",
    policy
  );
  console.log("STDOUT:", result.stdout);
})();

The SDK validates that allowOutbound is present before accepting the allowedHosts array.

Example 2: Linux Bubblewrap with HTTP Proxy

Use this approach when you cannot modify iptables rules but can route traffic through a local proxy:

import { spawnSandboxAsync, SandboxPolicy } from "@microsoft/mxc-sdk";

const policy: SandboxPolicy = {
  version: "0.5.0-alpha",
  network: {
    allowOutbound: true,
    proxy: { localhost: 3128 }
  }
};

await spawnSandboxAsync("wget -O - https://example.com", policy);

Because the proxy is present, applyLinuxNetworkPolicy() maintains enforcementMode: 'capabilities', delegating filtering to the proxy service running on port 3128.

Example 3: Windows with Firewall Block List

Prevent connections to specific malicious domains while allowing all other traffic:

import { spawnSandboxAsync, SandboxPolicy } from "@microsoft/mxc-sdk";

const policy: SandboxPolicy = {
  version: "0.5.0-alpha",
  network: {
    allowOutbound: true,
    blockedHosts: ["example.com"]
  }
};

await spawnSandboxAsync(
  "powershell -Command \"Invoke-WebRequest https://example.com\"", 
  policy
);

The SDK translates blockedHosts into Windows Firewall deny rules that block DNS resolution and TCP connections to the specified domains.

Example 4: Invalid Configuration Handling

Attempting to specify host lists without enabling outbound traffic triggers validation errors:

const badPolicy: SandboxPolicy = {
  version: "0.5.0-alpha",
  network: {
    allowedHosts: ["api.github.com"]
    // Missing allowOutbound: true
  }
};

await spawnSandboxAsync("echo hi", badPolicy); 
// Throws: "allowedHosts/blockedHosts require allowOutbound to be true"

This validation occurs in sdk/src/sandbox.ts before any sandbox creation begins, preventing misconfigurations from reaching the backend.

Summary

  • Declarative Policy Surface – MXC uses the SandboxPolicy.network object to express intent, with strict TypeScript validation in sdk/src/types.ts and JSON schema validation against schemas/stable/mxc-config.schema.0.6.0-alpha.json.
  • Automatic Enforcement Selection – The SDK selects appropriate enforcement mechanisms (Windows Firewall, Linux iptables, macOS Seatbelt, or HTTP proxy) based on the platform and policy complexity.
  • Mandatory Explicit Flags – The allowOutbound boolean is required whenever using allowedHosts or blockedHosts, enforced by validation logic in sdk/src/sandbox.ts (lines 319-321).
  • Dynamic Mode Promotion – On Linux, applyLinuxNetworkPolicy() in sdk/src/helper.ts automatically switches to 'firewall' mode when host-specific rules require iptables intervention.

Frequently Asked Questions

What happens if I specify allowedHosts without setting allowOutbound to true?

The SDK throws a validation error before creating the container. According to the implementation in sdk/src/sandbox.ts (lines 319-321), the createConfigFromPolicy() function checks for this misconfiguration and returns an error stating that "allowedHosts/blockedHosts require allowOutbound to be true". This prevents ambiguous policy states where host lists exist but outbound connections are entirely disabled.

How does MXC enforce network policies on Linux without root access?

When administrative privileges are unavailable, MXC can route traffic through a cooperative HTTP proxy specified in the network.proxy configuration. In this mode, documented in sdk/src/sandbox.ts (lines 89-102), the sandbox relies on the proxy to filter requests rather than iptables rules. The bubblewrap backend supports this user-space filtering approach, though it requires the application to respect the proxy configuration.

Does MXC support wildcard or subdomain matching in allowedHosts and blockedHosts?

The source analysis focuses on exact hostname matching implemented in the platform-specific backends. Windows Firewall rules and iptables rules generated by the SDK target specific domain strings as provided in the policy arrays. For complex filtering requirements involving wildcards, the documentation recommends using the HTTP proxy approach where the proxy server handles pattern matching before forwarding requests.

What is the difference between defaultPolicy and allowOutbound?

The defaultPolicy field accepts "allow" or "block" strings that define the baseline network posture, while allowOutbound is a boolean flag required for technical validation. In sdk/src/sandbox.ts (lines 84-89), the SDK derives the default policy from allowOutbound: when true, it sets defaultPolicy to "allow"; when false or omitted, it defaults to "block". The allowOutbound flag also serves as an explicit opt-in that unlocks the allowedHosts and blockedHosts arrays for granular control.

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 →