fix(mxc): gate proxy startup on explicit policy (NVBug 6783325) - #3472
prekshivyas wants to merge 1 commit into
Conversation
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
Qualification before/after summaryNVBug: 6783325 — MXC host-proxy activation/lifecycle does not match explicit policy Before: Explicit allow and deny/no-match policies started a listener and injected proxy variables, but the no-network-policy case incorrectly did the same. Mock lifecycle skipped the real listener and successful startup had no durable log. After: Explicit allow and deny/no-match retain governed proxy startup; the no-network-policy case has no listener, proxy credentials, or proxy environment. Real ARM64 lifecycle proof confirmed listener ownership and cleanup. Results include 94 unit + 57 integration tests, 4,942 Windows ARM64 tests passed with 26 skipped, mock 4/4, and the signed real-MXC matrix passing. Qualification status: Focused scenario PASS; full combined qualification pending. A full two-cycle OpenClaw qualification should run after combining/rebasing this change with #3434. Hosted CI also requires a maintainer |
shailendra-nv
left a comment
There was a problem hiding this comment.
Requesting changes for the two inline findings below. The proxy activation test and startup log are valuable, but the empty-policy gate must not silently change mixed-config egress from loopback-only to unrestricted. Please also align the relay qualification documentation with the new non-proxy configuration. For NVBug 6783325, the PR should be treated as observability/regression hardening: the explicit-policy production path already worked on the base revision, and the original clean-exit reproduction still removes the listener after AgentCompleted.
| policy: Option<&SandboxPolicy>, | ||
| ) -> Result<Option<SocketAddr>, tonic::Status> { | ||
| let configured = configured_egress_addr(config)?; | ||
| Ok(configured.filter(|_| policy_activates_governed_egress(policy))) |
There was a problem hiding this comment.
Filtering the configured proxy address to None changes precedence with the existing pc_network_allow fallback. With egress_proxy=true, pc_network_allow=true, and no network rules, the base used loopback-only governed egress; this revision reaches the fallback that emits egress.default=allow. Preserve default-deny, reject the conflicting configuration, or explicitly document and test this security-sensitive behavior.
| 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 |
There was a problem hiding this comment.
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.
Summary
Fixes the remaining MXC host-proxy activation and lifecycle gaps associated with NVIDIA NVBug 6783325. An explicit
network_policiesrule now activates governed egress, while a policy with no network rules leaves the host listener and proxy environment absent; the lifecycle also emits a successful startup log and the mock path now exercises the real host proxy.The headline "explicit policy never starts" symptom no longer reproduces on the current
windowstip: explicit rules already created a real listener and injected proxy variables. The patch is still necessary because the default/no-network-policy case did the same thing unconditionally, successful startup was not logged, and the mock lifecycle explicitly skipped listener startup, leaving no durable regression coverage for the NVBug contract.Base:
fb2980e077288b61ef03a2e6187e162d158526aa(origin/windows, re-fetched immediately before commit).Related Issue
NVIDIA NVBug 6783325. No public GitHub issue required; this is a localized Windows MXC bug fix.
NVBug 6782969 remains separate. This PR does not change policy matching or enforcement and sends no request through the deny/no-match scenario.
Root Cause
egress_proxy = truealone produced a per-sandbox proxy address, MXC loopback redirect, credentials, and proxy environment for every policy, including policies without network rules.start_host_proxy, so tests could observe redirect/env serialization but could not catch a missing host listener or verify cleanup.Changes
Exact Before/After Evidence
Environment: Yukon Windows 10.0.28000 ARM64, native Rust 1.95.0
aarch64-pc-windows-msvc, signed Microsoftwxc-exec.exe0.8.0 (DDE1C592270E9A659B01DCCAD70362DA7B99FEC114885FA4D625507AA775A503). Workloads printed only presence markers; proxy credentials and values were not logged.Unmodified base, gateway PID 25388:
127.0.0.1:51990; env count 17 withHTTP_PROXY=SET/HTTPS_PROXY=SET; no successful startup log; stop completed in 67 ms and closed the listener.allowed.invalid:443): Ready; listener127.0.0.1:65434; the same proxy env markers; stop/delete cleaned up.127.0.0.1:60489and injected the same 17-variable proxy environment.host_proxyunder mock, and the default case unexpectedly had a proxy address.Patched commit, gateway PID 32012, identical policies/config/workload:
MXC host egress proxy started sandbox=n6783325-allow3 address=127.0.0.1:59127; listener owned by the gateway; env count 17 with both proxy markers; stop completed in 61 ms and the listener was gone after 250 ms.127.0.0.1:50743; listener/env present; stop/delete cleaned up.Security Impact
This narrows exposure: policies without explicit network governance no longer receive a host loopback listener, per-sandbox proxy credential, broad loopback MXC allowance, or proxy environment. Explicit governed egress remains fail-closed on startup/mapping errors. Provider credential resolution still requires both
egress_proxyand an explicit network policy. No permissions or policy-enforcement rules are broadened.Testing
mise run pre-commitpasses981files).grpcio-toolsfrom source: MSVC rejects upstream/std:c++17plus/std:c11flags.cargo test -p openshell-driver-mxc --target aarch64-pc-windows-msvc: 94 unit + 57 integration tests passed; 12 real-MXC tests ignored by the normal suite.mise run --skip-tools windows:test:arm64: 4,942 passed, 26 skipped, zero failures.clippy::unused_self,clippy::needless_updateinwxc_exec_real.rs). New Clippy findings in this patch were fixed.cargo fmt --all -- --check,git diff --check, PowerShell parser check: passed.Additional infrastructure notes:
windows:check:arm64reachedz3-sysbut the configured prebuilt Z3 download returned HTTP 403.wxc-execprobe hung; only this PR's queued wrapper was canceled. The direct signed-MXC matrix above completed and is the scenario-specific real-runtime proof.Residual Risk / Platform Limits
Checklist