Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions crates/openshell-driver-mxc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ it does not implement the Linux `ConnectSupervisor` protocol.
|---|---|
| Filesystem policy | Read-only/read-write grants come only from `SandboxPolicy`. `process_container` enforces default-deny; `isolation_session` is an explicit grant-only compatibility mode. |
| UI policy | `process_container` advertises complete support and maps portable graphical UI, clipboard-direction, and input-injection controls to MXC; omitted fields inside an explicit section deny. `isolation_session` advertises no support, so the gateway rejects any explicit section before provisioning. |
| Network policy | With `egress_proxy = true` on `process_container`, split into MXC 0.8 loopback-only egress plus the full policy enforced by a per-sandbox OpenShell host CONNECT proxy. The driver injects proxy environment variables for proxy-aware clients; direct Internet access remains denied by MXC. Otherwise rejected synchronously. `isolation_session` remains fail-closed. |
| Network policy | With `egress_proxy = true` on `process_container`, an explicit `network_policies` rule activates MXC 0.8 loopback-only egress plus the full policy enforced by a per-sandbox OpenShell host CONNECT proxy. The driver injects proxy environment variables for proxy-aware clients; direct Internet access remains denied by MXC. A policy without network rules does not activate the proxy. Otherwise rejected synchronously. `isolation_session` remains fail-closed. |
| Provider credentials | The child receives revision-scoped placeholders and non-secret provider environment only. The per-sandbox host proxy retains the resolver and substitutes credentials only for their bound endpoints. |
| Process policy | Unsupported; MXC supplies OS isolation only. |
| Dynamic forwarding | Supported through `openshell-supervisor-relay`; interactive exec/connect remain unsupported. |
Expand Down Expand Up @@ -72,8 +72,9 @@ etw_audit = false
```

When `egress_proxy` is enabled, `egress_proxy_addr` must be a loopback
`IP:PORT` seed. The driver preserves the configured IP and allocates a unique
ephemeral port for each sandbox's authenticated host CONNECT proxy.
`IP:PORT` seed. For policies with explicit network rules, the driver preserves
the configured IP and allocates a unique ephemeral port for that sandbox's
authenticated host CONNECT proxy.

Supply workload settings for each sandbox. The public config is keyed by driver name; the gateway forwards only the inner `mxc` object to the driver:

Expand All @@ -87,7 +88,7 @@ The `command` array is required and preserves Windows argument boundaries. `cwd`

UI capability (Win32k syscalls, clipboard, input injection) is a `SandboxPolicy` concern, not gateway TOML -- see the Capability Matrix above and `docs/reference/policy-schema.mdx`'s `ui` section. Defaults to disabled (Win32k syscall lockdown) when a policy has no explicit `ui:` section; set `allow_graphical_ui: true` for agents that touch user32/gdi32 at startup even without opening a real window (e.g. Node.js-based targets like OpenClaw's gateway -- see `examples/e2e-policies/openclaw-gateway.yaml`).

`egress_proxy_addr` must be a `127.0.0.1:PORT` address. The port acts only as a configuration seed: the driver reserves a unique ephemeral loopback port for every sandbox. MXC 0.8 denies direct Internet egress and permits `127.0.0.1/32`; the driver points proxy-aware clients at the per-sandbox listener using environment variables. The current policy permits all loopback ports, so sandboxes can also reach unrelated host services bound to loopback. Control-channel forwarding does not require the legacy reverse-WebSocket connections to fresh host ports; restricting the generated policy is separate hardening work. Do not treat this path as loopback-service isolation. Live policy replacement or merge updates remain unsupported; delete and recreate the sandbox to apply a different policy.
`egress_proxy_addr` must be a `127.0.0.1:PORT` address. The port acts only as a configuration seed: for a sandbox policy with explicit network rules, the driver reserves a unique ephemeral loopback port. MXC 0.8 denies direct Internet egress and permits `127.0.0.1/32`; the driver points proxy-aware clients at the per-sandbox listener using environment variables. A policy without network rules keeps MXC's default network posture and receives neither a host listener nor proxy environment variables. The current governed-egress policy permits all loopback ports, so governed sandboxes can also reach unrelated host services bound to loopback. Control-channel forwarding does not require the legacy reverse-WebSocket connections to fresh host ports; restricting the generated policy is separate hardening work. Do not treat this path as loopback-service isolation. Live policy replacement or merge updates remain unsupported; delete and recreate the sandbox to apply a different policy.

When `etw_audit` is enabled, each gateway process owns a distinct real-time ETW
session named from the stable `OpenShell-MXC-ETW` prefix, its process ID, and a
Expand Down Expand Up @@ -142,8 +143,9 @@ or MXC-specific gateway composition variant. Provider resolver state uses a
separate, create-scoped in-process handoff because it intentionally cannot be
represented in the public compute-driver protobuf.

When `egress_proxy` is enabled, `EmbeddedPolicyMapper` uses `split_policy`
instead: MXC receives filesystem grants plus loopback-only egress,
When `egress_proxy` is enabled and the policy contains explicit network rules,
`EmbeddedPolicyMapper` uses `split_policy` instead: MXC receives filesystem
grants plus loopback-only egress,
and the driver starts a host CONNECT proxy from the trimmed
network-only `SandboxPolicy`. Policies containing `network_middlewares` are
rejected synchronously until this host-proxy path can receive the gateway's
Expand Down
17 changes: 5 additions & 12 deletions crates/openshell-driver-mxc/examples/e2e-policies/ws-agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
# system paths and share_dir).
# - TCP socket binding on port 22000 (governed by pc_capabilities in the
# gateway TOML, not by filesystem policy here).
# - Outbound TCP through the egress proxy, for openshell-supervisor-relay
# to dial the driver's on-demand relay — governed by egress_proxy in the
# TOML.
# - Private/loopback client access for openshell-supervisor-relay to dial
# the driver's on-demand relay — granted by pc_capabilities in the TOML.
# - No writes to the host filesystem.
#
# workload directory (passed by run-ws-agent-test.ps1, default C:\work\openshell-mxc-ws)
Expand All @@ -24,15 +23,9 @@
# patches this path and the per-sandbox driver config when -AgentDir overrides
# the default below.
#
# This example intentionally omits network_policies, not because the driver
# would reject it: with egress_proxy = true (set in mxc-ws-gateway.toml), the
# driver takes the lossless split path (policy_map::split_policy) and
# delegates network_policies verbatim to the OpenShell host CONNECT proxy for
# enforcement -- an "info" loss item, not an error, so it would be accepted.
# (Only the no-proxy coarse path, or an unsupported rule shape, can turn a
# network_policies entry into a rejected "error" loss item -- see
# policy_map/map.rs.) This scenario just doesn't need host-enforced network
# rules beyond the loopback/pc_capabilities grant above.
# This example intentionally omits network_policies because it does not need
# governed Internet egress. The driver therefore does not start a host CONNECT
# proxy or inject proxy environment variables for this sandbox.
version: 1

filesystem_policy:
Expand Down
9 changes: 4 additions & 5 deletions crates/openshell-driver-mxc/examples/mxc-ws-gateway.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ pc_capabilities = ["privateNetworkClientServer"]
# process_container only: keep standard privilege level (not LPA).
pc_least_privilege = false

# Egress proxy for outbound TCP connectivity -- required for
# openshell-supervisor-relay to dial out to the driver's on-demand relay
# (see mxc-openclaw-gateway.toml, which uses the same pattern).
egress_proxy = true
egress_proxy_addr = "127.0.0.1:18080"
# No governed Internet egress is needed. The relay reaches the driver's
# on-demand loopback listener through privateNetworkClientServer above.
egress_proxy = false

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This configuration now disables egress_proxy and relies on privateNetworkClientServer, but companion qualification comments still say mxc-ws-gateway.toml enables the proxy and that the relay connects through it (run-ws-agent-test.ps1, relay.rs, and mxc-ws-agent.rs). Update those references so qualification attributes connectivity to the correct mechanism.

egress_proxy_addr = ""

# The workload command and cwd are supplied per sandbox by
# run-ws-agent-test.ps1 through `sandbox create --driver-config-json`.
Expand Down
17 changes: 14 additions & 3 deletions crates/openshell-driver-mxc/examples/ocsf-audit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,24 @@
# else is default-deny. run-ocsf-audit.ps1 copies this policy into the result
# bundle and replaces the default grant with -ShareDir for that run.
#
# No network_policies block is needed here: the per-sandbox egress proxy is driven
# by `egress_proxy = true` in mxc-ocsf-audit.toml (that is what makes MXC emit the
# SandboxProxyConfigured event we map to OCSF), not by a policy rule.
# The explicit network rule activates the per-sandbox egress proxy configured
# in mxc-ocsf-audit.toml. That proxy configuration makes MXC emit the
# SandboxProxyConfigured event mapped to OCSF. run-ocsf-audit.ps1 removes this
# block for its explicit -NoProxy comparison.
version: 1

filesystem_policy:
include_workdir: false
read_only: []
read_write:
- "C:/work/openshell-mxc-demo"

network_policies:
audit_probe:
name: audit-probe
endpoints:
- host: example.com
port: 443
protocol: tcp
binaries:
- path: "C:/Windows/System32/cmd.exe"
3 changes: 3 additions & 0 deletions crates/openshell-driver-mxc/examples/run-ocsf-audit.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ try {
$shareDirPolicy = $ShareDir.Replace('\', '/')
$shareDirJson = ConvertTo-Json $shareDirPolicy -Compress
$policyText = Get-Content $policySrc -Raw
if (-not $proxyOn) {
$policyText = [regex]::Replace($policyText, '(?ms)^network_policies:\s*.*\z', '')
}
$defaultGrant = ' - "C:/work/openshell-mxc-demo"'
if (-not $policyText.Contains($defaultGrant)) {
throw "policy template does not contain the expected default ShareDir grant"
Expand Down
Loading
Loading