Watch
0
0
Fork
You've already forked hyperhive
0

docs: drop harness systemd settings; swarm-nats-auth: refuse the hive's shared agent client

Docs (review on #4948): the harness's restart settings are not useful to
a reader, so the `Restart`/`RestartSec` bullet in docs/turn-loop and the
"30 seconds later, no start limit" wording in docs/swarm are removed.
What stays is the behaviour: the harness exits and comes back until the
queue accepts it.

Grant: with the harness's shared-client fallback gone, nothing presents
the hive's shared agent client (`hive-<hive>-agent`) to the queue;
swarm-logs uses that OIDC client over HTTP only. swarm-nats-auth now
refuses it outright instead of granting the configured
`$SWARM.term.{hive}.>` / `$SWARM.agent-state.{hive}.>` publish and its
`_INBOX.client.<id>.>` subscribe, so an agent holding it can no longer
publish as a sibling. The agent arm still runs before the hive arm, so
that id never falls through to its hive's grant.

Removed with it: the `--agent-publish-subject` flag and its two uses in
swarm-nats.nix, `Policy`'s agent subject list, and
swarm-queue-client's `client_inbox_prefix`. The module-eval now asserts
the flag is absent; the policy tests assert the refusal and that the
hive itself is still admitted.
This commit is contained in:
atlas 2026-10-04 20:46:49 +02:00 • committed by mara
commit 91fdf96a67
10 changed files with 85 additions and 333 deletions

View file

@ -16,9 +16,6 @@
//!
//! **Each agent writes its own key** with its own queue credential. The auth
//! callout grants that credential `$KV.agent-icons.<agent>` and no other key.
//! The hive's shared agent client gets nothing in this bucket: every agent on
//! a hive presents that same client, so its grant cannot be narrowed to one
//! agent's key.
//!
//! The writer publishes to [`crate::agent_icon::subject`] directly instead of
//! opening the bucket, so that one subject is its whole grant. Creating the

View file

@ -260,10 +260,9 @@ pub struct DeployRequest {
/// on. That agent's harness subscribes to its own and turns each message into
/// an inbox turn.
///
/// Its own family rather than a leaf under `$SWARM.term.`: every agent on a
/// hive's shared credential may publish under `$SWARM.term.<hive>.>`, and the
/// harness trusts [`AgentInput::from`] only because the controller is the one
/// client granted publish here.
/// Its own family rather than a leaf under `$SWARM.term.`, so no agent's
/// terminal grant covers it: the harness trusts [`AgentInput::from`] only
/// because the controller is the one client granted publish here.
#[must_use]
pub fn agent_input_subject(agent: &str) -> String {
format!("{AGENT_INPUT_SUBJECT_PREFIX}.{agent}")
@ -283,21 +282,13 @@ const AGENT_INPUT_SUBJECT_PREFIX: &str = "$SWARM.input";
/// The queue grants that credential subscribe on this prefix's `.>` and its
/// [`agent_input_subject`], nothing else, so a request made under the
/// library's default `_INBOX.<nuid>` is refused its reply and times out. The
/// `agent` token keeps it disjoint from [`client_inbox_prefix`] and from the
/// default, whose second token is a 22-character nuid.
/// `agent` token keeps it disjoint from the default, whose second token is a
/// 22-character nuid.
#[must_use]
pub fn agent_inbox_prefix(agent: &str) -> String {
format!("_INBOX.agent.{agent}")
}
/// The reply-inbox prefix for a client authenticating as the OIDC client
/// `client_id`, for a client whose grant limits subscribe to this prefix's
/// `.>` — see [`agent_inbox_prefix`].
#[must_use]
pub fn client_inbox_prefix(client_id: &str) -> String {
format!("_INBOX.client.{client_id}")
}
/// What an [`agent_input_subject`] message carries.
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct AgentInput {