swarm: say the read policy names the hive it is written for

`policy::render()` became `render(hive)` when a hive gained read on its own
entry, so two places now describe a document that no longer exists: this
module's header said it "is the same for every hive and depends on nothing",
and the security doc said the grant reaches the agent-credential prefix and
nothing else.

The module header is the load-bearing one. It sits above `write_policy_for`
and says, to anyone about to touch that function, that the render is
hive-independent — which is an invitation to hoist it to a shared constant
and hand every hive the stanza naming one of them.
This commit is contained in:
atlas 2026-09-12 11:41:01 +02:00
commit 45e73f8636
2 changed files with 10 additions and 5 deletions

View file

@ -60,8 +60,10 @@ advertises a boundary it doesn't actually hold. A wide grant that says what it
is beats a narrow one that only looks narrow.
What still holds: the grant is **read-only** (a hive can't write an agent's
credential, so it can't hand itself an agent's identity), and it's scoped to
the agent-credential prefix — nothing else in the store is reachable with it.
credential, so it can't hand itself an agent's identity), and it reaches two
prefixes and nothing else in the store — every agent's credentials, and the
reader's _own_ entry under the hive namespace, which names the hive asking and
so widens nothing between them.
**A tracked follow-up** narrows this, with the two candidate directions: scope
the grant per hive (and pay for the re-emission), or give each agent container

View file

@ -14,9 +14,12 @@
//! take down a daemon that serves everything else, and a store that answers is
//! answering the same way next time, so the next start is the retry for those.
//!
//! The policy document is the same for every hive and depends on nothing
//! ([`swarm_secret_client::policy`] explains why it is that wide), and the hive
//! list is loaded once because a config change means a redeploy.
//! The document names the hive it is written for: one stanza is the same
//! everywhere, the other is scoped to the reader's own name
//! ([`swarm_secret_client::policy`] explains the asymmetry). There is no shared
//! document to hoist this render up to — doing that hands every hive the stanza
//! naming one of them. The hive list is loaded once because a config change
//! means a redeploy.
use std::{future::Future, time::Duration};