refactor(#4006): one wanted-state bucket per hive, so a watch can be scoped
A hive reads its own declaration today and that scopes cleanly: DIRECT.GET carries the key in the subject, so the grant can name it. A *watch* cannot be scoped that way — a consumer's filter travels in the request payload, so $JS.API.CONSUMER.CREATE.<stream> grants the whole stream. With every hive in one bucket, letting a hive watch its own declaration would let it read every other hive's. One bucket per hive (hive-wanted-<hive>) makes the stream a hive may hold exactly as wide as what it is allowed to see, which is what #4006's live-watch needs. That watch is a separate change; this only moves the boundary. mara's calls, both on #4006: one stream per hive rather than teaching the auth responder a hive roster, and a wildcard for the controller — "its okay if swarm controller can theoretically override hive". A bucket name is a single subject token with no prefix matching, so no wildcard narrower than * covers N per-hive buckets; the controller's grant is account-wide by consequence, and documented as chosen rather than left to look accidental. The reader arm of #4005's key-layout guard asserted the opposite of that ruling, so it is replaced rather than deleted: the hive arm survives as no_hive_may_write_another_role_s_agent_status (with a positive control), and the_readers_grant_is_deliberately_account_wide pins the decision and names the ruling, so the width reads as chosen to whoever finds it next. Two pre-existing negative assertions were silently defanged by the rename -- they matched hive-wanted.beta and $KV.hive-wanted.alpha, strings nothing produces any more, and kept passing. Both now match current names. swarm-controller resolves the store per hive per call instead of caching one in a OnceCell: there is no single handle that serves N buckets, and declarations change on operator action rather than per tick.
This commit is contained in:
parent
8c94e340b8
commit
78637ded0c
6 changed files with 111 additions and 66 deletions
|
|
@ -125,7 +125,7 @@ pub async fn open_or_create(
|
|||
})
|
||||
.await
|
||||
.map_err(|source| Error::CreateBucket {
|
||||
bucket: BUCKET,
|
||||
bucket: BUCKET.to_owned(),
|
||||
source,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ pub async fn open_or_create(
|
|||
})
|
||||
.await
|
||||
.map_err(|source| Error::CreateBucket {
|
||||
bucket: BUCKET,
|
||||
bucket: BUCKET.to_owned(),
|
||||
source,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,10 @@ mod tests {
|
|||
// the grant scoping in `swarm-nats-auth` names this string, so a bucket
|
||||
// the client refuses to open would surface as a permissions problem
|
||||
// rather than as the naming problem it is.
|
||||
let legal = |s: &str| s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-');
|
||||
let legal = |s: &str| {
|
||||
s.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
|
||||
};
|
||||
assert!(legal(&bucket("alpha")));
|
||||
assert!(legal(&bucket("a-hive-with-hyphens")));
|
||||
assert!(legal(&bucket("h9")));
|
||||
|
|
|
|||
Loading…
Reference in a new issue