Repository navigation
doc: say which network policies attach no network device - #1006
Merged
Pedro Henrique Penna (ppenna) merged 1 commit intoOct 29, 2026
Merged
Conversation
doc/run.md and doc/usage.md said that a sandbox policy that "lets nothing through" attaches no network device, and listed egress denied without allow rules, ingress denied, and --host-loopback deny. That is not the rule that nvx::host::network::openvmm_arguments applies: it attaches no device exactly when a policy has no proxy, denies egress by default without allow rules, and denies ingress and host-loopback access, whatever its deny rules. Both parts of the description were too broad: - A policy can let nothing through and still attach a device. A sandbox with --network-egress deny and --host-loopback deny renders --net and both rules when it also has --network-egress-allow 192.0.2.1 and --network-egress-deny 192.0.2.0/24, whose deny rule covers the allow rule. Through the Rust API, a NetworkPolicy whose allow rule excepts its whole destination lowers to no OpenVMM rule but attaches a device too, as #1001 reports. - A proxy-only policy has every option that the documents listed, but attaches a device for its proxy. The documents also did not say which allow rules count. The CLI compiles a --network-egress-policy-file to native rules before it builds the policy, so a file whose allow rules all except their whole destinations leaves no allow rule and attaches no device, while the same rule in a typed policy of the Rust API counts. Name the condition by its options in the Sandbox networking section of doc/run.md, in its note on what changed since earlier releases, and in the --net row of the sandbox options in doc/usage.md. Say that a policy file's allow rules are those that it compiles to, that any other policy attaches a device even if it lets nothing through, and that the typed policy of the Rust API counts every allow rule. The issue also offers attaching no device for a policy whose allow rules lower to no OpenVMM rule. That would change behavior and the template key of such policies, which the open template stack, #958 and the pull requests above it, derives from this lowering; #958 even defines the device of a closed policy as the one that the same policy gets with one more such rule. So this change keeps the behavior and documents it. Fixes #1001. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues were identified for this documentation-only clarification of when NVX omits a network device.
No open issues 🎉
What changed in this PR
This documentation-only PR addresses #1001 by stating the exact network-policy conditions under which NVX attaches no network device. Runtime behavior and template keys remain unchanged.
Changes:
- Replaces “lets nothing through” with the specific options that omit a network device.
- Clarifies how compiled policy-file allow rules differ from typed Rust API rules.
- Adds an example of a policy that blocks all traffic but still attaches a device.
| File | Description |
|---|---|
doc/usage.md |
Clarifies device-attachment conditions in the sandbox --net reference. |
doc/run.md |
Explains the precise conditions, rule-counting differences, and an example; updates the historical behavior note. |
Review effort: Balanced
Pedro Henrique Penna (ppenna)
deleted the
nvx-issue-fix/1001-no-device-policies
branch
October 29, 2026 14:47
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.
Fixes #1001.
doc/run.mdanddoc/usage.mdsaid that a sandbox policy that "lets nothing through" attaches no network device.nvx::host::network::openvmm_argumentsattaches none exactly when a policy has no proxy, denies egress by default without allow rules, and denies ingress and host-loopback access, whatever its deny rules. This names that condition by its options in both documents, as the issue's first option asks, and keeps the behavior.Based on
devatfbeb563bb. One documentation commit; no code, test, or behavior changes.Problem and root cause
The documents described the condition by its effect, then listed
--network-egress denywithout allow rules, ingress denied, and--host-loopback deny.openvmm_argumentstests the policy's options instead (nvx-rs/src/host/network/arguments.rs: no proxy,egress == Deny,allow.rules.is_empty(),ingress == Deny,host_loopback == Deny), so both parts of the description were too broad:--network-egress deny --host-loopback denywith--network-egress-allow 192.0.2.1and--network-egress-deny 192.0.2.0/24, whose deny rule covers the allow rule, renders--netand both rules. Through the Rust API, aNetworkPolicywhose allow rule excepts its whole destination lowers to no OpenVMM rule but attaches a device, as the issue reports.The documents also did not say which allow rules count. The CLI compiles a
--network-egress-policy-fileto native rules before it builds the policy, asnvx-rs/README.mddescribes, so a file whose allow rules all except their whole destinations leaves no allow rule and attaches no device, while the same rule in a typed policy of the Rust API counts.Change
018ea1a34docdoc/run.md,doc/usage.mddoc/run.md, in its note on what changed since earlier releases, and in the--netrow of the sandbox options indoc/usage.md:--network-egress denyand--host-loopback deny, without allow rules,--network-ingress allow, or--network-proxy, whatever the deny rules. Says that a policy file's allow rules are those that it compiles to, that any other policy attaches a device even if it lets nothing through, with an example, and that the typed policy of the Rust API counts every allow rule.Why documentation rather than a behavior change
The issue offers two fixes: name the condition by its options, or also attach no device for a policy whose allow rules lower to no OpenVMM rule, "which also changes the template key of such a policy". This takes the first, the conservative one:
attached_arguments) as the one that the same policy gets with one more allow rule that lowers to no OpenVMM rule. nvx-rs: per-clone network policies on deny-all templates #978, later in that stack, keepsopenvmm_arguments's condition unchanged, so the documented condition stays accurate when the stack lands.The behavior change can still follow as its own issue once the template stack has landed, if maintainers want it.
Validation
Base:
devatfbeb563bb29adf085184227fde46deed29def40f. Head:018ea1a34dc54cfeb323ee81a63dd806b1665efc, signed.Reproduced on
devat the base, on Windows, before changing anything, with scratch tests that are not committed:openvmm_argumentsfor10.0.0.2/24: no arguments for a deny-all policy, with or without a deny rule;--netand the portable profile for an allow rule whoseexceptcovers its wholecidr, with no--network-egress-allowrendered; for an allow rule that a deny rule covers; for a proxy-only policy; and for a deny-all policy with host-loopback accessOutbound, the CLI's default without--host-loopback.nvx-rs sandbox run --dry-runcases in the harness ofnvx-rs/tests/cli/dry_run.rs:--network-egress deny --host-loopback denyalone renders no network option; adding--network-egress-allow 192.0.2.1 --network-egress-deny 192.0.2.0/24renders--netand both rules; and a--network-egress-policy-filewhose allow rule excepts its whole destination renders no network option.nvx-rs egress compileof that policy file prints{"allow": [], "deny": []}.At the head, on Windows:
python scripts\check_markdown_links.py;python -m compileall -q scripts; andpython -m unittest scripts/test_nvx_tools.py scripts/test_markdown_links.py scripts/test_performance.pywithNVX_RSset to a releasenvx-rsbuilt at the base (732 tests, OK, 34 skipped). They includetest_usage_documents_every_option_of_nvx_rs, which checks that the sandbox section ofdoc/usage.mdnames exactly the options ofnvx-rs sandbox --help.Hosts: none, since the change is documentation only and changes no runtime behavior.
CI: run 40892621875, attempt 1, passed on head
018ea1a34:Required status checkand the 7 other checks that ran succeeded, and the other 29 were skipped, since every path is documentation and the change selects no suite; see Change classification. Nothing is pending.Follow-ups
tests/runtime-adapter/README.md(its Networks section, the NIC rule of itscreatecommand, its test inventory, and the network checks of its VM scenarios), uses the same shorthand, as do the rustdoc ofSandboxNetwork::openvmm_argumentsinnvx-rs/src/host/sandbox/plan.rsand some comments innvx-rs/src/host/template/,nvx-rs/src/host/sandbox/plan/tests.rs, andtests/runtime-adapter/. They are left alone here: the rustdoc defers to that ofopenvmm_arguments, which states the exact condition; the comments describe the deny-all policies of their tests, for which the shorthand holds; and ten open pull requests (nvx-rs: serve shorter images, and restore clones in RAM without a scratch file #925, nvx-rs: serve clones of each processor count from one template #926, nvx-rs: export one directory to a template's clone, and map it before its start #955, nvx-rs: give each network policy a template of its own, and start network clones #958, nvx-rs: set a clone's hostname and machine ID for every execution #959, nvx-rs: mount a clone's export and set its network settings #960, runtime-adapter: refresh, list, inspect, and remove template generations #962, runtime-adapter: start and run from a template, and run the stage's scenarios as one suite #963, nvx-rs: per-clone network policies on deny-all templates #978, nvx-rs: aggregate exports for clones #992) edit that README.openvmm_argumentsreturns no arguments for a policy that attaches no device before it parses that policy's deny rules, so through the Rust API it accepts a malformed deny rule there, such asEgressRule::to("not-a-cidr")(Ok([])), although its rustdoc says that it fails for an invalid rule. The CLI is not affected, since it parses each rule withEgressRule::parse_nativebefore it builds the policy.