From c590447e8f18e2543f8c161da27e3f91e741ad70 Mon Sep 17 00:00:00 2001 From: atlas Date: Wed, 9 Sep 2026 16:03:49 +0200 Subject: [PATCH] swarm-secret-client: give the store handle a policy write The renderer beside this produces a hive's read policy; nothing could put one in the store. `read`/`write` are KV v2 verbs and a policy is not a secret, so this is a second endpoint rather than another path. A whole-document write, because the store has no merge verb: the caller renders from the current agent set, so a stanza missing from the render is a grant that is meant to be gone. --- swarm-secret-client/src/client.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/swarm-secret-client/src/client.rs b/swarm-secret-client/src/client.rs index 74e61af8..fcd9bda1 100644 --- a/swarm-secret-client/src/client.rs +++ b/swarm-secret-client/src/client.rs @@ -151,6 +151,22 @@ impl SecretStore { vaultrs::kv2::set(&self.inner, MOUNT, path, value).await?; Ok(()) } + + /// Replace the ACL policy named `name` with `policy`. + /// + /// A whole-document write, not a merge: the store has no other verb, and + /// the caller renders the document from the current agent set anyway, so + /// a stanza that is gone from the render is meant to be gone from the + /// grant. Render the text with [`crate::policy`] rather than by hand. + /// + /// # Errors + /// [`Error::Vault`] when the token's own policy does not cover + /// `sys/policies/acl/` — which is what a controller scoped to the + /// `hive-*` namespace gets for any other name. + pub async fn write_policy(&self, name: &str, policy: &str) -> Result<(), Error> { + vaultrs::sys::policy::set(&self.inner, name, policy).await?; + Ok(()) + } } #[cfg(test)]