Skip to content

fix(supervisor): reject unsupported live filesystem policy changes - #5327

Open
nv-rahool wants to merge 1 commit into
NVIDIA:windowsfrom
nv-rahool:fix/5326-reject-live-filesystem-changes/nv-rahool
Open

nv-rahool wants to merge 1 commit into
NVIDIA:windowsfrom
nv-rahool:fix/5326-reject-live-filesystem-changes/nv-rahool

Conversation

@nv-rahool

Copy link
Copy Markdown

Summary

Backport of #5234 to windows. A live policy update that adds a filesystem path is accepted by the gateway, reported as loaded by the supervisor, and shown as effective, but the running workload never receives the new path. On Windows the MXC driver maps filesystem grants into the container only when the sandbox is created. After this change the supervisor compares the candidate's filesystem section with the one applied at startup and rejects a changed revision as failed, with "filesystem policy cannot be changed on a running sandbox; recreate the sandbox to apply filesystem changes".

Related Issue

Closes #5326

The windows counterpart of #5041, which #5234 closes on main.

Changes

  • openshell-supervisor (lib.rs): add validate_live_filesystem_policy, the same check as fix(supervisor): reject live filesystem policy changes that cannot take effect #5234's ConfigRuntime::validate_live_filesystem_policy, except that it returns Err(miette::miette!(..)) like the other validators in this crate instead of miette::bail!. It compares include_workdir and the read_only / read_write paths as sets, so reordered paths still load. The poll loop runs it before reload_gateway_configuration_runtime and reports a mismatch as GatewayRuntimeReloadError::PolicyValidation. Rejection then follows the existing validation-failure handling: the revision is reported failed, and the configured policy_validation_failure_mode (default fail_closed) applies.
  • On windows the poll loop still lives in lib.rs (there is no config_runtime.rs), so the check is a free function that takes the applied policy (current_endpoint_policy) instead of a method.
  • Tests (ported from fix(supervisor): reject live filesystem policy changes that cannot take effect #5234, driven through run_policy_poll_loop_with_client because windows has no ConfigRuntime):
    • live_filesystem_changes_reject_polled_policy_without_advancing_active_revision: sandbox and global sources × added read-only path, added read-write path, and a filesystem section added where there was none; checks the failed status report, fail-closed versus retained policy, and the OPA generation.
    • live_filesystem_change_poll_reports_failure_then_accepts_network_only_repair: a rejected revision followed by a network-only revision with reordered paths loads. Unlike the main test, it sets the transparent TCP state as ready, because the windows reload path still checks it for the TCP fixture.
  • poll_rejects_first_tcp_expansion_and_reports_previous_policy_active: its second revision now keeps the first revision's filesystem section and changes only the network rules. It was built from a TCP-only policy with no filesystem section, so the new check rejected it before the TCP check ran. The gateway already refuses a sandbox policy update that drops the filesystem section. main no longer has the transparent TCP check, so fix(supervisor): reject live filesystem policy changes that cannot take effect #5234 did not need this.
  • Docs: the "Added filesystem paths" row in docs/how-it-works/policies/manage-policies.mdx, same text as fix(supervisor): reject live filesystem policy changes that cannot take effect #5234.

Testing

  • Checks appropriate to the affected code and behavior pass
    • Linux (Rust 1.95.0): cargo test -p openshell-supervisor --lib passes 158/158; cargo fmt --all --check is clean; cargo clippy -p openshell-supervisor --all-targets --no-deps -- -D warnings is clean. With the new check disabled, both new tests fail.
    • Windows x64 (Windows Insider 28020.3382):
      • cargo test -p openshell-supervisor --lib passes 155/155.
      • cargo clippy -p openshell-supervisor --all-targets --no-deps -- -D warnings is clean.
      • mise run windows:build:x64 succeeds.
    • Through a gateway running the MXC driver on Windows x64 (process container, wxc-exec --probe reports baseContainerApiPresent: true), with a sandbox created with read_write: [A] whose workload keeps writing to A and tries to write to B:
      • Before: policy set --wait adding B printed "Policy version 2 loaded (active version: 2)" and exited 0; policy list showed version 2 as Loaded. 25 s later the workload was still running and still could not write to B.
      • After: the same command prints "Policy version 2 failed to load: filesystem policy cannot be changed on a running sandbox; recreate the sandbox to apply filesystem changes" and exits 1; policy list shows version 2 as Failed with that error. The supervisor logs the fail-closed transition (default fail_closed). A following network-only update with the filesystem section unchanged loads as version 3. Removing a path is still rejected by the gateway, and a new sandbox created with A and B can write to B.
  • Unit tests added/updated (if applicable)
  • E2E tests added/updated (if applicable): not added. The new unit tests run the supervisor's poll loop against a scripted gateway; fix(supervisor): reject live filesystem policy changes that cannot take effect #5234 adds no E2E test either.

Not tested: ARM64, the MXC end-to-end scenarios, and the full workspace test suite. Running cargo clippy -p openshell-supervisor --all-targets -- -D warnings without --no-deps on Windows stops in openshell-extension-core (transport.rs:185, unused async), which this change does not touch.

Note for review: after a rejected revision, sandbox get lists the stored candidate policy (including the added path) together with ConfigurationInvalid, while policy get shows the active policy. This is existing gateway behaviour and is unchanged here.

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (if applicable): the policy docs row is updated; no architecture change.

Backport of NVIDIA#5234 to windows. The gateway accepts live policy updates
that only add filesystem paths, and the supervisor reported such a
revision as loaded after reloading the network policy alone. Filesystem
grants are applied when the sandbox starts (the MXC driver maps them
into the container at create), so the running workload never received
the added paths.

Compare each reload with the filesystem grants applied at startup and
reject a changed revision before replacing the running policy. The
rejection uses the existing policy validation failure handling, so the
revision is reported as failed and the configured failure mode applies.
Network-only reloads and reordered paths still load.

Closes NVIDIA#5326

Signed-off-by: Rahool Paliwal <rpaliwal@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Nov 6, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant