Watch
0
0
Fork
You've already forked hyperhive
0

swarm ui: show when an agent's claude login was stored, and delete it

The agent's settings get a claude login row: when the swarm stored the
login, read by the minter from the leaf's metadata, or that none is, with a
delete that removes every version after a confirmation. New minter steps
(status, delete), controller routes (GET claude-login, DELETE
claude-login/stored) and a read and delete grant on the leaf's metadata,
pinned in the module-eval check.
This commit is contained in:
iris 2026-11-09 21:39:17 +01:00 • committed by mara
commit 7dd147adb4
2 changed files with 469 additions and 32 deletions

View file

@ -1353,7 +1353,10 @@ let
# The claude login minter: every agent's `claude-credentials` leaf,
# create and update so a relogin replaces the last, and nothing else under
# an agent; and its own queue client secret, read at start.
# an agent; the leaf's metadata, to say when it was written (`read`) and to
# delete every version of it (`delete`; the `data/` path's delete would leave
# the older versions, each a live session), never the credential itself; and
# its own queue client secret, read at start.
claudeLoginWriters = [
{
name = "swarm-claude-login";
@ -1362,6 +1365,9 @@ let
path "${credentialMountPath}/data/swarm/agents/+/claude-credentials" {
capabilities = ["create", "update"]
}
path "${credentialMountPath}/metadata/swarm/agents/+/claude-credentials" {
capabilities = ["read", "delete"]
}
''
+ readStanza "${credentialMountPath}/data/swarm/services/${hyperhiveCfg.swarm.claude-login.clientId}/oidc/client";
}
@ -2294,8 +2300,9 @@ in
description = ''
Subject the store's `swarm-claude-login` cert-auth role accepts: the
identity the claude login minter presents from inside its container.
Its grant is create and update on `swarm/agents/+/claude-credentials`
and read on its own queue client secret.
Its grant is create and update on `swarm/agents/+/claude-credentials`,
read and delete on that leaf's metadata, and read on its own queue client
secret.
⚠️ Reserved as a hive name by ./swarm.nix, like its siblings.
'';

View file

@ -2098,9 +2098,10 @@ let
}
{
# The minter writes one leaf under every agent, create and update so a
# relogin replaces the last, and reads its own queue client secret. No
# read on the leaf, and nothing else under an agent.
name = "the claude login minter's grant is create and update on agents' claude-credentials, and its queue client secret";
# relogin replaces the last, reads and deletes the leaf's metadata (when it
# was written; every version removed), and reads its own queue client
# secret. No read on the leaf's data, and nothing else under an agent.
name = "the claude login minter's grant is create and update on agents' claude-credentials, read and delete on its metadata, and its queue client secret";
ok =
let
s = baoGrantHere.systemd.services.swarm-bao-claude-login-policy.script;
@ -2110,8 +2111,13 @@ let
"create"
"update"
]
&&
(grantFor grants "secret/metadata/swarm/agents/+/claude-credentials").caps == [
"read"
"delete"
]
&& (grantFor grants "secret/data/swarm/services/swarm-claude-login/oidc/client").caps == [ "read" ]
&& lib.length grants == 2
&& lib.length grants == 3
&& !(lib.hasInfix "secret/data/swarm/agents/*" s)
&& lib.hasInfix "auth/cert/certs/swarm-claude-login" s
&& lib.hasInfix "allowed_common_names=swarm-claude-login" s
@ -2147,7 +2153,7 @@ let
in
(grantFor grants "secret/data/swarm/services/swarm-notify-router/oidc/client").caps == [ "read" ]
&& lib.length grants == 1
&& lib.length minter == 2
&& lib.length minter == 3
&& lib.hasInfix "auth/cert/certs/swarm-notify-router" s
&& lib.hasInfix "allowed_common_names=swarm-notify-router" s
&& lib.hasInfix "token_policies=swarm-notify-router" s;