Skip to content

Commit 348d4ed

Browse files
committed
chore: merge windows branch updates
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
2 parents 9ae8a43 + 4f06e23 commit 348d4ed

12 files changed

Lines changed: 324 additions & 175 deletions

File tree

crates/openshell-driver-mxc/README.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ it does not implement the Linux `ConnectSupervisor` protocol.
2323
|---|---|
2424
| 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. |
2525
| 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. |
26-
| 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. |
26+
| 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. |
2727
| 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. |
2828
| Process policy | Unsupported; MXC supplies OS isolation only. |
2929
| Dynamic forwarding | Supported through `openshell-supervisor-relay`; interactive exec/connect remain unsupported. |
@@ -60,6 +60,10 @@ pc_relay_target_port = 0
6060
# (SYSTEMROOT/WINDIR/PATH/COMSPEC/LOCALAPPDATA); pc_minimal_env starts from an
6161
# EMPTY env for runtimes that need a fully curated per-sandbox environment.
6262
pc_minimal_env = false
63+
# processContainer only: compatibility fallback for unrestricted outbound TCP.
64+
# A sandbox with egress_proxy enabled but no explicit network rules rejects
65+
# this fallback instead of silently changing governed egress to allow-all.
66+
pc_network_allow = false
6367
# processContainer only: include "allowLocalNetwork": true in the MXC
6468
# network section. This compatibility setting broadens network access and is
6569
# not required by the BaseContainer qualification profile.
@@ -72,8 +76,14 @@ etw_audit = false
7276
```
7377

7478
When `egress_proxy` is enabled, `egress_proxy_addr` must be a loopback
75-
`IP:PORT` seed. The driver preserves the configured IP and allocates a unique
76-
ephemeral port for each sandbox's authenticated host CONNECT proxy.
79+
`IP:PORT` seed. For policies with explicit network rules, the driver preserves
80+
the configured IP and allocates a unique ephemeral port for that sandbox's
81+
authenticated host CONNECT proxy.
82+
83+
`pc_network_allow = true` is an explicit unrestricted-egress compatibility
84+
fallback. If it is combined with `egress_proxy = true`, a sandbox policy
85+
without explicit network rules is rejected synchronously rather than falling
86+
through from governed egress to `defaultPolicy = "allow"`.
7787

7888
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:
7989

@@ -87,7 +97,7 @@ The `command` array is required and preserves Windows argument boundaries. `cwd`
8797

8898
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`).
8999

90-
`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.
100+
`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.
91101

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

145-
When `egress_proxy` is enabled, `EmbeddedPolicyMapper` uses `split_policy`
146-
instead: MXC receives filesystem grants plus loopback-only egress,
155+
When `egress_proxy` is enabled and the policy contains explicit network rules,
156+
`EmbeddedPolicyMapper` uses `split_policy` instead: MXC receives filesystem
157+
grants plus loopback-only egress,
147158
and the driver starts a host CONNECT proxy from the trimmed
148159
network-only `SandboxPolicy`. Policies containing `network_middlewares` are
149160
rejected synchronously until this host-proxy path can receive the gateway's

crates/openshell-driver-mxc/examples/e2e-policies/ws-agent.yaml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010
# system paths and share_dir).
1111
# - TCP socket binding on port 22000 (governed by pc_capabilities in the
1212
# gateway TOML, not by filesystem policy here).
13-
# - Outbound TCP through the egress proxy, for openshell-supervisor-relay
14-
# to dial the driver's on-demand relay — governed by egress_proxy in the
15-
# TOML.
13+
# - Private/loopback client access for openshell-supervisor-relay to dial
14+
# the driver's on-demand relay — granted by pc_capabilities in the TOML.
1615
# - No writes to the host filesystem.
1716
#
1817
# workload directory (passed by run-ws-agent-test.ps1, default C:\work\openshell-mxc-ws)
@@ -24,15 +23,9 @@
2423
# patches this path and the per-sandbox driver config when -AgentDir overrides
2524
# the default below.
2625
#
27-
# This example intentionally omits network_policies, not because the driver
28-
# would reject it: with egress_proxy = true (set in mxc-ws-gateway.toml), the
29-
# driver takes the lossless split path (policy_map::split_policy) and
30-
# delegates network_policies verbatim to the OpenShell host CONNECT proxy for
31-
# enforcement -- an "info" loss item, not an error, so it would be accepted.
32-
# (Only the no-proxy coarse path, or an unsupported rule shape, can turn a
33-
# network_policies entry into a rejected "error" loss item -- see
34-
# policy_map/map.rs.) This scenario just doesn't need host-enforced network
35-
# rules beyond the loopback/pc_capabilities grant above.
26+
# This example intentionally omits network_policies because it does not need
27+
# governed Internet egress. The driver therefore does not start a host CONNECT
28+
# proxy or inject proxy environment variables for this sandbox.
3629
version: 1
3730

3831
filesystem_policy:

crates/openshell-driver-mxc/examples/mxc-ws-agent.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,8 @@ async fn run_relay_proxy(relay_url: String, local_url: String, mut stop_rx: ones
282282
const LOCAL_CONNECT_ATTEMPTS: u32 = 15;
283283
const LOCAL_CONNECT_TIMEOUT: Duration = Duration::from_millis(500);
284284
const LOCAL_CONNECT_BACKOFF: Duration = Duration::from_millis(300);
285-
// Connect to the gateway relay (outbound via egress_proxy).
285+
// Connect directly to the gateway relay over the private network access
286+
// granted by the qualification profile's privateNetworkClientServer capability.
286287
let relay_ws = match tokio_tungstenite::connect_async(&relay_url).await {
287288
Ok((ws, _)) => {
288289
eprintln!("[spawner] relay connected: {relay_url}");

crates/openshell-driver-mxc/examples/mxc-ws-gateway.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,10 @@ pc_capabilities = ["privateNetworkClientServer"]
4848
# process_container only: keep standard privilege level (not LPA).
4949
pc_least_privilege = false
5050

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

5756
# The workload command and cwd are supplied per sandbox by
5857
# run-ws-agent-test.ps1 through `sandbox create --driver-config-json`.

crates/openshell-driver-mxc/examples/ocsf-audit.yaml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,24 @@
77
# else is default-deny. run-ocsf-audit.ps1 copies this policy into the result
88
# bundle and replaces the default grant with -ShareDir for that run.
99
#
10-
# No network_policies block is needed here: the per-sandbox egress proxy is driven
11-
# by `egress_proxy = true` in mxc-ocsf-audit.toml (that is what makes MXC emit the
12-
# SandboxProxyConfigured event we map to OCSF), not by a policy rule.
10+
# The explicit network rule activates the per-sandbox egress proxy configured
11+
# in mxc-ocsf-audit.toml. That proxy configuration makes MXC emit the
12+
# SandboxProxyConfigured event mapped to OCSF. run-ocsf-audit.ps1 removes this
13+
# block for its explicit -NoProxy comparison.
1314
version: 1
1415

1516
filesystem_policy:
1617
include_workdir: false
1718
read_only: []
1819
read_write:
1920
- "C:/work/openshell-mxc-demo"
21+
22+
network_policies:
23+
audit_probe:
24+
name: audit-probe
25+
endpoints:
26+
- host: example.com
27+
port: 443
28+
protocol: tcp
29+
binaries:
30+
- path: "C:/Windows/System32/cmd.exe"

crates/openshell-driver-mxc/examples/run-ocsf-audit.ps1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ try {
144144
$shareDirPolicy = $ShareDir.Replace('\', '/')
145145
$shareDirJson = ConvertTo-Json $shareDirPolicy -Compress
146146
$policyText = Get-Content $policySrc -Raw
147+
if (-not $proxyOn) {
148+
$policyText = [regex]::Replace($policyText, '(?ms)^network_policies:\s*.*\z', '')
149+
}
147150
$defaultGrant = ' - "C:/work/openshell-mxc-demo"'
148151
if (-not $policyText.Contains($defaultGrant)) {
149152
throw "policy template does not contain the expected default ShareDir grant"

crates/openshell-driver-mxc/examples/run-ws-agent-test.ps1

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -359,15 +359,12 @@ try {
359359
}
360360
Ok "wxc-exec: $WxcExecPath"
361361

362-
# A real run exercises process_container with egress_proxy = true
363-
# (mxc-ws-gateway.toml). MXC schema 0.8.0-alpha's network_json()
364-
# (mxc.rs) now emits a direct egress.allow rule for 127.0.0.0/8
365-
# instead of runtimeConfig.networkProxy when a proxy is configured,
366-
# so the driver no longer calls the elevation-only
367-
# NetworkIsolationSetAppContainerConfig -- process_container +
368-
# egress_proxy selects the BaseContainer/PSEC tier and runs
369-
# non-elevated. Elevation is therefore no longer required here; keep
370-
# logging the elevation state for diagnostics only.
362+
# A real run exercises process_container with egress_proxy disabled
363+
# (mxc-ws-gateway.toml). The sandbox connects directly to the driver's
364+
# route-selected private-interface relay listener through the
365+
# privateNetworkClientServer capability; the governed host CONNECT
366+
# proxy is not part of this qualification path. Elevation is not
367+
# required here; keep logging the elevation state for diagnostics only.
371368
$wid = [Security.Principal.WindowsIdentity]::GetCurrent()
372369
$wp = New-Object Security.Principal.WindowsPrincipal($wid)
373370
$admin = $wp.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

0 commit comments

Comments
 (0)