Repository navigation
feat(bep): re-certify the published root when a store registration changes - #2767
norrietaylor merged 4 commits into
Conversation
bep serve takes recertify_root on its control socket. It re-issues the root for the current store rules, publishes it to the identity file, and replies only after both, with ok or the reason. The CONNECT path stays the fallback for a rule file edited by hand.
min secret set sends recertify_root on the proxy's control socket after it writes a store rule. When the proxy did not re-issue or publish its root, it says the rule is saved and names the upstream that a box created before then does not reach. With no proxy running it prints nothing new.
|
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: PASS_WITH_CONDITIONS · 1 condition · the full ruling
The change conforms to Gatehouse §6.10 line 839. bep serve re-signs the root under the same key when a store rule changes, and boxes that exist keep their anchor. The new control op stays behind the peer-uid check, and a failure keeps the root in use. One condition is open. The e2e case proof_bep_store_reference_end_to_end reported NOT RUN on Linux, so get its PASS row from the macOS VM lane (C1). Separately, the verify log shows every_daemon_connection_is_classified failing, because the inventory does not list the new connect site in cmd/secret.rs. That is not a design item, but CI will stop on it.
Ruled at dfc01ec against gominimal/arch@42d214dc8ac8 by claude-opus-5-5.
min secret set now opens the egress proxy's control socket, so the connection inventory records that site as ungated.
There was a problem hiding this comment.
arch-review: PASS_WITH_CONDITIONS · 1 condition · the full ruling
The change conforms to Gatehouse §6.10 line 839. bep serve re-self-signs the root under the same key when min secret set changes a rule, and publishes it before it replies. Running boxes keep their anchor. The compare only classifies the new control connection in a test. One condition stays open: the e2e leg reported NOT RUN on Linux. Get a PASS from the macOS VM lane on this head (C1).
Ruled at 7e215e1 against gominimal/arch@42d214dc8ac8 by claude-opus-5-5.
|
Round 1 of 10 on a failed check suite, pushed as
Verify Outside the task's
Converted to a draft: something above needs a person before review. Review threads the coder judged:
A box activated right after Notes from the agent: The tests check failed in minimal tests::every_daemon_connection_is_classified. The new ControlClient::connect( call in cmd/secret.rs::recertify was not in the connection inventory. I added it as ungated, with a comment, in crates/minimal/src/tests.rs. That file is outside the layers, but the inventory test is there to make each new connection site get recorded. A Self::connect wrapper would get past the scanner without that record. ci-linux-native-success is the lane aggregator and failed only because tests failed. Before the fix, a full |
There was a problem hiding this comment.
Approve at 7e215e19.
bep servenow takes arecertify_rootrequest on its control socket. It re-issues the root under the same key and subject for the current store rules, then publishes it to the identity file, and only then replies. So a box created aftermin secret settrusts the rule's upstream with no restart ofbep serve(BEP-013). A box that already runs keeps its anchor.- The op sits behind the existing peer-uid check. A
Controlbuilt withoutwith_recertificationrefuses it. The re-issue runs on a blocking thread because it can wait on the Keychain. When the re-issue or the publish fails, the root in use stays, the rule stays saved, andmin secret setnames the reason. - The e2e case drops the #2612 restart interim. It checks that the proxy pid did not change, and that the box reaches the upstream.
- Arch ruling 618 rules PASS_WITH_CONDITIONS. By the owner's ruling, its one condition (the macOS run of
bep_store_reference_end_to_end) is deferred to the owner's close-out e2e run. The LOW finding on the 10 s control timeout stays as is: on a slow Keychain prompt,min secret setcan report a failure that did not happen. Every lane is green.
Generated by Claude Code
T99 — Re-certify bep's published root when a store registration changes
slice: S13
kind: task
covers: BEP-013
size: M
est: 180 code, 240 tests
executor: agent
d 8000 ifficulty: needs care
model: standard
diagnostics: when a running proxy answers that it did not re-issue or publish the root,
min secret setsays that the rule is saved, name the upstream, and say that a box created before the proxy publishes a root with the change does not reach that upstream, pinned by secret_set_asks_a_running_proxy_to_recertify; with no proxy running it prints nothing new, becausebep serveissues its root from the current rules when it startsobservability: bep serve logs one info line each time a registration change re-certifies the root, with the number of store rules and whether the publish succeeded; the existing error lines still name a failed re-issue or publish
layers:
- recertify:
- crates/bep/src/main.rs:
StoreAdmissionre-issues the root and publishes it to the identity file when the control socket reports a store registration change, not only at the next CONNECT, so the next box activation reads a root that admits the new upstream (#2746, arch condition C2 on #2612); the CONNECT path stays the fallback for a rule file edited by hand, and a failed re-issue or publish keeps today's retry- crates/bep/src/control.rs: a control request that re-certifies at once and answers only after the re-issue and the publish, with ok or the reason they failed
test: cargo nextest run -p bep a_store_registration_change_recertifies_the_published_root_at_once
- client:
- crates/minimal/src/cmd/secret.rs:
min secret setsends the re-certify request after it writes the rule, when a proxy answers on its control socket- crates/minimal/src/mint.rs: the control-socket client that the mint path already uses carries the re-certify request
test: cargo nextest run -p minimal secret_set_asks_a_running_proxy_to_recertify
- e2e:
- scripts/session-e2e.sh:
proof_bep_store_reference_end_to_enddrops the bep stop and daemon restart that #2612 keeps aftermin secret set, and the comment that names #2746; the box activates against the proxy that was already runningtest: ./scripts/session-e2e.sh bep_store_reference_end_to_end
produces: none
consumes: none
proof: A box activated right after
min secret setadds an upstream trusts that upstream, with no restart of bep serve.depends on:
- blocked by #2294
- blocked by #2618
Generated by Claude Code
Proof
After
min secret setwrites a rule that adds an upstream, the running bep serve re-issues its root and publishes it to the identity file before it answers. A box activated right after that trusts the new upstream, and bep serve does not restart. The e2e case bep_store_reference_end_to_end now activates its box against the proxy that ran before the set.Notes from the agent: The control socket takes a new request, {"op":"recertify_root"}. The reply is the usual Reply, {"ok":true} or {"ok":false,"error":...}. StoreAdmission answers it at once and ignores the CONNECT retry delay. The CONNECT path stays the fallback for a rule file edited by hand. bep serve logs one info line for each re-certify, with store_rules and published. The failure text of min secret set goes to stderr: "min secret set saved the rule for . The Box Egress Proxy did not update its root certificate for : . A box created before the proxy updates its root certificate does not reach ." The task fixed no exact wording. The test secret_set_asks_a_running_proxy_to_recertify pins this text. The reason is the text the proxy sends, for example "the root certificate was not written to : ". A proxy older than this change refuses the unknown op, and then this notice prints with that proxy's reason. When no proxy answers on the control socket, the command prints nothing new. RuleTarget has a new field, control. The existing tests in secret.rs pass control: None. The e2e line ran and exited 0, but the case reported NOT RUN, because this box is Linux. The macOS VM lane owes the live evidence. The e2e case now records the proxy pids after the gate. It fails if min secret set printed the notice or if a different proxy serves before the activate.
Tests
cargo nextest run -p bep a_store_registration_change_recertifies_the_published_root_at_oncecargo nextest run -p minimal secret_set_asks_a_running_proxy_to_recertify./scripts/session-e2e.sh bep_store_reference_end_to_endVerify
min task run agent-verifyexited 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.Closes #2746