agent permissions: one set, tool groups included, set at agent creation
mara on #5170: "dont split caps and perms. its all perms. / dont include the now empty tool groups / nothing set -> default / also add perms to agent creation screen". - hive-sh4re: one `Permission` enum (messaging, meta, inbox, execution, web_tools, manage_root_agent) replaces `ToolGroup` and `Capability`; `lifecycle`/`forge` are gone. `Permission::default_for` is the default for an agent the swarm sets nothing for. - The record is `{ "permissions": [...] }`. Missing key, unset field or no successful read yet = default; `[]` = none; a failed read after a good one keeps the last value. - hive-agent reads its own key every 10s and builds each turn's --tools, --allowedTools and MCP config (rewritten before every turn) from it; the subagent daemon reads it on each start/continue. Agents get a read-only grant on their own key. - hive-c0re restarts an agent only when its manage_root_agent changes. The import now merges meta/capabilities.json and meta/tool-groups.json into one list per agent and deletes both; the "import pending, don't read" decision is `ImportOutcome::read_allowed`, table-tested. - swarm-controller: `GET /api/permissions` (names + default) and an optional `permissions` on `POST /api/agents`, stored before the job is queued. swarm-ui's create-agent form gets a permissions field. - Deleted: HIVE_TOOL_GROUPS and its forward to the subagent daemon, tool_groups.rs, ruth's tool-group seed, the permissions rebuild job (PermPayload/WritePermFile/perm_change), the dashboard permissions tab and its stale-entries panel. Part of #5170.
This commit is contained in:
parent
f862354e43
commit
f0844f6da3
73 changed files with 1578 additions and 2742 deletions
|
|
@ -564,7 +564,7 @@ impl Policy {
|
|||
"$JS.API.DIRECT.GET.{}.>",
|
||||
swarm_queue_client::agent_limits::STREAM
|
||||
));
|
||||
// The capabilities the swarm grants those agents
|
||||
// The permissions the swarm grants those agents
|
||||
// (`swarm_queue_client::agent_permissions`), read the same way and
|
||||
// every key for the same reason.
|
||||
subjects.push(format!(
|
||||
|
|
@ -852,15 +852,15 @@ mod tests {
|
|||
}
|
||||
|
||||
/// A hive reads any agent's permissions and can change none of them; an
|
||||
/// agent, even one granted direct gets on its own keys elsewhere, reads
|
||||
/// none of them.
|
||||
/// agent, with the template `swarm-nats.nix` passes, reads its own key and
|
||||
/// no other, and writes none.
|
||||
#[test]
|
||||
fn a_hive_may_read_every_agents_permissions_and_an_agent_none() {
|
||||
fn a_hive_reads_every_agents_permissions_and_an_agent_only_its_own() {
|
||||
use swarm_queue_client::agent_permissions::{STREAM, direct_get_subject, key_subject};
|
||||
|
||||
let p = policy()
|
||||
.with_agent_token_subjects(vec![
|
||||
"$JS.API.DIRECT.GET.KV_agent-inference.$KV.agent-inference.{agent}".to_owned(),
|
||||
"$JS.API.DIRECT.GET.KV_agent-permissions.$KV.agent-permissions.{agent}".to_owned(),
|
||||
])
|
||||
.expect("a per-agent template is valid");
|
||||
let hive = p.permissions("hive-alpha").expect("a hive is admitted");
|
||||
|
|
@ -880,15 +880,10 @@ mod tests {
|
|||
|
||||
let agent = p.agent_token_permissions("atlas").expect("configured");
|
||||
let agent_may = |subject: &str| agent.publish.iter().any(|g| covers(g, subject));
|
||||
assert!(
|
||||
!agent_may(&direct_get_subject("atlas")),
|
||||
"an agent may read its own permissions: {:?}",
|
||||
agent.publish
|
||||
);
|
||||
// Control: the agent's direct-get grant is real, just not this bucket.
|
||||
assert!(agent_may(
|
||||
&swarm_queue_client::agent_inference::direct_get_subject("atlas")
|
||||
));
|
||||
assert!(agent_may(&direct_get_subject("atlas")));
|
||||
for forbidden in [direct_get_subject("ruth"), key_subject("atlas")] {
|
||||
assert!(!agent_may(&forbidden), "atlas may publish {forbidden}");
|
||||
}
|
||||
}
|
||||
|
||||
/// A hive sends its import on its own subject only; the reader hears every
|
||||
|
|
|
|||
Loading…
Reference in a new issue