swarm-bao: deny the secret publisher the callout xkey's seed
`swarm-secret-publisher` holds create and update on `secret/data/swarm/services/*`, which covers the callout xkey's seed at `swarm/services/swarm-nats/callout/xkey-seed`. It never writes that path, but a write there would replace the key the queue's server seals every callout request to. An exact-path `deny` outranks the prefix. A create-only grant would not do: KV v2 honours create versus update, so it would stop an overwrite, but it would still let the publisher plant a seed of its choosing whenever the path is empty, on a first boot or after a key replacement. The publisher needs no access to the path at all.
This commit is contained in:
parent
06784e55fa
commit
531d44d34b
2 changed files with 26 additions and 1 deletions
|
|
@ -425,6 +425,23 @@ let
|
|||
&& !(lib.hasInfix "secret/data/swarm/*" s)
|
||||
&& !(lib.hasInfix "sys/policies/acl" s);
|
||||
}
|
||||
{
|
||||
# The publisher's `services/*` write covers the callout xkey's seed, and
|
||||
# only the exact-path denial, which outranks the prefix, keeps it from
|
||||
# replacing the key. The control is an OIDC leaf beside it, which the
|
||||
# prefix still grants.
|
||||
name = "the publisher may not write the callout xkey's seed";
|
||||
ok =
|
||||
let
|
||||
grants = grantsIn baoGrantHere.systemd.services.swarm-bao-secret-publisher-policy.script;
|
||||
in
|
||||
(grantFor grants "secret/data/swarm/services/swarm-nats/callout/xkey-seed").caps == [ "deny" ]
|
||||
&&
|
||||
(grantFor grants "secret/data/swarm/services/swarm-nats/oidc/client").caps == [
|
||||
"create"
|
||||
"update"
|
||||
];
|
||||
}
|
||||
{
|
||||
# The ordering is load-bearing and invisible at runtime: the controller's
|
||||
# unit creates the KV and cert-auth mounts this one writes into, so
|
||||
|
|
|
|||
Loading…
Reference in a new issue