swarm-nats-auth: grant each hive its own notices publish subject
`hive_subjects` granted `$JS.API.STREAM.INFO`/`CREATE` on `hive-notices` but never the per-hive subject a publish actually targets, so every `notices::publish` was refused with a permissions violation naming `hive-notices.<hive>`. The gap survived because `notices_subjects`'s own doc comment asserted `extra_hive_subjects` covered it "since that one *is* per-hive". Nothing in `nix/` has ever passed `--hive-publish-subject` (`git grep` → 0 hits; control: `--reader-client` is passed at `nix/host-modules/swarm-nats.nix:711`), so the publish had been refused for as long as the feature existed. Subject comes from `swarm_queue_client::notices::subject`, the same constant the publisher formats from, rather than a literal here. Refs #3859
This commit is contained in:
parent
d6c8bcf5d3
commit
a73cc83ee6
1 changed files with 28 additions and 2 deletions
|
|
@ -189,8 +189,8 @@ impl Policy {
|
||||||
/// no such per-hive split at the `STREAM.INFO`/`STREAM.CREATE` layer
|
/// no such per-hive split at the `STREAM.INFO`/`STREAM.CREATE` layer
|
||||||
/// — the stream itself, not a slice of it, is what every hive's
|
/// — the stream itself, not a slice of it, is what every hive's
|
||||||
/// `open_or_create` needs to reach before it can publish to its own
|
/// `open_or_create` needs to reach before it can publish to its own
|
||||||
/// `hive-notices.<hive>` subject (which `extra_hive_subjects` already
|
/// `hive-notices.<hive>` subject, which [`Self::hive_subjects`] grants
|
||||||
/// covers, since that one *is* per-hive). Granting these two subjects
|
/// beside these from the same crate constant. Granting these two subjects
|
||||||
/// to every hive is therefore correct, not a widening: it is
|
/// to every hive is therefore correct, not a widening: it is
|
||||||
/// `CREATE`/`INFO` on one named stream, the same shape already
|
/// `CREATE`/`INFO` on one named stream, the same shape already
|
||||||
/// measured safe for the hive-status bucket in [`Self::create`] —
|
/// measured safe for the hive-status bucket in [`Self::create`] —
|
||||||
|
|
@ -233,6 +233,11 @@ impl Policy {
|
||||||
format!("$KV.{}.{hive}", self.bucket),
|
format!("$KV.{}.{hive}", self.bucket),
|
||||||
]);
|
]);
|
||||||
subjects.extend(Self::notices_subjects());
|
subjects.extend(Self::notices_subjects());
|
||||||
|
// The hive's own slice of the stream the subjects above let it open.
|
||||||
|
// Named from the defining crate so a rename cannot leave the grant
|
||||||
|
// pointing at a subject nobody publishes to. Not `extra_hive_subjects`:
|
||||||
|
// that is for streams this crate does not know about.
|
||||||
|
subjects.push(swarm_queue_client::notices::subject(hive));
|
||||||
subjects.extend(
|
subjects.extend(
|
||||||
self.extra_hive_subjects
|
self.extra_hive_subjects
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -544,6 +549,27 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_hive_may_publish_to_its_own_notices_subject() {
|
||||||
|
// Opening the stream and writing into it are separate grants.
|
||||||
|
let p = policy()
|
||||||
|
.permissions("hive-alpha")
|
||||||
|
.expect("a hive is admitted");
|
||||||
|
assert!(p.publish.contains(&"hive-notices.alpha".to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_hive_may_not_publish_to_another_hives_notices_subject() {
|
||||||
|
// The stream-level subjects are identical for every hive; this one
|
||||||
|
// must not be, or reaching the stream would carry writing to every
|
||||||
|
// other hive's slice of it.
|
||||||
|
let p = policy()
|
||||||
|
.permissions("hive-alpha")
|
||||||
|
.expect("a hive is admitted");
|
||||||
|
assert!(!p.publish.contains(&"hive-notices.beta".to_owned()));
|
||||||
|
assert!(!p.publish.iter().any(|s| s == "hive-notices.>"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn the_notices_stream_grant_is_identical_across_hives() {
|
fn the_notices_stream_grant_is_identical_across_hives() {
|
||||||
// Unlike `$KV.<bucket>.<hive>` or an `extra_hive_subjects`
|
// Unlike `$KV.<bucket>.<hive>` or an `extra_hive_subjects`
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue