Repository navigation
fix(mxc): keep host supervisor proxy CA files in sandbox state - #5059
Merged
shailendra-nv merged 3 commits intoOct 31, 2026
Merged
shailendra-nv merged 3 commits into
shailendra-nv merged 3 commits into
Conversation
…ndows write_tls_output installs each file with NamedTempFile::persist, which passes the temporary file's path to SetFileAttributesW and both paths to MoveFileExW unchanged. On Windows those calls fail with ERROR_PATH_NOT_FOUND for a path longer than MAX_PATH without the \\?\ prefix, and the supervisor then disables TLS termination. A TLS directory inside a deep state directory, such as an MXC sandbox's host state directory, can exceed that length. On Windows, resolve the output directory with canonicalize, which returns the \\?\ form, before creating and installing the file. If canonicalize fails, as it can on volumes that the Mount Manager does not track, keep the path as given. Signed-off-by: Jeffrey Quesnelle <emozilla@nousresearch.com>
The MXC driver starts the host supervisor without a proxy TLS directory, so the supervisor uses its default, /etc/openshell-tls, which Windows resolves to \etc\openshell-tls on the gateway's current drive. Every MXC sandbox on the host writes its proxy CA certificate and trust bundle to the same two files there and reads them back when it starts its workload, and the files stay after the sandbox is deleted. Set OPENSHELL_PROXY_TLS_DIR for the host supervisor to proxy-tls\ in the sandbox's host state directory, as the VM driver does with its state directory. delete_sandbox already removes that directory. Signed-off-by: Jeffrey Quesnelle <emozilla@nousresearch.com>
Author
4 tasks
Collaborator
|
/ok to test d2efbe9 |
Merge the current windows branch so CI includes the existing server test repairs and MXC fixes. Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
Collaborator
|
/ok to test eda6cc1 |
shailendra-nv
approved these changes
Oct 31, 2026
shailendra-nv
left a comment
Collaborator
There was a problem hiding this comment.
Reviewed the per-sandbox TLS directory, CA delivery and cleanup paths, and Windows extended-length atomic writes. No actionable findings.
The branch now includes the existing Windows test repairs. All 46 enabled checks pass, including native Windows x64 and ARM64 lint/tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The MXC driver starts each sandbox's host supervisor without
OPENSHELL_PROXY_TLS_DIR, so every supervisor writes its proxy CA certificate and the workload's CA bundle to/etc/openshell-tls, which Windows resolves to\etc\openshell-tlson the gateway's drive. Sandboxes started together overwrite each other's files, and the files outlive the sandbox. The Linux drivers don't hit this: Docker, Podman and Kubernetes run the supervisor inside each sandbox's container or pod withOPENSHELL_PROXY_TLS_DIR=/run/openshell/proxy-tls, and the VM driver sets it toproxy-tlsin the sandbox's state directory. This PR puts them inproxy-tls\in the sandbox's host state directory, as the VM driver does, and makes the supervisor's TLS file writes work for paths longer thanMAX_PATH, which that directory can exceed.Related Issue
Closes #5058
Changes
openshell-driver-mxc: the host supervisor command setsOPENSHELL_PROXY_TLS_DIR=<state_dir>\<sandbox-id>\<generation>\proxy-tls.delete_sandboxalready removes that directory.spawn_supervisornow calls a newsupervisor_command, which builds the command, so a unit test can read its environment. The driver README says where the files are.OPENSHELL_PROXY_TLS_DIRset for the gateway reached it and moved the files (still one directory for every sandbox); the driver now always sets the variable, so that value no longer applies.openshell-supervisor-network: on Windows,write_tls_outputresolves the output directory withcanonicalize(the\\?\form) before creating and installing the file. Ifcanonicalizefails, as it can on volumes that the Mount Manager does not track, the path is used as given, as before.NamedTempFile::persistpasses the temporary file's path toSetFileAttributesWand both paths toMoveFileExWunchanged, and those calls fail withos error 3beyondMAX_PATH. The new directory adds 84 characters tostate_dir(\<sandbox-id>\<generation>\proxy-tls), so the CA file path isstate_dirplus 101 characters. Other platforms are unchanged.\etc\openshell-tlsare not moved or removed.Testing
Host: Windows 11 26340.9767 x64, MXC 1.0.1
wxc-exec(--probe:base-container,needsDaclAugmentation: false), Rust 1.95.0, VS 2022 17.14, cargo-nextest 0.9.143. The Windows commands are the oneswindows:lint:x64andwindows:test:x64run (tasks/scripts/windows-msvc.ps1), with its environment.windows:lint:x64(workspace clippy with the Windows excludes and-D warnings,e2e/rustclippy,examples/governance-interceptorcheck): pass.windows:test:x64(cargo nextest run --profile ci --workspace <Windows excludes> --target x86_64-pc-windows-msvc --features openshell-server/test-support --features openshell-server/prebuilt-z3,openshell-prover/prebuilt-z3): 6,633 passed, 41 skipped. The first of two runs had one failure in a crate this PR does not touch (openshell-mxc-boundarysocket_owner::tests::resolves_child_that_owns_ipv4_connection: "No Windows process owns proxy connection", bug(mxc): proxy refuses some connections from an allowed program with "No Windows process owns proxy connection" #5056); it passed alone 5 of 5 and in the second run.cargo fmt --all -- --check,git diff --check: pass.cargo clippy --locked -p openshell-supervisor -p openshell-driver-mxc --all-targets -- -D warningsandcargo nextest run --locked --profile ci -p openshell-supervisor(169 passed) pass on the driver change. Theopenshell-supervisor-networkchange and its tests are Windows-only.host_supervisor_proxy_tls_dir_is_in_sandbox_host_state(openshell-driver-mxc): the host supervisor command setsOPENSHELL_PROXY_TLS_DIRtoproxy-tlsin the sandbox's host state directory. Onwindows(5d1bfbf92) it fails withleft: None. It also fails if the driver points the variable at the boundary state directory or at a directory shared by the gateway's sandboxes.write_ca_files_accepts_paths_longer_than_max_path(openshell-supervisor-network, Windows): writes both files into a directory whose CA file path is longer than 260 UTF-16 code units. Onwindowsit fails withatomically install TLS output ...: The system cannot find the path specified. (os error 3).extended_length_path_keeps_the_path_when_canonicalize_fails(openshell-supervisor-network, Windows): an existing directory resolves to the\\?\form; for a directory that does not exist,canonicalizefails and the path comes back unchanged. It fails if the error is not handled.run-mxc-e2e.ps1 -Scenario https-ca(local copy whoseTest-PortListeningconnects to the port, becauseGetActiveTcpListeners()does not list the gateway's listener on this host), with%TEMP%deep enough to put the CA file path at 304 characters (the harness keeps the driver's state under%TEMP%):windowspasses 2 of 2. The driver change alone fails 2 of 2 withHTTPS certificate absent(gateway log:Failed to write CA files ... (os error 3)) and passes with a short%TEMP%. With both commits it passes 2 of 2 at the same depth, and 1 of 1 with the CA file path at about 419 characters. These runs were on a host withLongPathsEnabled=1. On a host with the default0, creating a sandbox may fail earlier oncestate_diris about 186 characters or more, becausecreate_restricted_state_dirpasses the raw host state directory path toicacls.exe, which handles long paths only when that setting is on. That predates this PR and was not measured.Live before and after with the script in #5058: one gateway (mTLS, throwaway certificates) with an explicit
state_dir, 8 ProcessContainer sandboxes created at the same time; each workload saves the CA it was given and makes one HTTPS request toexample.comthrough the proxy, curl trusting only the injected bundle.windows5d1bfbf92C:\etc\openshell-tls\openshell-ca.pem,ca-bundle.pem, rewritten by every run<state_dir>\<sandbox-id>\<generation>\proxy-tls\, one per sandboxFailed to write CA files, TLS termination disabledand their workloads got no CAproxy-tlsfilesandbox deleteC:\etc\openshell-tlsstate_dirThe overwrites depend on timing: another run of this script on
windowshad 8 of 8, while all eight supervisors still wrote their files toC:\etc\openshell-tlsand none to sandbox state. The earlier runs used the same workload steps against a gateway without TLS. One sandbox at a time passed on both in the earlier runs (3 of 3 onwindows).Checklist