openshell-driver-mxc
The Windows-only MXC compute driver runs each workload in a Microsoft MXC ProcessContainer while preserving OpenShell's standard RFC 0012 runtime split:
gateway / MXC driver
|
| gateway authentication and policy
v
openshell-supervisor --role=isolation-backend (host)
|
| generation-scoped TLS + sandbox JWT
v
openshell-windows-sandbox (ProcessContainer)
|
v
workload
Caller driver config is disabled by default, so command-based MXC workflows need explicit administrator opt-in. Host filesystem grants have no trusted label resolver and are rejected while resource admission is enabled. See resource admission configuration for the independent controls and the security consequences of opting out.
This driver implements the gateway's ordinary in-process ComputeDriver
contract and is linked into openshell-gateway. Runtime readiness comes from
the authenticated host supervisor session, not a driver-reported condition.
The resolved create-time SandboxPolicy is carried by
DriverSandboxSpec.policy. The driver provisions a one-shot ProcessContainer,
launches the Windows boundary and separate host supervisor, and monitors both.
The boundary launches the workload only after authenticated confirmation.
The driver resolves its gateway endpoint and TLS server-name defaults from generic gateway inputs. The host supervisor authenticates its gateway session and retains main-process attachment independently of the optional Unix SSH adapter. TCP readiness remains gated by authenticated session acceptance.
Windows boundary execution is implemented by the openshell-mxc-boundary
library behind the dedicated openshell-windows-sandbox.exe. The compute driver does not
embed the supervisor, and the sandbox does not link the compute driver.
Dynamic forwarding uses the shared protocol stream, not a dedicated relay
executable or a reverse connection to a new gateway listener.
Enforcement boundaries
The current port is not runtime-qualified against main's outer-fence contract.
Broad host-loopback access does not establish NoUnmanagedEgressPath, and
live access revocation has no verified native evidence. The driver therefore
does not publish those guarantees, and main's confirmation gate prevents
workload activation. Configuration intent must not be promoted to enforcement
proof. A qualified PSEC host is necessary but does not by itself close these
implementation gaps.
- MXC supplies the default-deny filesystem fence, AppContainer token, UI policy, and loopback-only network fence.
openshell-windows-sandboxconsumes its bootstrap files before launching untrusted code, authenticates the paired supervisor, and terminates workloads when an authenticated supervisor cannot recover within the reconnect deadline.- The host supervisor owns an authenticated per-generation explicit proxy. Missing or cross-sandbox credentials receive HTTP 407 before policy evaluation. MXC denies direct Internet egress.
- The current explicit-proxy path attributes traffic to the admitted main workload binary. It does not distinguish descendant processes. MXC process policy must therefore prevent an untrusted allowed child binary from inheriting broader per-binary network rights.
- The loopback fence permits
127.0.0.1/32; it does not isolate unrelated host services bound to that address. Treat the gateway host as trusted. - Host supervisor tokens and descriptors live beneath an owner-only Windows DACL. Boundary bootstrap secrets live in the ProcessContainer staging path and are deleted before workload launch.
Configuration
The packaged openshell-supervisor.exe and openshell-windows-sandbox.exe default to
siblings of openshell-gateway.exe. Override their paths for development
builds.
[openshell.drivers.mxc]
wxc_exec_path = "C:\\mxc-kit\\bin\\wxc-exec.exe"
supervisor_binary_path = "C:\\OpenShell\\openshell-supervisor.exe"
sandbox_binary_path = "C:\\OpenShell\\openshell-windows-sandbox.exe"
# Defaults to %LOCALAPPDATA%\OpenShell\mxc.
state_dir = "C:\\Users\\operator\\AppData\\Local\\OpenShell\\mxc"
# Empty uses the gateway's loopback listener and TLS mode.
grpc_endpoint = ""
backend = "process_container"
pc_least_privilege = false
pc_capabilities = []
pc_allow_local_network = true
pc_minimal_env = false
debug = false
etw_audit = false
Only process_container supports this architecture. isolation_session is
rejected during sandbox validation.
Legacy configurations may retain default_configuration_id; it remains unused
by ProcessContainer and does not enable IsolationSession. New configurations
should omit that field.
Supply the workload command and working directory per sandbox:
$config = '{"mxc":{"command":["C:\\Windows\\System32\\cmd.exe","/d","/c","echo hello"],"cwd":"C:\\work"}}'
openshell sandbox create --name mxc-demo --policy policy.yaml `
--driver-config-json $config --no-tty
The command is required. The working directory is required because it contains
the generation-scoped bootstrap staging directory. Environment belongs in
--env or --env-from, not gateway configuration.
When gateway TLS is enabled, configure the gateway-owned guest_tls_ca.
The host supervisor verifies the gateway certificate with that CA and uses
main's launch authentication bundle. Gateway client certificates and keys are
not required; driver-owned guest TLS fields are rejected.
Capabilities
| Capability | Status |
|---|---|
| Filesystem and UI policy | Mapped to the MXC ProcessContainer fence |
| Network policy and provider credentials | Standard host supervisor proxy; proxy-aware workloads only |
| Exec, signals, retained output | Authenticated Sandbox Protocol; ConPTY resize is not yet supported |
| Dynamic forwarding | Standard supervisor ForwardTcp path through sandbox loopback connect |
| ETW/OCSF audit | Optional Windows Sandboxing ETW consumer |
| Gateway restart recovery | Not yet supported; live MXC generations remain in-memory |
Validation
Run the Windows build lane on a native Windows MSVC host:
mise run --skip-tools windows:check:x64
mise run --skip-tools windows:lint:x64
mise run --skip-tools windows:build:x64
mise run --skip-tools windows:test:mxc-real:x64
mise run --skip-tools windows:e2e:mxc
The real-MXC tests are skip-safe when wxc-exec.exe or the required host
capabilities are absent. A complete integration run still requires a qualified
Windows MXC host; cross-compilation validates code shape but cannot validate
ProcessContainer networking or DACL behavior.
The real runtime requires native ProcessContainer directional egress and ingress
host-loopback support, reported by wxc-exec.exe --probe. AppContainer fallback
cannot supply these guarantees. Count test-internal SKIP messages separately
from Cargo's passed count.
The E2E runner uses native release artifacts (override with -BinaryDir), OpenSSL
on PATH for disposable Ed25519 keys, and per-run writable fixtures under
target/windows-e2e-results. It preserves the tracked gateway TOML and isolates
CLI registration via XDG_CONFIG_HOME. Signing keys have an owner-only DACL,
remain outside result bundles, and are removed unless -KeepRunning is requested.
E2E runs real MXC only: there is no mock mode, and an inherited
OPENSHELL_MXC_MOCK_WXC=1 is rejected. Any skipped selected scenario makes the
run incomplete and exits non-zero; a passing exit requires all selected scenarios
to execute successfully. Unit-test mocks are separate from E2E coverage.
network-policy checks admission and workload execution, not real network
enforcement. All-skipped real runs report INCOMPLETE, not PASS.
The forwarding scenario starts a TCP listener inside MXC, then verifies two
nonce-bound request/reply exchanges through openshell forward service, the
gateway, supervisor, and Windows boundary. Both listener ports are dynamically
assigned. Its native echo agent is a test-only Cargo example, built automatically
by the E2E mise task and remote runner, not a shipped runtime binary. It verifies
managed ingress, not denial of direct host-to-workload connections. Select it with
-Scenario forwarding on the local harness or remote runner.
The separate service-forwarding scenario runs the same native fixture in HTTP
mode, exposes a named endpoint with openshell service expose, and verifies two
unique GET responses through gateway host-based routing. It deletes the endpoint
and requires HTTP 404 afterward. Requests connect only to the gateway with the
exposed URL's Host header, so no wildcard DNS setup is required.