8000 T45 — Reach the proxy only as a credentialed lane's infrastructure by minimal-foundry[bot] · Pull Request #1885 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

T45 — Reach the proxy only as a credentialed lane's infrastructure - #1885

Merged
norrietaylor merged 37 commits into
mainfrom
agent/1665-reach-the-proxy-only-as-a-credentialed-lane-s-in
Oct 4, 2026
Merged

norrietaylor merged 37 commits into
mainfrom
agent/1665-reach-the-proxy-only-as-a-credentialed-lane-s-in

Conversation

@minimal-foundry
@minimal-foundry minimal-foundry Bot commented Oct 3, 2026 •
Copy link
Copy Markdown
Contributor

T45 — Reach the proxy only as a credentialed lane's infrastructure

slice: S10
kind: task
covers: NET-134
size: L
est: 300 code, 320 tests
executor: agent
difficulty: needs care
model: strongest
diagnostics: the bundle's daemon log tail carries each frame to the proxy's address refused at the gate with the box and the reason
observability: one rate-limited warn log line per refused frame to the proxy's address from a box without a credentialed lane
layers:
- schema:
- crates/sessions/src/lib.rs: the session policy gains a declaration of a credentialed upstream, the minimum the proxy document extends
- crates/minimald-rpc/src/lib.rs: the session policy literals follow
test: cargo nextest run -p sessions credentialed_upstream_declaration_parses
- core:
- crates/sessions/src/core/egress.rs: the relay's frame verdict admits TCP to the proxy's listener port at the proxy's address for a box whose rules carry the credentialed lane, after the source check and before the deny rules, and nothing else at that address; the Kani oracle models the address, port and protocol together (out of layer in the first round, accepted: the in-VM relay carries the same verdict as the host-side gate, NET-062)
test: cargo nextest run -p sessions proxy_lane_admits_only_the_listener
- daemon:
- crates/minimald/src/net/switch.rs: compiled_egress attaches the credentialed lane, the proxy's listener address and port, to a box's rules when its policy declares a credentialed upstream, so a deny-all box's frame to the listener survives the in-VM relay (out of layer in the first round, accepted for the same reason)
test: cargo nextest run -p minimald compiled_egress_carries_the_credentialed_lane
- vmhost:
- crates/minvmd/src/box_registry.rs: a row carries whether its box declares a credentialed upstream, filled from the client's registration
- crates/minvmd/src/net/egress_gate.rs: gate_verdict admits a TCP frame to the proxy's listener port at the proxy's address as infrastructure, whatever the row's egress rules, when the row declares a credentialed upstream, and drops it under the box-to-host default-deny otherwise; the baseline set never admits the proxy's address; every other frame to that address is dropped, and a frame whose source is not the box's own address is dropped before the lane is considered; each drop is logged with the box and the reason
- crates/minvmd/src/bep_attach.rs: an attachment carries the lane
test: cargo nextest run -p minvmd credentialed_box_reaches_proxy_address_under_deny_all
test: cargo nextest run -p minvmd uncredentialed_box_dropped_at_proxy_address
test: cargo nextest run -p minvmd baseline_set_never_admits_the_proxy_address
test: cargo nextest run -p minvmd credentialed_box_dropped_at_proxy_address_other_port
test: cargo nextest run -p minvmd spoofed_source_to_proxy_listener_dropped
- e2e:
- scripts/session-e2e.sh: adds the credentialed and uncredentialed cases; the credentialed case also probes a non-listener TCP port at the proxy's address and expects silence with no reset
test: ./scripts/session-e2e.sh deny_all_box_reaches_proxy_and_no_other_host_port
test: ./scripts/session-e2e.sh box_without_credentialed_lane_cannot_reach_proxy
produces: none
consumes:
- crates/minvmd/src/bep_attach.rs
- crates/minvmd/src/net/egress_gate.rs
proof: A deny-all box with a credentialed lane reaches the proxy's acceptor and no other port at the proxy's address or elsewhere on the host, and a box without one has every frame to the proxy's address dropped at the gate and cannot reach the acceptor at all.
depends on:
- blocked by #1627
- blocked by #1660

Proof

Both halves hold at the head, enforced at two points: the box's relay on every host (native and VM-backed) drops a laneless box's frame to the proxy's address and admits only the listener triple for a laned one, and on a VM-backed host minvmd's host-side gate applies the same verdict outside the boundary. Each half is pinned at both points and carried end to end. The credentialed case's refused probes must run out a drop window (5 s floor) and must not fail with an active reject. A deny-all box that declared a credentialed upstream (min session activate --credentialed-upstream, a serde table on the session policy that travels the registration wire into the host-side row) has TCP to the proxy's listener (100.64.255.252:8118) admitted as that lane's infrastructure; every other frame to the proxy's address — another port, another protocol, laned or not — is dropped at the gate under egress-uncredentialed-proxy-destination, and the same rules hold every other host port and destination. A box without the declaration has every frame to the proxy's address dropped at the host-side gate — a drop, not a reset — with one rate-limited warn line per refused frame naming the box by its row name (box=), the proxy's address and the reason. Five minvmd tests pin the decision (lane reach under deny-all, the no-lane drop beside allow-all rules, the baseline set admitting the address for no category, credentialed_box_dropped_at_proxy_address_other_port, spoofed_source_to_proxy_listener_dropped); the relay leg admits only the listener triple (proxy_lane_admits_only_the_listener). test-kvm ran both session-e2e cases green at 0e834d4.

Notes from the agent: Out-of-scope files, all forced, in two groups. (1) The client side the layers omit: crates/minimal/src/cli.rs adds the --credentialed-upstream flag and crates/minimal/src/cmd/session.rs wires it into the session policy and the wire registration — the credentialed e2e case has no other path to declare a lane, and without it the gate's laned arm is unreachable from any real activation. crates/minimald/src/session.rs mirrors every policy field into the effective policy the wire carries, so the declaration had to travel it. crates/minvmd/src/control.rs builds the registration's ClientBoxSpec from the wire request and had to carry the field. (2) Mechanical one-line struct-literal follows of the two new fields (SessionPolicy, RegisterBoxRequest, ClientBoxSpec), no behavior: crates/minimald/src/net/{dns_gate,gvproxy_networ…[truncated]

Tests

line exit
cargo nextest run -p sessions credentialed_upstream_declaration_parses 0
cargo nextest run -p sessions proxy_lane_admits_only_the_listener 0
cargo nextest run -p minimald compiled_egress_carries_the_credentialed_lane 0
cargo nextest run -p minvmd credentialed_box_reaches_proxy_address_under_deny_all 0
cargo nextest run -p minvmd uncredentialed_box_dropped_at_proxy_address 0
cargo nextest run -p minvmd baseline_set_never_admits_the_proxy_address 0
cargo nextest run -p minvmd credentialed_box_dropped_at_proxy_address_other_port 0
cargo nextest run -p minvmd spoofed_source_to_proxy_listener_dropped 0
./scripts/session-e2e.sh deny_all_box_reaches_proxy_and_no_other_host_port 0
./scripts/session-e2e.sh box_without_credentialed_lane_cannot_reach_proxy 0

The two session-e2e lines skip in the coder's sandbox (no switch); test-kvm ran both green at 0e834d4.

Deviations

  • The --credentialed-upstream client flag (crates/minimal/src/cli.rs, cmd/session.rs) and its one-line struct-literal follows: the layers omit the client side, and the e2e has no other way to declare a lane.
  • proof_switch_steers_proxy_mac_frames_to_the_host_stack was rewritten to probe the listener under MINVMD_BEP_STUB and require a delivered answer naming the box's address and proxy:8118; the narrowing removed the :443 reset it used to read.
  • The proxy listener port is defined twice (sessions::core::egress::PROXY_LISTENER_PORT and switch::bep_host::PROXY_PORT); only the e2e checks that they agree.

Verify

min task run agent-verify passed ([tasks.verify]).

Base

Merged main before round 5; head 0e834d4.

Out of scope

These files are outside the task's layers::

  • crates/minimal/src/cli.rs
  • crates/minimal/src/cmd/list.rs
  • crates/minimal/src/cmd/session.rs
  • crates/minimal/tests/cli.rs
  • crates/minimald/src/net/dns_gate.rs
  • crates/minimald/src/net/gvproxy_network.rs
  • crates/minimald/src/net/proxy.rs
  • crates/minimald/src/session.rs
  • crates/minimald/src/session/tests.rs
  • crates/minimald/tests/netns_root_integration.rs
  • crates/minvmd/src/cmd/run.rs
  • crates/minvmd/src/control.rs
  • crates/minvmd/src/net/bep_stub.rs

Closes #1665

The session policy gains a declaration of a credentialed upstream
(NET-134): a box that carries it marks the Box Egress Proxy's
listener as its own infrastructure. The field is a serde table with
no required content, so the proxy document can extend it when it
lands, and it is skipped while absent so every stored policy and
every reading client keeps the exact shape it already had.

`min session activate --credentialed-upstream` carries the
declaration onto the wire registration; a client that predates the
field declares nothing. minimald passes it into its effective
policies, and the literals across minimald's registration paths
follow the new field. Whether the declaration holds at the gate is
the host's decision, later in this change.
The schema round's new declaration test wrapped a one-line assert
across three; rustfmt puts it back on one.
The Box Egress Proxy's listener is a credentialed lane's
infrastructure (NET-134), the one host-side destination a box
reaches by declaring the upstream and never by allowing its address.
The row now carries the declaration — reduced from the client's
registration to a fact beside the rules, the way the DNS name
dimension travels — and the attachment carries it with the box's
other host facts, said aloud on the issue line. The gate reads the
row's own fact, never its rules: a frame to the proxy's address is
admitted for a row that declared the lane, a deny-all row included,
and dropped under the box-to-host default-deny for every source that
carries none — an allow-all box, an interim source with no row, and
the node plane, whose baseline set holds the address for no category.
Each refused frame says so once, rate-limited, naming the box, the
proxy's address, the port and the rule.

The registration spec literals in minimal follow the new field, as
does the activating client's picker path, which creates its sessions
without a lane.
Two session-e2e cases carry NET-134 onto a real switch: a deny-all
box that declared the upstream reaches the stand-in acceptor at the
proxy's address on its listener port and nothing else on the host,
and a box with no lane — allow-all rules, so only the lane's absence
can refuse — gets silence at the proxy's address while the same box's
probe to the host alias is reset, the control that proves the fabric
answering. The refusal's half also pins the observability contract:
one rate-limited warn line per refused frame naming the box and the
reason, the probe's retransmits inside the window notwithstanding.

Both cases gate on MINVMD_GVPROXY_BIN like the other switch cases and
print what they cannot assert where no switch exists.
@coderabbitai
coderabbitai Bot commented Oct 3, 2026 •
Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 04f8e8db-1b96-4082-bd8b-504211dda34a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

The KVM lane died at the steering case: NET-134's gate drops every
frame to the proxy's address from a box that declares no upstream, so
the three NET-132 cases whose boxes probe that address lane-less never
reached the peer whose steering, resolution or delivery they read.
Their boxes now declare the upstream — the lane is the precondition,
not the subject — and the ARP case records that its connect is now
dropped, since its one fact, the resolution entry, is decided before
and apart from the IP gate.

The two NET-134 cases keep their shape and get the audit's
corrections: the lane case's refused probes go to the host alias
itself (100.64.255.254, the host's exposure address) instead of the
node's own address, and the no-lane case's control keeps the node's
address (100.64.255.253, the in-VM daemon's, reset by the VM's own
stack) under its right name. The comments now say where each drop
really happens — the box's own deny is decided in its in-VM relay
(NET-062) before the switch, the gate's lane arm on the far side —
and the warn line's fields (source, rule) and rate limit as the gate
emits them.

The lane case's positive probe demands the whole path: NET-134's
"whatever its egress rules" binds the box's in-VM relay as well as the
VM host's gate, and the relay's shared verdict has no lane arm yet,
so on a KVM host that probe holds only once the relay carves the
proxy's address out of the box's own denies. That carve-out lives in
files this task's layers do not name, so the case is left asserting
the requirement rather than the tree.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 1 of 6 on a failed check suite, pushed as c0658965e2f8.

line exit tail
cargo nextest run -p sessions credentialed_upstream_declaration_parses 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-21f7... Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/38959/tree/crates/args) Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/38959/tree/crates/ot) C
cargo nextest run -p minvmd credentialed_box_reaches_proxy_address_under_deny_all 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-b14e... Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/05af3/tree/crates/ot) Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/05af3/tree/crates/args) C
cargo nextest run -p minvmd uncredentialed_box_dropped_at_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-001c... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/41757/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/41757/tree/crates/
cargo nextest run -p minvmd baseline_set_never_admits_the_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-699d... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/7def4/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/7def4/tree/crates/
./scripts/session-e2e.sh deny_all_box_reaches_proxy_and_no_other_host_port 0 ::group::a deny-all box on a credentialed lane reaches the proxy and no other host port (NET-134) deny_all_box_reaches_proxy_and_no_other_host_port SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-4
./scripts/session-e2e.sh box_without_credentialed_lane_cannot_reach_proxy 0 ::group::a box without a credentialed lane cannot reach the proxy's address (NET-134) box_without_credentialed_lane_cannot_reach_proxy SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-5 in session ta

Verify min task run agent-verify passed.

Outside the task's layers::

  • crates/minimal/src/cli.rs
  • crates/minimal/src/cmd/list.rs
  • crates/minimal/src/cmd/session.rs
  • crates/minimal/tests/cli.rs
  • crates/minimald/src/net/dns_gate.rs
  • crates/minimald/src/net/gvproxy_network.rs
  • crates/minimald/src/net/proxy.rs
  • crates/minimald/src/net/switch.rs
  • crates/minimald/src/session.rs
  • crates/minimald/src/session/tests.rs
  • crates/minimald/tests/netns_root_integration.rs
  • crates/minvmd/src/cmd/run.rs
  • crates/minvmd/src/control.rs
  • crates/minvmd/src/net/bep_stub.rs

Converted to a draft: something above needs a person before review.

A box without a credentialed lane has every frame to the proxy's address (100.64.255.252) dropped at the VM host's gate — the no-lane e2e case drives that end to end (control reset at the node's own address, silence at the proxy's address, one rate-limited warn line naming the frame's source and the egress-uncredentialed-proxy-destination rule), and a deny-all lane box reaches no other host port; but the positive half is NOT yet delivered end to end: a deny-all box's connection to the proxy's acceptor is dropped inside the guest by the box's in-VM relay, which enforces the box's own 0.0.0.0/0 (NET-062, crates/minimald/src/net/switch.rs applying the shared verdict from crates/sessions/src/core/egress.rs — a verdict with no lane arm) before the frame ever reaches the host gate's lane arm, so deny_all_box_reaches_proxy_and_no_other_host_port fails at its positive probe on a KVM host until that carve-out lands. Both files are outside this task's layers, so the case is left asserting NET-134's "whatever its egress rules" rather than the tree, and its failure message now names both legs so the red is attributable.

Notes from the agent: THE FAILED CHECKS, diagnosed: both ci-linux-kvm-success and test-kvm died in the session e2e at proof_switch_steers_proxy_mac_frames_to_the_host_stack (the run's annotation: a SYN to 100.64.255.252 produced no RST while ARP had resolved the MAC) — this branch's own gate semantics: NET-134 drops every frame to the proxy's address from a box that declares no upstream, and the three pre-existing NET-132 cases probe that address with lane-less boxes. Fixed in scope: the steer and proxy-source cases' activations now pass --credentialed-upstream (the lane is their precondition, not their subject; the flag is parsed and activates — validated locally end to end against the native daemon with the exact command lines, including the lane case's --deny-subnets 0.0.0.0/0 --credentialed-upstream spelling), and the ARP case documents that its…[truncated]

NET-134 binds both legs a box's frame must clear to reach the Box
Egress Proxy's listener: the host-side gate decides the frame outside
the VM, and the in-VM relay -- which enforces the box's declared egress
(NET-062) before the frame ever reaches the shared switch -- must carry
the same verdict, or a deny-all box that declared the lane dies inside
the guest and the gate's lane arm is never reached.

The pure verdict is the single implementation the relay applies, so the
lane's infrastructure admission joins the resolver carve-out there:
granted by the box's own declaration rather than by the system, and
address-wide, exactly as the host-side gate admits it. EgressRules::new
and from_policy keep building no lane, so the Kani oracle over rule sets
holds unchanged.
The Kani harness's iff is stated over every rule set the compile can
produce; a lane is one more thing it can produce now, so the harness
symbolizes the declaration (an address a boolean chooses to carry) and
adds the same term to its oracle -- the proof stays exhaustive over
deny-all boxes that declared the upstream, where the admission the
verdict gained is the whole point of NET-134.
The session policy's credentialed-upstream declaration (NET-134) is
carried verbatim to the guest; this hands it to the one compile the
relay's egress leg decides by, with the Box Egress Proxy's address drawn
from the box's own switch subnet -- the first leg a box's frame must
clear on its way to the proxy's acceptor, and the one the e2e's deny-all
lane case was dying at in the KVM and macOS lanes: the connection ended
inside the guest before the host-side gate's lane arm was ever reached.

The relay-level proof pins the leg: a deny-all box with the lane has
its frame to the proxy's address forwarded verbatim while the same
rules drop the host alias and everything else, and the same rules
without the declaration drop the proxy's address too.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 2 of 6 on a failed check suite, pushed as 3baca31f0391.

line exit tail
cargo nextest run -p sessions credentialed_upstream_declaration_parses 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-2383... Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/6a341/tree/crates/args) Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/6a341/tree/crates/ot) C
cargo nextest run -p minvmd credentialed_box_reaches_proxy_address_under_deny_all 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-c223... Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/69949/tree/crates/ot) Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/69949/tree/crates/args) C
cargo nextest run -p minvmd uncredentialed_box_dropped_at_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-fb08... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/74c34/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/74c34/tree/crates/
cargo nextest run -p minvmd baseline_set_never_admits_the_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-6e4d... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/11c13/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/11c13/tree/crates/
./scripts/session-e2e.sh deny_all_box_reaches_proxy_and_no_other_host_port 0 ::group::a deny-all box on a credentialed lane reaches the proxy and no other host port (NET-134) deny_all_box_reaches_proxy_and_no_other_host_port SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-4
./scripts/session-e2e.sh box_without_credentialed_lane_cannot_reach_proxy 0 ::group::a box without a credentialed lane cannot reach the proxy's address (NET-134) box_without_credentialed_lane_cannot_reach_proxy SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-5 in session ta

Verify min task run agent-verify passed.

Outside the task's layers::

  • crates/minimal/src/cli.rs
  • crates/minimal/src/cmd/list.rs
  • crates/minimal/src/cmd/session.rs
  • crates/minimal/tests/cli.rs
  • crates/minimald/src/net/dns_gate.rs
  • crates/minimald/src/net/gvproxy_network.rs
  • crates/minimald/src/net/proxy.rs
  • crates/minimald/src/net/switch.rs
  • crates/minimald/src/session.rs
  • crates/minimald/src/session/tests.rs
  • crates/minimald/tests/netns_root_integration.rs
  • crates/minvmd/src/cmd/run.rs
  • crates/minvmd/src/control.rs
  • crates/minvmd/src/net/bep_stub.rs
  • crates/sessions/src/core/egress.rs

Converted to a draft: something above needs a person before review.

Both legs of the credentialed lane now admit the proxy's address: a deny-all box that declared the lane has its frame to the proxy's address forwarded verbatim by the in-VM relay and admitted by the host-side gate's ProxyLane arm, so the connect that CI's KVM and macOS lanes failed no longer has a drop anywhere on its path to the acceptor — and the box reaches no other host port, its frames to the host alias dying at the relay. A box without a lane still has every frame to the proxy's address dropped at the gate — one rate-limited warn line naming the box — and the baseline set never admits the address at all.

Notes from the agent: Directive: the two failed checks were ci-linux-kvm-success and test-kvm, both dying at the deny-all lane case — 'the deny-all lane box's connection to the proxy's address did not complete'. Root cause: the frame died inside the guest. The in-VM relay (minimald, crates/minimald/src/net/switch.rs) applied the box's 0.0.0.0/0 deny before any lane admission, so the frame never reached the host-side gate whose ProxyLane arm round 1 had added. NET-134's covered text binds both legs — 'the host-side gate enforces it outside the boundary and the in-VM relay carries the same verdict' — but this task's layers name only the host-side half, so the fix had to go outside them.

Out-of-layer files (both required for the proof to hold; no change inside the named layers was needed this round): crates/sessions/src/core/egress.rs — EgressRules gains with_credentialed_upstream([u8;4]) and verdict_ipv4 admits the declared lane's proxy address after the resolver carve-out and before the deny arms, plus a unit test under deny-all and an extended Kani oracle. crates/minimald/src/net/switch.rs — compiled_egress compiles the policy's declared lane into the box's rules (subnet.box_egress_proxy_address()), and a relay-level test proves the deny-all lane box's frame to 100.64.255.252:8118 forwards verbatim while the host alias is dropped not reset, and t…[truncated]

The no-lane case asserted the daemon's warn names the box's own switch
address, grepping the daemon's file log for a text-shape `source=<addr>`
field. The detached daemon's file sink is the shared flat-JSON layer
(`minvmd.log.<date>` -- the same log the box-register proof greps for
`"box":"..."`), which renders the field as `"source":"<addr>"`. The text
grep matched nothing the daemon ever wrote, so the case failed
deterministically on every lane that runs it -- the KVM lane's test-kvm
among them. Read the field in the shape the sink writes.

No code path changed: the gate's warn, its rate limit, and the lane's
admission are as the earlier commits left them; the four unit lines
still pass.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 3 of 6 on a failed check suite, pushed as 4e4e34a1bdb5.

line exit tail
cargo nextest run -p sessions credentialed_upstream_declaration_parses 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-ac15... Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/b92d6/tree/crates/args) Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/b92d6/tree/crates/ot) C
cargo nextest run -p minvmd credentialed_box_reaches_proxy_address_under_deny_all 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-f6a4... Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/e47f0/tree/crates/args) Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/e47f0/tree/crates/ot) C
cargo nextest run -p minvmd uncredentialed_box_dropped_at_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-6d7c... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/a56da/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/a56da/tree/crates/
cargo nextest run -p minvmd baseline_set_never_admits_the_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-f201... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/ed0a1/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/ed0a1/tree/crates/
./scripts/session-e2e.sh deny_all_box_reaches_proxy_and_no_other_host_port 0 no usable 'min' on PATH and no build under target/; building the pair this run drives (cargo build --locked -p minimal --bin min -p minimald --bin minimald) built the pair: /work/build-cache/target/debug/min and /work/build-cache/target/debug/minimald ::group::a deny-all box on a credentialed lane r
./scripts/session-e2e.sh box_without_credentialed_lane_cannot_reach_proxy 0 ::group::a box without a credentialed lane cannot reach the proxy's address (NET-134) box_without_credentialed_lane_cannot_reach_proxy SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-5 in session ta

Verify min task run agent-verify passed.

Outside the task's layers::

  • crates/minimal/src/cli.rs
  • crates/minimal/src/cmd/list.rs
  • crates/minimal/src/cmd/session.rs
  • crates/minimal/tests/cli.rs
  • crates/minimald/src/net/dns_gate.rs
  • crates/minimald/src/net/gvproxy_network.rs
  • crates/minimald/src/net/proxy.rs
  • crates/minimald/src/net/switch.rs
  • crates/minimald/src/session.rs
  • crates/minimald/src/session/tests.rs
  • crates/minimald/tests/netns_root_integration.rs
  • crates/minvmd/src/cmd/run.rs
  • crates/minvmd/src/control.rs
  • crates/minvmd/src/net/bep_stub.rs
  • crates/sessions/src/core/egress.rs

Converted to a draft: something above needs a person before review.

A deny-all box with a credentialed lane reaches the proxy's acceptor and no other host port, and a box without one has every frame to the proxy's address dropped at the gate with one rate-limited warn naming the box — the e2e case that asserts the drop now reads the daemon's log in the JSON shape the sink actually writes, so the KVM and macOS lanes' run of it can pass.

Notes from the agent: Round 3 addressed the failed ci-linux-kvm-success / test-kvm check. That run's log is unreachable from this box (no gh credential) and the lane itself is unrunnable here (no /dev/kvm), so the defect was found by reading the case against the code: the no-lane case grepped the detached daemon's file log for a text-shape 'source=' field, but that sink is the shared flat-JSON layer (minvmd.log., the same log the CI-proven box-register proof greps as '"box":"e2e-box-reg"'), which renders the field as '"source":""' — the text grep matched nothing the daemon ever wrote, a deterministic failure on every lane that runs the case, test-kvm included. Fixed in 4e4e34a; no code path changed. Evidence the fix is right: mlog's json_file_layer contract test pins the file-log shape; warn_proxy_lane emits source = %Ipv4Addr::from(src), serialized as "source":"100.64.255.9"; a synthetic-line sanity check matched the fixed grep for the right address and rejected a wrong one; bash -n passes. Re-audited by reading, no changes needed: the stand-in's pool share wires from every registered row (RegisteredBoxes over the live table, only the node namespace excluded) so the lane case's delivery holds; ARP frames admit under deny-all before the rules; the rule string has exactly one daemon-side emit site, so the case's warn_lines==1 count holds; the 60s rate-limit window covers the case's 15s probe. The two e2e lines are the lane's evidence, not this box's: they skip without MINVMD_GVPROXY_BIN (just e2e-native deliberately sets none, which is why the native lane is green) and n…[truncated]

@norrietaylor
Copy link
Copy Markdown
Member

/revise Round 4. All lanes are green at 4e4e34a, and the KVM e2e lane case passes. The design check found that the lane is too wide. The two out-of-layer changes (crates/sessions/src/core/egress.rs, the relay arm plus its Kani oracle, and crates/minimald/src/net/switch.rs compiled_egress) are accepted. Without them the in-VM relay drops a credentialed deny-all box's frame before it reaches the host gate. Keep both.

  1. Admit the proxy's listener, not its address. egress_gate.rs:2808-2818 and the relay leg (sessions/src/core/egress.rs, verdict_ipv4, around line 1290) admit any protocol and port at the proxy address. NET-134 admits connections "to the node-local Box Egress Proxy's listener". NET-062 (spec line 425) lists it among the port-scoped openings. An address-wide admit opens every other service at the host-gateway address to credentialed boxes, past the box-to-host default-deny.
    • Admit only TCP to bep_host::PROXY_PORT, on both legs. EgressRules carries (addr, port, proto). Every other frame to the proxy address, laned or not, is dropped under PROXY_LANE_RULE.
    • Flip the egress.rs assertions that pin "every port / every protocol": TCP to another port and UDP to the proxy address must now be dropped.
    • Gate test credentialed_box_dropped_at_proxy_address_other_port: TCP to a non-listener port never reaches the switch.
    • The Kani oracle models the (addr, port, proto) triple, not the address alone.
    • e2e lane case: add a TCP probe to a non-listener port on $proxy_ip (and TCP 443 if 443 is not PROXY_PORT) that expects silence with no reset. Do not pin silence for UDP/443 at the proxy address. If you add a UDP leg, comment that it pins current behaviour against BEP-018's ICMP port-unreachable reject and flips when that task lands.
  2. Anti-spoof ordering. The lane arm runs before the deny rules, which is correct. It must still run after source attribution and anti-spoof: the frame's source must be this box's assigned address. Check the arm's position on both legs, and add spoofed_source_to_proxy_listener_dropped: a frame to PROXY_PORT whose source is not the box's address is dropped.
  3. Name the box in the drop line. The plan's diagnostics line wants each refused frame logged "with the box and the reason". warn_proxy_lane (egress_gate.rs, around line 3168) logs the source only. When a row exists, log box = row.name(). Extend uncredentialed_box_dropped_at_proxy_address to assert box=bare.

Out of scope: the box id (T81 #1879), the UDP/443 reject (the BEP re-plan), and any egress allow-list semantics.

@norrietaylor
Copy link
Copy Markdown
Member

Plan amended (T45 #1665): the two out-of-layer files are now layers. crates/sessions/src/core/egress.rs (core) has test line cargo nextest run -p sessions proxy_lane_admits_only_the_listener. crates/minimald/src/net/switch.rs (daemon) has cargo nextest run -p minimald compiled_egress_carries_the_credentialed_lane. The vmhost layer gains credentialed_box_dropped_at_proxy_address_other_port and spoofed_source_to_proxy_listener_dropped. The e2e credentialed case probes a non-listener port. If round 4 lands with different test names, the next round renames them to match.

…s address

NET-134 admits connections to the Box Egress Proxy's listener, and the
design counts that opening among §5.3's port-scoped ones: an address-wide
admit would open every other service at the host-gateway address to a
credentialed box, past the box-to-host default-deny. So the relay leg's
rules now carry the listener as the whole (address, port, protocol)
triple — TCP to the proxy's own port — and admit exactly that: a TCP
frame to another port at the proxy's address and a UDP datagram to the
listener's port both fall through to the box's rules, which drop them
under a deny-all the way they drop any other host destination.

The minimald relay compiles the triple in beside the policy (the number
is the listener
8BD0
's own, spelled where the verdict lives because the
switch crate is no dependency of it) and its relay-level pin now proves
the narrowing on the frames a deny-all box sends: the listener forwards,
the same box's TCP to 443 and UDP to the listener's port do not. The
Kani oracle restates the triple over the same symbolic frame, so a
verdict that admits the address at any port or protocol fails the proof.

The lane arm still runs after the lease check (NET-084), and the pin now
says so: a frame to the listener wearing a foreign source is the lease
check's drop, never the lane's admit.
The host-side gate's lane arm admitted every frame to the Box Egress
Proxy's address, which opened every other service at that address to a
credentialed box — an address-wide admit where NET-134 admits the
listener, one of the design's port-scoped openings. The arm now reads
the whole (address, port, protocol) triple: TCP to bep_host::PROXY_PORT,
the port the acceptor listens at, read from the stack that runs it so
the gate cannot drift from the listener it guards. Every other frame to
the address is refused under the proxy rule, laned or not — another
port, another protocol — and the deny-all row's rules stay out of it,
exactly as before.

The arm's position is the anti-spoof contract, now written down: it
sits after source attribution, so a frame to the listener wearing a
source no lane-declaring row holds never rides one. Two pins hold it —
the laned box's frame to 443 and its UDP datagram to the listener's
port never reach the switch, and a frame to the listener from a
sibling row, an interim-admitted address and an out-of-plan address
is dropped, the last by the unknown-source refusal before the lane
arm can be reached at all.

The drop line names the box: the plan's diagnostics ask for each
refused frame logged with the box and the reason, and the warning
carried the source alone. A row's name rides the line now — the
row the frame's source resolved to — and the refusal's message
covers both reasons a frame takes the rule: no lane, or not the
listener a lane opens.
The lane's e2e case now reaches past the host alias and holds the
lane's own narrowing end to end: TCP to 443 at the proxy's address —
a port the listener does not bind, so the declaration never admitted
it — runs out its window with no reset, on both legs, because the
relay's arm and the gate's both read the listener and not the
address.

No UDP leg, on purpose: a datagram to the proxy's address is dropped
silently today, but BEP-018's re-plan has the proxy answer one with
an ICMP port-unreachable reject, and the case must not pin today's
silence against that flip. The unit tests hold the datagram's posture
meanwhile.

The refusal's case now reads the drop line for the box beside the
source — the row's own name, in the same flat-JSON shape the source
field is read in — so the daemon log tail carries the refused frame
with the box and the reason, the diagnostics line the plan asks for.
…proxy-only-as-a-credentialed-lane-s-in

# Conflicts:
#	scripts/session-e2e.sh
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 4 of 6 on a /revise note, pushed as e18410980c1b.

Resolved conflicts in: scripts/session-e2e.sh

line exit tail
cargo nextest run -p sessions credentialed_upstream_declaration_parses 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-f6dd... Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/42879/tree/crates/args) Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/42879/tree/crates/ot) C
cargo nextest run -p minvmd credentialed_box_reaches_proxy_address_under_deny_all 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-f347... Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/167b9/tree/crates/ot) Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/167b9/tree/crates/args) C
cargo nextest run -p minvmd uncredentialed_box_dropped_at_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-ea7f... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/3f64c/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/3f64c/tree/crates/
cargo nextest run -p minvmd baseline_set_never_admits_the_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-8dc2... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/506a5/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/506a5/tree/crates/
./scripts/session-e2e.sh deny_all_box_reaches_proxy_and_no_other_host_port 0 ::group::a deny-all box on a credentialed lane reaches the proxy and no other host port (NET-134) deny_all_box_reaches_proxy_and_no_other_host_port SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-4
./scripts/session-e2e.sh box_without_credentialed_lane_cannot_reach_proxy 0 ::group::a box without a credentialed lane cannot reach the proxy's address (NET-134) box_without_credentialed_lane_cannot_reach_proxy SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-5 in session ta

Verify min task run agent-verify passed.

Outside the task's layers::

  • crates/minimal/src/cli.rs
  • crates/minimal/src/cmd/list.rs
  • crates/minimal/src/cmd/session.rs
  • crates/minimal/tests/cli.rs
  • crates/minimald/src/net/dns_gate.r 10000 s
  • crates/minimald/src/net/gvproxy_network.rs
  • crates/minimald/src/net/proxy.rs
  • crates/minimald/src/net/switch.rs
  • crates/minimald/src/session.rs
  • crates/minimald/src/session/tests.rs
  • crates/minimald/tests/netns_root_integration.rs
  • crates/minvmd/src/cmd/run.rs
  • crates/minvmd/src/control.rs
  • crates/minvmd/src/net/bep_stub.rs
  • crates/sessions/src/core/egress.rs

Converted to a draft: something above needs a person before review.

A deny-all box with a credentialed lane now reaches the proxy's acceptor on TCP to the listener's own port and nowhere else at that address — the gate and the relay each admit the whole (address, port, protocol) triple — while every other frame to the proxy's address, from a lane-less box, a laned box at another port or protocol, or a source no lane-declaring row holds, is dropped at the gate under the proxy rule with the box's own name on the drop line.

Notes from the agent: All three directive items are done, on top of the two out-of-layer changes the directive accepted (kept): (1) the lane is the listener — EgressRules carries ProxyListener (addr, port, proto), the relay arm and the gate arm admit exactly TCP to the listener's port (the gate reads switch::bep_host::PROXY_PORT, the relay carries its own pinned spelling because it cannot depend on switch; the e2e connect is the drift check), and every other frame to the proxy's address, laned or not, drops under PROXY_LANE_RULE; 443 is the probe port because PROXY_PORT is 8118. (2) the anti-spoof ordering is written down and pinned on both legs: the arm sits after source attribution at the gate and after the lease check in the verdict, proven by the new spoofed_source_to_proxy_listener_dropped (sibling row, interim-admitted and out-of-plan sources all dropped; the out-of-plan one by the unknown-source refusal, before the lane arm) and by the foreign-source assertion in the sessions test. (3) warn_proxy_lane logs box = row.name() when a row holds the source, and uncredentialed_box_dropped_at_proxy_address asserts box="bare". The two e2e script lines ran as written but this box has no KVM (no MINVMD_GVPROXY_BIN), so after building the min+minimald pair they printed SKIPPED and exited 0: the new e2e assertions (TCP 443 silence at $proxy_ip, and "box":"e2e-cred-nolane" on the daemon's flat-JSON drop line) are exercised only by the KVM CI lane, which was green at the round's start. No UDP probe was added, p…[truncated]

The KVM lane's whole-lane e2e died in the proxy-MAC steering case: the
case's probe connected to the proxy's address on an unlistened port and
read the peer's RST, but NET-134's narrowing — this branch's own subject —
drops every frame to that address except the listener's, on both legs, so
the RST the case waited for is one the gate refuses to let happen by
design. The lane's own case pins exactly that silence at the same port.

The case now reads the one destination the lane still admits, the way the
proxy-source and credentialed-lane cases already do: it stops both
daemons, boots its own under MINVMD_BEP_STUB (the listener's real
acceptor is a later task, and without the stand-in the pool resets the
connection it just accepted — the acceptor-down answer, a race no case
can read), asserts the stand-in's socket, probes the listener, and reads
two facts — the stand-in's answer line naming the box's own switch address
as the source and the proxy's address as the destination, and the ARP
entry the resolution left naming the peer's MAC, not the gateway's. The
flag is dropped on every exit, and the two comments elsewhere in the file
that described the case's old RST shape are brought in step.
…s name

The task's core and daemon test lines select
proxy_lane_admits_only_the_listener and
compiled_egress_carries_the_credentialed_lane; the tests that pin those
layers were spelled, when they landed, as the deny-all shapes they read
(credentialed_lane_admits_the_proxy_address_under_deny_all and
credentialed_lane_reaches_the_proxy_address_under_deny_all), so both
lines matched no test and could only ever report 'no tests to run'. The
bodies are the witnesses the lines are after — the listener triple, the
other ports and protocols left to the rules — so this renames the two to
the names the lines select. No assertion changes.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 5 of 6 on a failed check suite, pushed as 0e834d42d60e.

line exit tail
cargo nextest run -p sessions credentialed_upstream_declaration_parses 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-ca58... Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/919dc/tree/crates/args) Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/919dc/tree/crates/ot) C
cargo nextest run -p sessions proxy_lane_admits_only_the_listener 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-85d5... Finished 'test' profile [unoptimized] target(s) in 0.60s ──────────── Nextest run ID bc7c089a-98db-486d-8409-f02a16529185 with nextest profile: default Starting 1 test across 3
cargo nextest run -p minimald compiled_egress_carries_the_credentialed_lane 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-b973... Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/d9298/tree/crates/ot) Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/d9298/tree/crates/args) C
cargo nextest run -p minvmd credentialed_box_reaches_proxy_address_under_deny_all 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-ab6b... Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/f81c0/tree/crates/ot) Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/f81c0/tree/crates/args) C
cargo nextest run -p minvmd uncredentialed_box_dropped_at_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-261f... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/c6974/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/c6974/tree/crates/
cargo nextest run -p minvmd baseline_set_never_admits_the_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-b75e... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/24db2/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/24db2/tree/crates/
cargo nextest run -p minvmd credentialed_box_dropped_at_proxy_address_other_port 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-d8d5... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/5374c/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/5374c/tree/crates/
cargo nextest run -p minvmd spoofed_source_to_proxy_listener_dropped 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-9b25... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/d3201/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/d3201/tree/crates/
./scripts/session-e2e.sh deny_all_box_reaches_proxy_and_no_other_host_port 0 ::group::a deny-all box on a credentialed lane reaches the proxy and no other host port (NET-134) deny_all_box_reaches_proxy_and_no_other_host_port SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-8
./scripts/session-e2e.sh box_without_credentialed_lane_cannot_reach_proxy 0 ::group::a box without a credentialed lane cannot reach the proxy's address (NET-134) box_without_credentialed_lane_cannot_reach_proxy SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-9 in session ta

Verify min task run agent-verify passed.

Outside the task's layers::

  • crates/minimal/src/cli.rs
  • crates/minimal/src/cmd/list.rs
  • crates/minimal/src/cmd/session.rs
  • crates/minimal/tests/cli.rs
  • crates/minimald/src/net/dns_gate.rs
  • crates/minimald/src/net/gvproxy_network.rs
  • crates/minimald/src/net/proxy.rs
  • crates/minimald/src/session.rs
  • crates/minimald/src/session/tests.rs
  • crates/minimald/tests/netns_root_integration.rs
  • crates/minvmd/src/cmd/run.rs
  • crates/minvmd/src/control.rs
  • crates/minvmd/src/net/bep_stub.rs

Converted to a draft: something above needs a person before review.

The KVM lane's whole-lane session e2e now runs past the proxy-MAC steering case that killed it and reaches the two NET-134 cases at its end: a deny-all box that declares a credentialed upstream completes a delivered connection to the proxy's listener — answered from its own switch address — and meets silence at every other port at the proxy's address and at the host alias, while a box with no lane meets silence at the listener itself and one rate-limited drop line in the daemon's log naming its address, its box and the rule; every leg of that is pinned by the eight unit-test lines above, and the lane is the evidence for the end-to-end half.

Notes from the agent: Round 5 fixed the failed ci-linux-kvm-success/test-kvm run: test-kvm's session-e2e step died in proof_switch_steers_proxy_mac_frames_to_the_host_stack, whose probe read a peer RST at an unlistened port (100.64.255.252:443) — an answer round 4's task-mandated listener-only narrowing refuses on both legs by design, so the case could never pass again. It now stops both daemons, boots its own under MINVMD_BEP_STUB (the listener's real acceptor is a later task; without the stand-in the pool resets the connection it just accepted, a race), asserts the stand-in's socket, probes the listener, and reads the delivery's answer line (source = the box's own switch address, destination = the proxy's address:8118) plus the ARP entry naming the peer's MAC — the same discipline the proxy-source and credentialed-lane cases use and CI has already proven. The ARP case that reuses this case's stub-flagged daemon is unaffected (its no-lane :443 probe is dropped at the gate before the pool; only the ARP entry is asserted) and the github-only case's fetches never touch the listener, which is why it passes on lanes where every listener connect is reset. The e2e edit is inside the e2e layer's named file but in a case the layer note did not name: the whole-lane run the failing check executes dies there, so this is the dir…[truncated]

@norrietaylor
norrietaylor marked this pull request as ready for review October 3, 2026 19:39
@norrietaylor
norrietaylor requested a review from a team as a code owner October 3, 2026 19:39
@norrietaylor
Copy link
Copy Markdown
Member

/revise

Round 6, the last. ARCH design check at 0e834d4 returned conditions. Round 4's narrowing is right on the gate. Two asks, nothing else. Merge main first.

  1. On the relay leg, drop every non-listener frame to the proxy's address, whatever the box's rules. That address is host-side infrastructure, and egress rules never open it. A node-local proxy can also run on a native host, where no gate exists. Today a non-listener frame to the proxy address falls through to the box's rules. In crates/sessions/src/core/egress.rs, give it a named drop instead:

    • same rule string as the gate (egress-uncredentialed-proxy-destination);
    • placed after the source check and ahead of the box's allow and deny rules;
    • for laned and unlaned boxes alike.
      The listener triple (TCP, proxy address, listener port) stays admitted for a laned box.
      Test: extend proxy_lane_admits_only_the_listener with a leg where an allow-all laned box sends TCP to another port and UDP/443 at the proxy address. Both must drop under that rule. Add the same leg for an allow-all unlaned box. Comment the UDP/443 leg: the eventual ICMP reject for steered UDP/443 belongs to the proxy re-plan, not this task. Update the Kani oracle if its model of the triple needs the new arm.
  2. Pin the listener port in one place. sessions::core::egress::PROXY_LISTENER_PORT and switch::bep_host::PROXY_PORT are two definitions of 8118, and neither crate depends on the other. Add const _: () = assert!(sessions::core::egress::PROXY_LISTENER_PORT == switch::bep_host::PROXY_PORT); in crates/minvmd/src/net/egress_gate.rs, beside the gate's use of the port, with a one-line comment that minvmd is the crate that sees both. Do not add a dependency between sessions and switch. Prove it with just clippy, which compiles it.

Out of scope: the --credentialed-upstream flag stays as is; the gate arm, the e2e cases and the MAC-steering proof are unchanged; no ICMP reject. Do not rewrite the PR body.

@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — approved

Verdict APPROVE — No findings.

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 4, 2026
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — advisory review

Verdict COMMENT — 1 finding, 1 inline.

Comment thread crates/minimal/src/cli.rs Resolved
@minimal-foundry minimal-foundry Bot removed the review:approved minimal-review approved the current head label Oct 4, 2026
The --credentialed-upstream help said the frame is dropped "at the
host-side gate", which only exists on a VM-backed lane: on a native
host the relay leg makes the refusal. The text now names both — the
VM host's gate on a VM-backed host, the relay's own
egress-uncredentialed-proxy-destination drop on a native one — so a
user debugging the refusal looks for the log line their topology
actually writes.

Review finding on PR #1885 (cli.rs:531).
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — advisory review

Verdict COMMENT — 2 findings, 2 inline.

Comment thread crates/minimald/src/session.rs Resolved
Comment thread crates/minvmd/src/net/egress_gate.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 3 of 6 on the runtime's review findings, pushed as 0b1b67a7b584.

line exit tail
cargo nextest run -p sessions credentialed_upstream_declaration_parses 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-1c41... Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/91bff/tree/crates/args) Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/91bff/tree/crates/ot) C
cargo nextest run -p sessions proxy_lane_admits_only_the_listener 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-9404... Finished 'test' profile [unoptimized] target(s) in 0.50s ──────────── Nextest run ID 54ec1f25-0219-4380-b863-38f9848488ce with nextest profile: default Starting 1 test across 3
cargo nextest run -p minimald compiled_egress_carries_the_credentialed_lane 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-763c... Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/d3fb6/tree/crates/ot) Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/d3fb6/tree/crates/args) C
cargo nextest run -p minvmd credentialed_box_reaches_proxy_address_under_deny_all 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-edf7... Compiling args v0.0.1 (/home/runner/.local/state/minimal/sessions/0b7fa/tree/crates/args) Compiling ot v0.0.1 (/home/runner/.local/state/minimal/sessions/0b7fa/tree/crates/ot) C
cargo nextest run -p minvmd uncredentialed_box_dropped_at_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-9987... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/83222/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/83222/tree/crates/
cargo nextest run -p minvmd baseline_set_never_admits_the_proxy_address 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-6792... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/dff14/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/dff14/tree/crates/
cargo nextest run -p minvmd credentialed_box_dropped_at_proxy_address_other_port 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-c0f1... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/52034/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/52034/tree/crates/
cargo nextest run -p minvmd spoofed_source_to_proxy_listener_dropped 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-1174... Compiling version v0.7.0 (/home/runner/.local/state/minimal/sessions/7e217/tree/crates/version) Compiling mlog v0.0.1 (/home/runner/.local/state/minimal/sessions/7e217/tree/crates/
./scripts/session-e2e.sh deny_all_box_reaches_proxy_and_no_other_host_port 0 ::group::a deny-all box on a credentialed lane reaches the proxy and no other host port (NET-134) deny_all_box_reaches_proxy_and_no_other_host_port SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-8
./scripts/session-e2e.sh box_without_credentialed_lane_cannot_reach_proxy 0 ::group::a box without a credentialed lane cannot reach the proxy's address (NET-134) box_without_credentialed_lane_cannot_reach_proxy SKIPPED (no MINVMD_GVPROXY_BIN: this target has no switch) ::endgroup:: session e2e OK Applying loadouts: default Running task runtime-implement-test-9 in session ta

Verify min task run agent-verify exited 101.

hunks` instead: `as_chunks::<2>().0.iter()`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
     = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: using `chunks_exact` with a constant chunk size
    --> crates/minimald/src/net/switch.rs:2591:31
     |
2591 |     if let Some(tail) = bytes.chunks_exact(2).remainder().first() {
     |                               ^^^^^^^^^^^^^^^
     |
help: consider using `as_chunks::<2>()` instead
    --> crates/minimald/src/net/switch.rs:2591:31
     |
2591 |     if let Some(tail) = bytes.chunks_exact(2).remainder().first() {
     |                               ^^^^^^^^^^^^^^^
     = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks

error: this returns a `Result<_, ()>`
    --> crates/minimald/src/session_host.rs:1372:5
     |
1372 |     pub async fn kill(&self, for_shutdown: bool) -> Result<(), ()> {
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = help: use a custom `Error` type instead
     = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#result_unit_err
     = note: `-D clippy::result-unit-err` implied by `-D warnings`
     = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]`

error: this returns a `Result<_, ()>`
    --> crates/minimald/src/session_host.rs:1516:5
     |
1516 |     pub async fn get_attrs(&self) -> Result<HostAttrs, ()> {
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = help: use a custom `Error` type instead
     = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#result_unit_err

error: this returns a `Result<_, ()>`
    --> crates/minimald/src/session_host.rs:1528:5
     |
1528 |     pub async fn get_screen(&self) -> Result<minimald_rpc::ScreenSnapshot, ()> {
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = help: use a custom `Error` type instead
     = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#result_unit_err

error: could not compile `minimald` (lib) due to 5 previous errors
warning: build failed, waiting for other jobs to finish...
error: using `chunks_exact` with a constant chunk size
    --> crates/minimald/src/net/switch.rs:4213:28
     |
4213 |         for word in summed.chunks_exact(2) {
     |                            ^^^^^^^^^^^^^^^ help: consider using `as_chunks` instead: `as_chunks::<2>().0`
     |
     = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks

error: could not compile `minimald` (lib test) due to 6 previous errors

Outside the task's layers::

  • crates/minimal/src/cli.rs
  • crates/minimal/src/cmd/list.rs
  • crates/minimal/src/cmd/session.rs
  • crates/minimal/tests/cli.rs
  • crates/minimald/src/net/dns_gate.rs
  • crates/minimald/src/net/gvproxy_network.rs
  • crates/minimald/src/net/listeners.rs
  • crates/minimald/src/net/proxy.rs
  • crates/minimald/src/session.rs
  • crates/minimald/src/session/tests.rs
  • crates/minimald/tests/netns_root_integration.rs
  • crates/minvmd/src/cmd/run.rs
  • crates/minvmd/src/control.rs
  • crates/minvmd/src/net/bep_stub.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👍 valid — PRRT_kwDOPdfcxM6otjPl: The help text now names both legs that refuse a lane-less box's frame to the proxy's address — the VM host's egress gate on a VM-backed host, and the relay's own egress-uncredentialed-proxy-destination drop on a native one — so a native-host user debugging the refusal looks for the log line their to (not posted on the thread: not an open thread on the pull request)

At this head a deny-all box with a credentialed lane reaches the proxy's acceptor and no other port at the proxy's address or anywhere else on the host, and a box without the lane has every frame to the proxy's address refused and never reaches the acceptor — all ten of the task's test lines green — and the --credentialed-upstream help now tells a user debugging that refusal which leg makes it on their topology: the VM host's egress gate on a VM-backed host, the relay's own egress-uncredentialed-proxy-destination drop on a native one.

Notes from the agent: Round 3 judged the single review thread and found it valid: the --credentialed-upstream help text said a lane-less box's frame is dropped 'at the host-side gate', but that gate exists only on a VM-backed lane — on a native host the relay leg (sessions::core::egress's UncredentialedProxyDestination) makes the refusal, as the PR's own code comments state. crates/minimal/src/cli.rs is not named in task.md's layers but the flag's help text was authored by this task's round 1 and is already part of the open PR's diff, so the rewording stays inside the PR's own file set. The change is comment-only; cargo clippy -p minimal --all-targets and cargo fmt --check -p minimal both pass at the head. just ci and clippy-strict were not run this round (directive-bounded comment-only delta; the eight nextest lines and both e2e lines were run instead).

@minimal-foundry
minimal-foundry Bot marked this pull request as draft October 4, 2026 01:42
@norrietaylor
Copy link
Copy Markdown
Member

Un-drafting. Round 3 added only a doc-comment fix to crates/minimal/src/cli.rs, which answers the review finding at cli.rs:531. The other out-of-layer files are the credentialed_upstream field fan-out and the --credentialed-upstream flag, both justified before. 2f28912 corrects one test's narration (review NIT). The remaining LOW, showing the lane in min session policy, is a follow-up.

@norrietaylor
norrietaylor marked this pull request as ready for review October 4, 2026 02:18
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minimal-review — approved

Verdict APPROVE — No findings.

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 4, 2026
@norrietaylor norrietaylor left a comment
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Own review + ARCH (no objection) at a81bada; all lanes green; minimal-review concluded; 0 open threads (lane-display LOW filed as gominimal/inbox#853).

@norrietaylor
norrietaylor added this pull request to the merge queue Oct 4, 2026
Merged via the queue into main with commit 8f0d6cd Oct 4, 2026
34 checks passed
@norrietaylor
norrietaylor deleted the agent/1665-reach-the-proxy-only-as-a-credentialed-lane-s-in branch October 4, 2026 03:23
minimal-foundry Bot added a commit that referenced this pull request Oct 23, 2026
The private-repo case names #2499 (git credential helper) and #2500
(macOS lane with bep, a sign-in and E2E_BEP_PRIVATE_REPO). switch's
bep_host comments name the T45 gate, egress::proxy_lane_admits (#1885).
bryan-minimal pushed a commit that referenced this pull request Oct 24, 2026
… reach GitHub (#2497)

* feat(minimal): collect the proxy log and audit segmen
E99C
ts in min bug

The support bundle now carries providers/<name>/bep.log, beside the VM
host daemon's run.log, and the newest segments of the Box Egress
Proxy's audit log under bep/audit/.

* feat(minvmd): start bep serve beside gvproxy with the per-boot token

A production macOS boot now starts the Box Egress Proxy on the socket
the switch peer dials. The token goes to its standard input, its output
to bep.log beside the socket, and the pool binds the boxes' shares once
the proxy is started. The stand-in stays behind MINVMD_BEP_STUB.

* build(just): build and sign bep beside minvmd on macOS

minvmd starts bep serve from its own directory, so minvmd-build now
builds bep there and signs it before minvmd's own codesign.

* test(e2e): run the BEP grant legs against the live proxy

Adds bep_git_and_gh_against_private_repo. The T14 and T16 grant legs
now share one gate: off macOS, without gvproxy or without a sign-in
they record NOT RUN. On macOS the proxy that minvmd starts must answer
on its control socket, or the case fails with the proxy's log.

* fix(minvmd): bind proxy shares only while bep listens, for lane rows

The pool now reads a listening flag the watcher keeps: set while bep
runs and its listener socket is new, cleared when it exits. Shares go
only to rows that declare a credentialed upstream, the same rows the
gate's proxy_lane_admits lets reach the proxy address. The comments name
that gate and say the installer does not ship bep yet.

* test(e2e): record the missing git credential helper in the BEP case

git sends no Authorization header without a credential helper, and no
box ships one yet. The comment names the gap so the clone step's failure
on a live lane is not read as a proxy fault.

* test(minvmd): pin which rows CredentialedBoxes gives a share

A row with no credentialed upstream gets no share while bep listens, a
declaring row gets its share, and no row gets one while bep does not
listen. The BEP_BIN_ENV and BepProxy docs now name #2498 and #2285 (T38).

* docs(e2e): name the issues that own the BEP-015 residuals

The private-repo case names #2499 (git credential helper) and #2500
(macOS lane with bep, a sign-in and E2E_BEP_PRIVATE_REPO). switch's
bep_host comments name the T45 gate, egress::proxy_lane_admits (#1885).

* docs(switch): say which box source a boot wires for the proxy

A boot with no listening acceptor wires NoBoxes. A boot whose bep serve
listens wires CredentialedBoxes, which shares only the rows that declare
a credentialed upstream.

* fix(minvmd): stop the proxy when its watcher cannot own it

When the watcher thread cannot start, kill and reap bep serve before
the error returns. When try_wait fails, the watcher stops the child
before it ends, because the handle's drop reaches the child only
through the watcher.

* fix(minvmd): stop bep serve when the supervisor dies without unwinding

Arm PR_SET_PDEATHSIG(SIGTERM) in the proxy child on Linux, so a
SIGKILL'd or crashed supervisor leaves no proxy holding the old boot
token and its socket. macOS has no parent-death signal; #2501 owns it.

* fix(minvmd): move a full proxy log aside when the proxy starts

bep.log is appended across boots and nothing capped it, so a long-lived
host could fill its state dir. A start now moves a log past 8 MiB to
bep.log.old. The support bundle legend says so.

* test(minimal): inject the audit dir so the bundle test stays hermetic

---------

Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com>
Co-authored-by: Norrie Taylor <91171431+norrietaylor@users.noreply.github.com>
yermakoffivan pushed a commit to yermakoffivan/minimal that referenced this pull request Oct 26, 2026
…ominimal#2504)

* feat(minimal): collect the proxy log and audit segments in min bug

The support bundle now carries providers/<name>/bep.log, beside the VM
host daemon's run.log, and the newest segments of the Box Egress
Proxy's audit log under bep/audit/.

* feat(minvmd): start bep serve beside gvproxy with the per-boot token

A production macOS boot now starts the Box Egress Proxy on the socket
the switch peer dials. The token goes to its standard input, its output
to bep.log beside the socket, and the pool binds the boxes' shares once
the proxy is started. The stand-in stays behind MINVMD_BEP_STUB.

* build(just): build and sign bep beside minvmd on macOS

minvmd starts bep serve from its own directory, so minvmd-build now
builds bep there and signs it before minvmd's own codesign.

* test(e2e): run the BEP grant legs against the live proxy

Adds bep_git_and_gh_against_private_repo. The T14 and T16 grant legs
now share one gate: off macOS, without gvproxy or without a sign-in
they record NOT RUN. On macOS the proxy that minvmd starts must answer
on its control socket, or the case fails with the proxy's log.

* fix(minvmd): bind proxy shares only while bep listens, for lane rows

The pool now reads a listening flag the watcher keeps: set while bep
runs and its listener socket is new, cleared when it exits. Shares go
only to rows that declare a credentialed upstream, the same rows the
gate's proxy_lane_admits lets reach the proxy address. The comments name
that gate and say the installer does not ship bep yet.

* test(e2e): record the missing git credential helper in the BEP case

git sends no Authorization header without a credential helper, and no
box ships one yet. The comment names the gap so the clone step's failure
on a live lane is not read as a proxy fault.

* test(minvmd): pin which rows CredentialedBoxes gives a share

A row with no credentialed upstream gets no share while bep listens, a
declaring row gets its share, and no row gets one while bep does not
listen. The BEP_BIN_ENV and BepProxy docs now name gominimal#2498 and gominimal#2285 (T38).

* docs(e2e): name the issues that own the BEP-015 residuals

The private-repo case names gominimal#2499 (git credential helper) and gominimal#2500
(macOS lane with bep, a sign-in and E2E_BEP_PRIVATE_REPO). switch's
bep_host comments name the T45 gate, egress::proxy_lane_admits (gominimal#1885).

* docs(switch): say which box source a boot wires for the proxy

A boot with no listening acceptor wires NoBoxes. A boot whose bep serve
listens wires CredentialedBoxes, which shares only the rows that declare
a credentialed upstream.

* fix(minvmd): stop the proxy when its watcher cannot own it

When the watcher thread cannot start, kill and reap bep serve before
the error returns. When try_wait fails, the watcher stops the child
before it ends, because the handle's drop reaches the child only
through the watcher.

* fix(minvmd): stop bep serve when the supervisor dies without unwinding

Arm PR_SET_PDEATHSIG(SIGTERM) in the proxy child on Linux, so a
SIGKILL'd or crashed supervisor leaves no proxy holding the old boot
token and its socket. macOS has no parent-death signal; gominimal#2501 owns it.

* fix(minvmd): move a full proxy log aside when the proxy starts

bep.log is appended across boots and nothing capped it, so a long-lived
host could fill its state dir. A start now moves a log past 8 MiB to
bep.log.old. The support bundle legend says so.

* test(minimal): inject the audit dir so the bundle test stays hermetic

* fix(minvmd): stop or reap a bep serve left behind by a minvmd crash

When minvmd died without unwinding (SIGKILL, a crash), nothing stopped
the `bep serve` it started on macOS: the proxy ran on with the dead
boot's token and held its listener socket, and `just reap` did not
match it.

minvmd now starts the proxy with `--exit-on-stdin-close` and keeps the
write end of the token pipe open after the token, inside the child
the watcher owns. `bep serve` with that flag reads its standard input
to the end on a thread of its own (`bep::supervisor`) and stops serving
when it closes. Linux keeps PR_SET_PDEATHSIG as it was; the pipe backs
it up there.

Why a pipe at end of file over polling getppid() for reparenting:
- The kernel closes a dead process's descriptors whatever killed it,
  so end of file arrives at once, with no polling interval to tune and
  no window in which the proxy serves a dead boot.
- It tracks the supervisor process itself. getppid() answers whether
  the parent pid changed, which a reparent to a subreaper or launchd
  shows only after the fact, and never if the proxy was started
  through an intermediate process.
- It needs no platform code, so the same mechanism runs on macOS and
  Linux, and its tests run on Linux: a SIGKILL'd child holding the only
  write end proves the end of file this design depends on.
The flag keeps it opt-in, so a person who pipes the token in by hand
still gets a proxy that outlives the pipe.

scripts/reap-vms.sh gains a pattern for this checkout's `bep serve`,
pinned to the ERE-quoted checkout root and to the VM's
`gvproxy-bep.sock` (in the per-name directory under `--vm`), sent with
`pkill -9`, user-side and through `sudo -n` like the others. AGENTS.md's
leaked-VMM footgun names the proxy too.

Closes gominimal#2501

Claude-Session: https://claude.ai/code/session_01WhCC5TEBNzPeWgytRsU4rc

* build(deps): crypto-bigint 0.7.7 and ctutils 0.4.5, for RUSTSEC-2026-0387 and -0385

Port of gominimal#2517 and gominimal#2503 so cargo-deny's advisories check passes on this
branch. The same Cargo.lock changes; they become no-ops once both are on
main.

Claude-Session: https://claude.ai/code/session_01WhCC5TEBNzPeWgytRsU4rc

* fix(scripts): reap only a VM's own bep serve in the bare reap

The bare proxy pattern matched this checkout's `bep serve` on any
listener named gvproxy-bep.sock, so `just reap` also SIGKILLed one
started by hand on another path. It now requires the listener under a
VM's `local-minvmd<N>/` directory, directly or one name below, as the
comment above it already says. reap_scoped_per_checkout gains the case
of a listener outside every VM's directory.

Claude-Session: https://claude.ai/code/session_01WhCC5TEBNzPeWgytRsU4rc

---------

Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review:approved minimal-review approved the current head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

T45 — Reach the proxy only as a credentialed lane's infrastructure

1 participant

0