swarm: split the deploy subject per hive
Per mara on the PR: *"split by hive. its not a security thing, just so hives dont get messages they dont care about."* She agreed with the finding and still wanted the split, which is the part worth recording. I measured that a per-hive subject gives no confidentiality — `sub` is unrestricted, so a hive that wanted another's messages could subscribe to them — and concluded it bought nothing. "Nothing" is a claim over every axis and I had checked one. The axis I never priced: every hive in the swarm being woken by every other hive's deploys. So `deploy_subject(hive)` replaces the single literal, and the payload drops `hive` to carry only the agent — the subject names the hive, and two places stating one fact are free to disagree. The hive subscribes to its own subject and no longer filters. The grant is a wildcard rather than a subject per hive because the responder has no roster: it cannot enumerate hives, and a grant that had to track one would be a second place to get the list wrong — the same argument `hive_name`'s doc makes about admission. The negative test gets stronger rather than merely adapted. Splitting the family makes "another hive's subject" and "its own" separate strings for the first time, so it now asserts a hive reaches neither, nor the wildcard.
This commit is contained in:
parent
7519d9b904
commit
b004ba3dc5
4 changed files with 73 additions and 71 deletions
|
|
@ -91,10 +91,8 @@ enum SwarmNodeKind {
|
|||
///
|
||||
/// Carries the hive, unlike every variant above — this is the node
|
||||
/// `InitAgentConfigRepo`'s doc points at when it says the hive belongs
|
||||
/// on the node that sends the deploy message. The subject is swarm-wide
|
||||
/// and the addressing rides in the payload; see
|
||||
/// `swarm_queue_client::DEPLOY_SUBJECT` for why it is not a per-hive
|
||||
/// family.
|
||||
/// on the node that sends the deploy message. It names the subject the
|
||||
/// message goes to, one per hive, so no other hive is woken by it.
|
||||
TriggerDeploy { hive: String, agent: String },
|
||||
}
|
||||
|
||||
|
|
@ -272,16 +270,16 @@ async fn publish_deploy(
|
|||
) -> hive_jobq::scheduler::Outcome {
|
||||
use hive_jobq::scheduler::Outcome;
|
||||
|
||||
let subject = swarm_queue_client::DEPLOY_SUBJECT;
|
||||
// One subject per hive, so the other hives are never woken by this.
|
||||
let subject = swarm_queue_client::deploy_subject(hive);
|
||||
let request = swarm_queue_client::DeployRequest {
|
||||
hive: hive.to_owned(),
|
||||
agent: agent.to_owned(),
|
||||
};
|
||||
let payload = match serde_json::to_vec(&request) {
|
||||
Ok(payload) => payload,
|
||||
Err(e) => return Outcome::Failed(format!("encoding the deploy request failed: {e}")),
|
||||
};
|
||||
if let Err(e) = client.publish(subject, payload.into()).await {
|
||||
if let Err(e) = client.publish(subject.clone(), payload.into()).await {
|
||||
return Outcome::Failed(format!("publishing to {subject} failed: {e}"));
|
||||
}
|
||||
if let Err(e) = client.flush().await {
|
||||
|
|
|
|||
Loading…
Reference in a new issue