8000 Merge remote-tracking branch 'origin/main' into agent/2990-a-vm-host-s-own-address-box-reaches-a-host-expos · gominimal/minimal@7eedd68 · GitHub
[go: up one dir, main page]

Skip to content

Merge remote-tracking branch 'origin/main' into agent/2990-a-vm-host-…

Minimal Arch / arch-review succeeded Nov 4, 2026 in 0s

PASS

Governs: specs/networking/deployment-and-egress-gateway.md §7.1. Line 248 makes box→host reach over the alias default-deny except configured host exposures. Line 250 puts the host half in the client's [host-exposures] table, read by the host-side creator and helper as the current table for each decision. Line 251 makes host.min.internal in allow_dns_hosts the box half, at the exposed ports and no other, with CIDR coverage of the alias as the fall-through. Line 252 refuses Minimal's own listeners at each flow ahead of the exposure openings. Line 244 puts the deny of the switch's own addresses at the link, which on LocalVM is outside the VM. Line 253 binds the rule on own_ip on every host.

Ruling. NET-160 conforms. The guest relay cannot read the host's table (line 250), so on a VM host it now passes TCP and UDP frames at the alias on to the VM host daemon's gate. It does so only for a box that names the host by name or by allow_subnets coverage (line 251). I opened that gate: crates/minvmd/src/net/egress_gate.rs AliasOpenings::for_box and admit. It applies the same naming predicate, reads the current table per flow, refuses Minimal's own listeners first (line 252), and opens only an exposure's own protocol and port. The libkrun vsock shuttle lands on the gate socket (crates/minvmd/src/net/shuttle.rs), so every frame the relay passes on crosses that gate. The decisive check therefore stays outside the VM. No check moves inward across the VM boundary (rubric rule 10). The pass-on is off by default: host_gated starts false and only attach_to_switch_vsock sets it. host_alias_passed_on starts false, and a native relay never sets it, so the native leg keeps the alias at its exposure ports (rule 7). In verdict_ipv4 the switch-own check runs before the allow_subnets skip, so ICMP and other non-port frames to the alias still drop on the guest leg. The deny and protocol dimensions still decide first. The refusal now names host-alias, which is the rule string crates/minvmd/src/net/egress_gate.rs HOST_ALIAS_RULE uses. The task's observability line asks for that name. Placement is in the two layers the task names: the shared verdict in boxes::core::egress and the relay in minimald::net::switch (rule 8).

Precedent. Consistent with #2861 (37f4ead9) on line 253: the VM node's lane is enforced outside the VM. Consistent with #2997 (71d5b24f) on line 254: no routing surface is a policy bypass. Here the guest leg defers to the host gate. It does not bypass the gate. No departure.

Not checked. I did not run an end-to-end flow on a real VM host. The author also did not. NET-160's verify lines are unit tests, so no E2E leg is open. I did not compile, by contract. I did not check that the host gate admits a by-name box whose allow_subnets does not cover the alias past its later CIDR dimension. That is existing minvmd code, outside this diff, and its own test host_alias_exposure_needs_the_box_to_name_the_host covers it.

Ruled at 7eedd68 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5; arch_rulings 894, job 45defc93-31d5-4fdf-a5d9-0b1328d15ed0.

0