Watch
0
0
Fork
You've already forked hyperhive
0

copy the cache's pull facts to each hive and create them in the in-swarm cache

the in-swarm cache stores its address, name and public key beside its tokens, create-only. swarm-controller copies the four cache facts to swarm/hives/<hive>/attic/* every five minutes, with read on the sources and write on the copies. part 1 of 3: nothing reads the copies until the hive reader and probe land.
This commit is contained in:
atlas 2026-10-27 15:51:13 +01:00 • committed by mara
commit 1e5070796d

View file

@ -1722,6 +1722,38 @@ let
&& !(lib.hasInfix "secret/data/swarm/hives/*" s)
&& !(lib.hasInfix "secret/metadata/swarm/hives" s);
}
{
# `attic_copy` reads the cache's four facts and writes each into every
# hive's `attic/` prefix. Pinned as whole stanzas, per leaf: a read of
# the services prefix would reach every service's secrets, and `*` under
# `hives/` every hive's queue credential. The read side has no
# `create`/`update`, so the controller cannot replace the cache's token.
name = "the controller reads the cache's four facts and writes a copy of each into every hive";
ok =
let
s = baoGrantHere.systemd.services.swarm-bao-controller-policy.script;
leaves = [
"pull-token"
"url"
"cache"
"public-key"
];
grants = grantsIn s;
in
lib.all (
l:
(grantFor grants "secret/data/swarm/services/attic/${l}").caps == [ "read" ]
&&
(grantFor grants "secret/data/swarm/hives/+/attic/${l}").caps == [
"create"
"read"
"update"
]
) leaves
&& lib.hasInfix "path \"secret/data/swarm/hives/+/attic/pull-token\" {\n capabilities = [\"create\", \"read\", \"update\"]\n}" s
&& (grantFor grants "secret/data/swarm/services/attic/jwt-secret") == null
&& (grantFor grants "secret/data/swarm/services/attic/push-token") == null;
}
{
# `forge::runner_token` writes the runner's registration token and keeps
# the last value in memory, so its stanza has no `read`. Pinned as the
@ -1988,11 +2020,11 @@ let
lib.hasInfix "/notify-router.pem ]" s && lib.hasInfix "swarm-notify-router \"\" clientAuth" s;
}
{
# The cache's host units create each of its three secrets and read them
# The cache's host units create each of its six secrets and read them
# back, and may not replace one: no `update`. Its container's journal
# forwarder reads its own client secret, read only. The notification
# router's grant is the control that `grantsIn` reads a one-path grant too.
name = "the cache's grant is create and read on its signing key and its two tokens, read on its forwarder client, and nothing else";
name = "the cache's grant is create and read on its signing key, its two tokens and its three public facts, read on its forwarder client, and nothing else";
ok =
let
s = baoGrantHere.systemd.services.swarm-bao-attic-policy.script;
@ -2005,24 +2037,33 @@ let
(grantFor grants "secret/data/swarm/services/attic/jwt-secret").caps == caps
&& (grantFor grants "secret/data/swarm/services/attic/push-token").caps == caps
&& (grantFor grants "secret/data/swarm/services/attic/pull-token").caps == caps
&& (grantFor grants "secret/data/swarm/services/attic/url").caps == caps
&& (grantFor grants "secret/data/swarm/services/attic/cache").caps == caps
&& (grantFor grants "secret/data/swarm/services/attic/public-key").caps == caps
&&
(grantFor grants "secret/data/swarm/services/swarm-attic-collector/oidc/client").caps == [ "read" ]
&& lib.length grants == 4
&& lib.length grants == 7
&& lib.length (grantsIn baoGrantHere.systemd.services.swarm-bao-notify-router-policy.script) == 1
&& lib.hasInfix "auth/cert/certs/swarm-attic" s
&& lib.hasInfix "allowed_common_names=swarm-attic" s
&& lib.hasInfix "token_policies=swarm-attic" s;
}
{
# The signing key and the pull token are the cache's alone; the push
# token is also the builder's, and is read there.
name = "no granting unit but the cache's names its signing key or its pull token";
# The signing key is the cache's alone; the push token is also the
# builder's, and is read there. The pull token is also the controller's,
# which only reads it (pinned above).
name = "no granting unit but the cache's names its signing key, and only it and the controller name its pull token";
ok =
lib.filter (
u:
lib.hasInfix "services/attic/jwt-secret" baoGrantHere.systemd.services.${u}.script
|| lib.hasInfix "services/attic/pull-token" baoGrantHere.systemd.services.${u}.script
) grantingUnitNames == [ "swarm-bao-attic-policy" ];
u: lib.hasInfix "services/attic/jwt-secret" baoGrantHere.systemd.services.${u}.script
) grantingUnitNames == [ "swarm-bao-attic-policy" ]
&&
lib.filter (
u: lib.hasInfix "services/attic/pull-token" baoGrantHere.systemd.services.${u}.script
) grantingUnitNames == [
"swarm-bao-controller-policy"
"swarm-bao-attic-policy"
];
}
{
name = "the PKI unit signs the cache's leaf under its own subject";