From 45e73f8636e76632879207326eacad3bd4e1fc03 Mon Sep 17 00:00:00 2001 From: atlas Date: Sat, 12 Sep 2026 11:41:01 +0200 Subject: [PATCH] swarm: say the read policy names the hive it is written for MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `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. --- docs/trust-boundary/security.md | 6 ++++-- swarm-controller/src/read_policy.rs | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/trust-boundary/security.md b/docs/trust-boundary/security.md index cc4751c2..852108d8 100644 --- a/docs/trust-boundary/security.md +++ b/docs/trust-boundary/security.md @@ -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 diff --git a/swarm-controller/src/read_policy.rs b/swarm-controller/src/read_policy.rs index b13103ee..ac759db3 100644 --- a/swarm-controller/src/read_policy.rs +++ b/swarm-controller/src/read_policy.rs @@ -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};