Repository navigation
T123 — Revoke a host-address grant box's minted id at the proxy when the box ends - #3034
norrietaylor merged 14 commits into
Conversation
retire_host_ip_box now sends the Box Egress Proxy a revocation of the box's minted id when the box declared a credentialed upstream, as the destroy of an own-address box does (BEP-043). The id stays in the id set, so no later mint takes it.
|
Important Review skippedBot user detected. To trigger a single review, invoke the
|
|
Reviewed: 1 finding, none blocking at Address the comments on the diff. Clobber: none seen. |
There was a problem hiding this comment.
arch-review: CONDITIONS · 1 condition · the full ruling
The revocation itself conforms to BEP-043: it goes on destroy, uses the right gate, and keeps the id in the set. But retire_host_ip_box also runs when min session rename renames a live host_ip box (crates/minimal/src/cmd/session.rs:739). After this change, that rename permanently revokes the id of a running box. Gatehouse §6.10 line 839 says destroy is the one revocation event. architecture.md lines 486 and 499 say rename changes only the alias. Make the revocation a field of the retire request, default true, and send false from rename. C1 gives the edits.
Ruled at dea5244 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.
A retired host_ip box now logs that the box ended, not that a destroy completed. The own-address destroy keeps its text, which the session e2e matches.
|
Round 1 of 10 on the runtime's review findings, pushed as
Verify Review threads the coder judged:
After a host-address grant box ends, minvmd sends the proxy a revocation of its minted id, so the proxy refuses a sealed value under that id and Notes from the agent: Revise round 1: spawn_revocation now takes a BoxEnd value. The own-address destroy keeps the text 'the destroy completed without a revocation from the Box Egress Proxy', because scripts/session-e2e.sh matches it and that script is outside this task's layers. The host_ip retire says 'the box ended ...'. The info line and the forget warning now say 'the ended box's revocation' for both callers. No test or script matches those lines. clippy -p minvmd --all-targets and cargo fmt --check are clean. just clippy-strict was not run. |
There was a problem hiding this comment.
arch-review: CONDITIONS · 3 conditions · the full ruling
The destroy of a credentialed host_ip box now revokes its id, and that part conforms. But retire_host_ip_box also runs on min box stop and on a rename. So a stop revokes the id of a box that restart brings back, and a rename revokes the id of a live box. Gatehouse §6.10 line 839 says destroy is the one revocation event. architecture.md lines 486 and 499 say that a rename and a restart keep the id. Make C1 to revoke only on a destroy, and C2 to take the rename off the retire. Add the tests in C3.
Outside the diff
crates/minimal/src/cmd/boxes/lifecycle.rs:600: C1 · The stop sendsRetireHostIpBox. With this PR, that retire revokes the box id. Sendend: stoppedhere, so that the stop drops the egress rules and does not revoke.crates/minimal/src/cmd/boxes/lifecycle.rs:835: C2 ·release_held_box_nameretires the box, so with this PR a rename revokes a live box id. Architecture.md line 486 says a rename leaves the id untouched. Release only the old name's hold withhold_box_name_with_vm_host(.., false).
Ruled at fda1689 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.
|
/revise Arch CONDITIONS at fda1689 (BEP-043, Gatehouse §6.10 line 839: destroy is the one revocation event).
Run both T123 test lines and the new tests. |
…ost-address-grant-box-s-minted-id-at-t
RetireHostIpBoxRequest now carries a required `end` (stopped or destroyed), with no serde default. The registry revokes a credentialed, minted id only on a destroy. A stop keeps the id, because a restart brings the box back. The id set remembers a stopped grant box, so its later destroy still revokes. `min box stop` retires as stopped, and the destroy paths retire as destroyed. A rename no longer retires the box. It releases the old name's hold and holds the new name, so a live box keeps its egress rules and its id. The no-grant test reads a synchronous record of spawned revocations in place of a 200 ms sleep. The label-only warning test is removed.
There was a problem hiding this comment.
arch-review: PASS · the full ruling
This head conforms. A host_ip grant box now has its id revoked only when the box is destroyed, as Gatehouse §6.10 line 839 says. A stop and a rename keep the id, as architecture.md lines 486 and 499 require. The prior conditions on this PR are met. Update the PR body: it still says that a stop sends a revocation.
Ruled at d1a555b against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.
|
Round 2 of 10 on a /revise note, pushed as
Verify Outside the task's
Converted to a draft: something above needs a person before review. Review threads the coder judged:
After a host-address grant box is destroyed, the VM host daemon sends revoke_box and forget_box for its minted id to the Box Egress Proxy, so the proxy refuses a sealed value under that id and the revocation is in the audit log that min box audit reads. A stop or a rename of the box revokes nothing, and a box that was stopped first still has its id revoked when it is destroyed. Notes from the agent: Files outside the layers: the directive's owner-accepted list (minimald-rpc lib.rs, minimal-client attach.rs, vm_host.rs, lifecycle.rs, session.rs, dash/rpc.rs, minvmd control.rs). Four more files changed only because the new required field and the new retire_host_ip_box argument must compile: crates/minimal/src/cmd/mod.rs (withdraw_interrupted_box sends destroyed), and test-only call sites in minvmd net/answerer.rs, net/dns_pins.rs, net/egress_gate.rs and tests/vm_escape_integration.rs (all pass destroyed). Design: host_ip_box_at's |
|
/revise Arch CONDITIONS at d1a555b (BEP-082; architecture line 499: "ids, never names, key every record"; Gatehouse §6.10 line 839). Round 2 took the retire out of the rename. That retire was also what removed the old name from minvmd's registration-name map (
Run both T123 test lines and the new tests. |
…ost-address-grant-box-s-minted-id-at-t
A rename withdraws the old registration name by the box's id. The test shows the name is free for a new grant box and the first id stays minted.
A rename now withdraws minvmd's registration name for the old name by the box's id, so a new grant box under that name is not refused. The withdraw retires and revokes nothing.
|
Round 3 of 10 on a /revise note, pushed as
Verify Outside the task's
Converted to a draft: something above needs a person before review. Review threads the coder judged:
After a host-address grant box is destroyed, minvmd sends the proxy a revoke_box line for its minted id, so the proxy refuses a sealed value under that id and Notes from the agent: Round 3. For the PR body, agent notes: a stop retires the box's rules with Residuals: #3041. A destroy after a minvmd restart sends no revocation, because
|
|
Round 4 of 10 on a failed check suite: the coder changed nothing. noop: this round changed nothing. The directive lists two failed checks and no new thread. ci-macos-success is the lane aggregator: its job runs only |
There was a problem hiding this comment.
Babysitter review at bda81e1, against the T123 plan block in #3032, BEP-043 and BEP-082.
- Destroy is the one revocation event (Gatehouse §6.10 line 839).
RetireHostIpBoxRequestcarries a requiredend: HostIpBoxEnd(stopped|destroyed). minvmd passes it toretire_host_ip_box, which spawnsrevoke_boxonly for a destroyed, credentialed box whose idHostIpIdsminted.min box stopsendsstopped, and every destroy path sendsdestroyed: destroy, rm, prune, the attach that finds the box gone, the re-admit undo,settle_destroyed_box,withdraw_interrupted_boxand theHostIpResidencydrop.- A stopped box keeps its id, and a later rm or prune still revokes it.
- A rename keeps the id (architecture lines 486 and 499).
min box renameandmin session renameno longer retire.move_held_box_namewithdraws the old registration name by id (bda81e1), then moves the zone hold. So a new grant box under the old name gets a fresh id, and the renamed box keeps its rules and its id. A minvmd test pins the fresh id. - Wire. A retire with no
endis refused at decode, so nothing is retired or revoked (fail closed). - PR body. The stop sentence is corrected, and #3041 is listed under Residuals.
Residual: #3041 (a destroy after a minvmd restart sends no revocation; HostIpIds is in memory only).
Lanes: the macOS e2e vm_escape_bounded_to_resident_union failure on the first run was a flake (#1845 class). The rerun passed.
There was a problem hiding this comment.
arch-review: PASS · the full ruling
This head adds one change to the PASS on d1a555b. A rename now withdraws the old host_ip name by the box id. minvmd serves that withdraw in withdraw_host_ip_name, which removes the name only. It does not retire the box or revoke the id. The id stays minted, so a later destroy still revokes it (gatehouse-spec.md line 839). The rename keeps the id, as architecture.md line 486 requires, and a new box under the old name gets a fresh id. Residual #3041 stays open.
Ruled at bda81e1 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.
There was a problem hiding this comment.
arch-review: PASS · the full ruling
The compare from 4104bdc9 changes one test call in crates/minvmd/src/box_registry.rs. It passes HostIpBoxEnd::Destroyed to retire_host_ip_box, so the test that the merge of #3014 brought matches the new signature. No other caller uses the old form. The revoke path is not changed, so the earlier ruling on BEP-043 and Gatehouse §6.10 line 839 stands. Residual #3041 stays open.
Ruled at ef92a66 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.
|
Round 5 of 10 on the runtime's review findings, pushed as Resolved conflicts in:
Verify Outside the task's
Converted to a draft: something above needs a person before review. Review threads the coder judged:
After a host-address grant box is destroyed, minvmd sends the revocation of its minted id to the proxy, so the proxy refuses a sealed value under that id, and Notes from the agent: This round changed only crates/minimald-rpc/src/lib.rs and its tests.rs. An earlier round already touched both files to add HostIpBoxEnd, and neither file is in the task's layers. RetireHostIpBoxRequest::end now has a serde default of Destroyed. Before this pull request, a client sent a retire only on its destroy paths. The stop retire is new in this pull request. So the default keeps the old meaning, and an old client never revokes the id of a box that it only stopped. |
|
The runtime will not revise this pull request again on its own: the diff is +496/-69 (565 lines), past 3x the plan's estimate of 180 lines (est: 60 code, 120 tests, as #3032 reads now), at round 5 (the last trigger was the runtime's review findings). A person decides now. Remove |
A test from main called retire_host_ip_box with one argument. A client retire ends the box as destroyed, so the call passes HostIpBoxEnd::Destroyed.
A min built before the end field also sends a retire on min box stop. A default of destroyed read that stop as a destroy and revoked the id of a box that min box restart brings back. The end field is required again, so a retire that does not say how the box ended is refused at decode, and nothing is retired or revoked.
ef92a66 to
626f5d6
Compare
There was a problem hiding this comment.
arch-review: PASS · the full ruling
This head conforms. A retire must now say how the box ended, and the control door refuses a retire with no end. An older min also sends a retire on min box stop and on rename. Under the old default, those retires revoked an id that restart brings back. Gatehouse §6.10 line 839 allows a revocation only on destroy. The refusal revokes nothing, and the NET-085 reconcile still clears the box's rules. Residual #3041 stays open.
Ruled at 626f5d6 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.
There was a problem hiding this comment. 10BC8 p>
minimal-review — approval withheld
Verdict COMMENT — APPROVE withheld: 3 unresolved threads — minimal-foundry[bot] crates/minvmd/src/box_registry.rs:6434, minimal-arch[bot] crates/minvmd/src/box_registry.rs:6432, minimal-foundry[bot] crates/minvmd/src/box_registry.rs:6432. No findings.
Panel: 3 of 3 personas ran (correctness, security, supply-chain).
A reconcile sets aside the rules of a host_ip box the guest lists but does not run. The retire then dropped those dormant rules unread, so a credentialed grant box the guest stopped revoked nothing at its destroy, and its stop never recorded it for a later destroy. BEP-043 says a destroy writes the revocation. The retire now reads whether the box was credentialed from its dormant rules when the resident set holds none.
There was a problem hiding this comment.
arch-review: CONDITIONS · 1 condition · the full ruling
The compare is correct: a destroy of a box with dormant rules now revokes its id. One path still loses the revocation. reconcile_host_ip_boxes drops the rules of a box that the guest no longer lists and keeps no record of the grant. If that pass runs before the client's retire_host_ip_box(.., Destroyed), the destroy revokes nothing. Section 6.10 line 839 says that the destroy writes the box revocation. Make the change in C1. Then the change conforms.
Ruled at d698066 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.
A reconcile drops the rules of a host_ip box the in-VM daemon no longer lists: the guest destroyed it with no retire from a client. That pass withdrew the box's name but sent no revocation, and left the id in the stopped set. BEP-043 says the end of a grant box revokes its minted id. The reconcile now revokes the id of each such box that declared a credentialed upstream, from resident or set-aside rules or the stopped set, and clears it from the stopped set.
There was a problem hiding this comment.
arch-review: PASS · the full ruling
This head closes the gap from the ruling on d6980668. A grant box that the VM destroys with no client retire now has its minted id revoked at the Box Egress Proxy. Gatehouse §6.10 line 839 and BEP-043 require that revocation. The id stays in the minted set, so it never returns. A failed list read changes nothing, so the path fails closed. No conditions.
Ruled at c9719cb against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5.
|
Round 1 of 10 on the runtime's review findings, pushed as
Verify Outside the task's
Converted to a draft: something above needs a person before review. Review threads the coder judged:
After a host-address grant box ends, by a client's destroy or by the VM destroying it, minvmd sends revoke_box and then forget_box for its minted id. The proxy then refuses a sealed value under that id, and Notes from the agent: Revise round 1. Threads 1-3 (dormant rules on a destroy) were already fixed on this branch by d698066. This round fixes threads 4-5: reconcile_host_ip_boxes now revokes the minted id of a credentialed box the guest no longer lists, and clears it from stopped_credentialed. The new BoxEnd::HostIpGuestDestroy names that step in the bep-revocation warnings ("the VM destroyed the box"). Not done: the HostIpIds set is still in memory only, so a minvmd restart between a stop and a destroy loses the stopped-credentialed record. Persistence is a design change beyond this task. A box a client stopped and the VM later destroyed, with no destroy retire, is also not revoked, because the reconcile thread runs only while minvmd holds host_ip rules. just clippy-strict was not run. |
|
The runtime will not revise this pull request again on its own: the diff is +719/-82 (801 lines), past 3x the plan's estimate of 180 lines (est: 60 code, 120 tests, as #3032 reads now), at round 1 (the last trigger was the runtime's review findings). A person decides now. Remove |
T123 — Revoke a host-address grant box's minted id at the proxy when the box ends
slice: S17
kind: task
covers: BEP-043
size: S
est: 60 code, 120 tests
executor: agent
difficulty: routine
model: standard
diagnostics:
min box audit <box>for an endedhost_ipgrant box shows the revocation of its id, as it does for an ended own-address boxobservability: the existing
bep-revocationthread's warning names the box id and the step that failed, for ahost_ipbox as for an own-address boxlayers:
- revoke:
- crates/minvmd/src/box_registry.rs:
retire_host_ip_boxsendsspawn_revocationfor the box's minted id when the retired box declared a credentialed upstream and the id is oneHostIpIdsminted, as the own-address destroy does (BEP-043); the id stays in the id set so it never returnstest: cargo nextest run -p minvmd retiring_a_host_ip_grant_box_revokes_its_minted_id
test: cargo nextest run -p minvmd retiring_a_host_ip_box_with_no_grant_sends_no_revocation
produces:
- the revocation of an ended host-address grant box
consumes: none
proof: After a host-address grant box ends, the proxy refuses a sealed value under its id, and
min box auditshows the revocation.depends on:
- blocked by #2854
Proof
When a host_ip box that declared a credentialed upstream ends, retire_host_ip_box sends the proxy's control socket a revoke_box line and then a forget_box line for the box's minted id. This is the same path the own-address destroy uses. The proxy then records the revocation, which
min box auditreads, and refuses sealed values under that id. The tests show the two lines at a stub control socket and show that the id stays in the minted set. The proxy-side refusal and the audit row come from the existing revoke_box handling. No test in this task runs them end to end.Notes from the agent: The revocation goes only when three things are true: the retired rules declared a credentialed upstream, HostIpIds minted the id, and the registry has a proxy control socket. A box with no grant, or one under an id this registry did not mint, sends nothing. The second test covers both of those cases. The existing bep-revocation thread logs failures with the box id and the failed step. Its warning text says 'the destroy completed', and that wording now also covers a host_ip box end. A stop retires the box's rules with
end: stoppedand revokes nothing. Only a destroy revokes the box's id. This is safe because the retire already withdraws the registration name, so a later box under that name gets a new id. cargo clippy -p minvmd --all-targets and cargo fmt --check are clean.Tests
cargo nextest run -p minvmd retiring_a_host_ip_grant_box_revokes_its_minted_idcargo nextest run -p minvmd retiring_a_host_ip_box_with_no_grant_sends_no_revocationVerify
min task run agent-verifypassed ([tasks.verify]).Closes #3032
Residuals
HostIpIdsis held in memory only (arch C2 on d1a555b).