Watch
0
0
Fork
You've already forked hyperhive
0

swarm: narrow the revoke grant to the queue leaf, not the whole agent prefix

revoke_queue_credential only ever deletes swarm/agents/<agent>/queue
(agent_queue_path + a literal "queue" suffix), never anything else
under an agent's prefix. secret/metadata/swarm/agents/+/queue matches
that exactly — `+` is bao's single-segment glob, the same form
swarm-nats-auth's read grant already uses for the data-side path.

Also rewords the module-eval test's stale note about a read/list grant
handing a "write-only principal" the version history: the controller
has held read on secret/data/swarm/agents/* since the mint-and-verify
read-before-write change, so it was never write-only on that path.
This commit is contained in:
atlas 2026-09-27 21:55:35 +02:00 • committed by mara
commit 642be57678
2 changed files with 10 additions and 6 deletions

View file

@ -400,7 +400,7 @@ let
capabilities = ["create", "read", "update"] capabilities = ["create", "read", "update"]
} }
path "${credentialMountPath}/metadata/swarm/agents/*" { path "${credentialMountPath}/metadata/swarm/agents/+/queue" {
capabilities = ["delete"] capabilities = ["delete"]
} }

View file

@ -1155,15 +1155,19 @@ let
# it separately — without this grant the revocation is a 403 and a # it separately — without this grant the revocation is a 403 and a
# destroyed agent's credential stays valid. # destroyed agent's credential stays valid.
# #
# Pinned as the whole capability list for the same reason as the stanza # `+` is one path segment, so this reaches `swarm/agents/<agent>/queue`
# above: `read` or `list` here would hand a write-only principal the # and nothing else an agent holds; `agents/*` would reach every object
# version history of every agent's secrets. # under the prefix, which `revoke_queue_credential` never asks the store
name = "the controller may revoke an agent credential, and only by removing every version of it"; # to delete. Pinned as the whole capability list too: `read` or `list`
# here would let the controller read back the queue-secret version
# history it is meant only to delete.
name = "the controller may revoke an agent's queue credential, and only that one";
ok = ok =
let let
s = baoGrantHere.systemd.services.swarm-bao-controller-policy.script; s = baoGrantHere.systemd.services.swarm-bao-controller-policy.script;
in in
lib.hasInfix "path \"secret/metadata/swarm/agents/*\" {\n capabilities = [\"delete\"]" s lib.hasInfix "path \"secret/metadata/swarm/agents/+/queue\" {\n capabilities = [\"delete\"]" s
&& !(lib.hasInfix "secret/metadata/swarm/agents/*" s)
&& !(lib.hasInfix "secret/metadata/*" s); && !(lib.hasInfix "secret/metadata/*" s);
} }
{ {