swarm-bao: the agent-token checkers' cert roles issue batch tokens
This commit is contained in:
parent
af914eb875
commit
de4871cab1
3 changed files with 56 additions and 7 deletions
|
|
@ -465,6 +465,13 @@ names the hive's own `clientCertFile` and misses a principal's pair has the
|
|||
build refused, by the module of the reader it missed, naming that pair — see
|
||||
[what a missing leaf costs](#what-a-missing-leaf-costs) below.
|
||||
|
||||
The roles of `swarm-nats-auth`, `swarm-logs-auth` and `swarm-metrics-auth` issue
|
||||
batch tokens with a five-minute TTL (`token_type=batch`, `token_ttl=5m`). The
|
||||
responders log in on every check, and the store keeps no record of a batch token,
|
||||
so unauthenticated requests don't grow its token storage. Nothing can renew
|
||||
or revoke a batch token. The other roles keep service tokens, because some of
|
||||
their readers hold a handle for longer than five minutes.
|
||||
|
||||
### What a missing leaf costs
|
||||
|
||||
Each of the three modules asserts its own pair, on the same condition: **this host
|
||||
|
|
|
|||
|
|
@ -1001,6 +1001,7 @@ let
|
|||
{
|
||||
name = "swarm-nats-auth";
|
||||
cn = baoDeploy.natsAuthCommonName;
|
||||
batchToken = true;
|
||||
policyText =
|
||||
readStanza "${credentialMountPath}/data/swarm/agents/+/queue"
|
||||
+ readStanza "${credentialMountPath}/data/swarm/services/${hyperhiveCfg.swarm.nats.clientId}/oidc/client"
|
||||
|
|
@ -1052,6 +1053,7 @@ let
|
|||
{
|
||||
name = "swarm-logs-auth";
|
||||
cn = baoDeploy.logsAuthCommonName;
|
||||
batchToken = true;
|
||||
policyText =
|
||||
readStanza "${credentialMountPath}/data/swarm/agents/+/queue"
|
||||
+ readStanza "${credentialMountPath}/data/${grafanaMetricsBearerLeaf}"
|
||||
|
|
@ -1069,6 +1071,7 @@ let
|
|||
{
|
||||
name = "swarm-metrics-auth";
|
||||
cn = baoDeploy.metricsAuthCommonName;
|
||||
batchToken = true;
|
||||
policyText =
|
||||
readStanza "${credentialMountPath}/data/swarm/agents/+/queue"
|
||||
+ readStanza "${credentialMountPath}/data/${grafanaMetricsBearerLeaf}"
|
||||
|
|
@ -1182,12 +1185,24 @@ let
|
|||
# `swarm` in one — and ./swarm.nix reserves the concrete per-hive spellings
|
||||
# anyway, because the prefixes are operator-settable and an operator may spell
|
||||
# one without that substring.
|
||||
readerRoleWrite = obj: ''
|
||||
#
|
||||
# `batchToken = true` on an object makes its logins batch tokens, which the
|
||||
# store does not persist and cannot renew or revoke. Only for a principal
|
||||
# that logs in, reads and drops the token within one call: the five
|
||||
# minutes outlast that read, and a leaked token dies as fast. A principal
|
||||
# that holds a handle longer must not set it.
|
||||
readerRoleWrite =
|
||||
obj:
|
||||
let
|
||||
batchArgs = lib.optionalString (obj.batchToken or false
|
||||
) " \\\n token_type=batch \\\n token_ttl=5m";
|
||||
in
|
||||
''
|
||||
bao write auth/cert/certs/${lib.escapeShellArg obj.name} \
|
||||
certificate=@${tlsDir}/client-ca.pem \
|
||||
allowed_common_names=${lib.escapeShellArg obj.cn} \
|
||||
token_policies=${lib.escapeShellArg obj.name} \
|
||||
display_name=${lib.escapeShellArg obj.cn}
|
||||
display_name=${lib.escapeShellArg obj.cn}${batchArgs}
|
||||
'';
|
||||
|
||||
# A unit that logs in as the granter and runs `body`, ordered after the
|
||||
|
|
|
|||
|
|
@ -815,6 +815,33 @@ let
|
|||
&& lib.hasInfix "allowed_common_names=swarm-metrics-auth" s
|
||||
&& lib.hasInfix "token_policies=swarm-metrics-auth" s;
|
||||
}
|
||||
{
|
||||
# The three agent-token checkers log in once per check; a batch token
|
||||
# leaves nothing stored per request. The CI runner's role, written by the
|
||||
# same helper, keeps service tokens, and still carries its policy, so a
|
||||
# misspelled script name cannot make the absence pass.
|
||||
name = "the agent-token checkers' roles issue batch tokens and a holder's role does not";
|
||||
ok =
|
||||
let
|
||||
script = unit: baoGrantHere.systemd.services.${unit}.script;
|
||||
batch =
|
||||
unit: role:
|
||||
let
|
||||
s = script unit;
|
||||
in
|
||||
lib.hasInfix "auth/cert/certs/${role} " s
|
||||
&& lib.hasInfix "token_type=batch" s
|
||||
&& lib.hasInfix "token_ttl=5m" s
|
||||
&& !(lib.hasInfix "token_max_ttl" s);
|
||||
ci = script "swarm-bao-ci-runner-policy";
|
||||
in
|
||||
batch "swarm-bao-nats-auth-policy" "swarm-nats-auth"
|
||||
&& batch "swarm-bao-logs-auth-policy" "swarm-logs-auth"
|
||||
&& batch "swarm-bao-metrics-auth-policy" "swarm-metrics-auth"
|
||||
&& lib.hasInfix "token_policies=swarm-ci-runner" ci
|
||||
&& !(lib.hasInfix "token_type" ci)
|
||||
&& !(lib.hasInfix "token_ttl" ci);
|
||||
}
|
||||
{
|
||||
name = "the PKI unit signs the metrics store responder's leaf under its own subject";
|
||||
ok =
|
||||
|
|
|
|||
Loading…
Reference in a new issue