swarm-bao: grant the agent PKI mount (for #4756)
#4756 moves agent client certificates onto a PKI mount of their own, `pki-agents`, whose root bao generates internally. The unit that sets that mount up runs as the bao granter, and the granter's policy is only written while #4754's one-time bootstrap token is in place. Adding these grants after an operator has done that step would cost a second token placement, so they go into the granter's policy here, before it. Six stanzas: enable and tune the mount, list its issuers, read its CA, generate its root internally, and write `swarm-*` roles on it. No root delete or sudo: agent cert-auth roles pin that root by value, so replacing it must not be something a deploy can do. Adds deploy.bao.agentPkiMountPath (default `pki-agents`), which the stanzas are rendered from. The module-eval case pinning the granter's policy now lists all seventeen stanzas, and the "grants nothing outside" case also refuses the agent mount's root, issue, sign and a roles/* glob.
This commit is contained in:
parent
e9cec0da21
commit
5cd7f866f4
2 changed files with 81 additions and 4 deletions
|
|
@ -185,10 +185,13 @@ let
|
|||
# A trailing `*` in a bao ACL path is a pure string-prefix match, and an
|
||||
# exact path wins over any prefix.
|
||||
#
|
||||
# The first three are the per-principal grants. The rest are what
|
||||
# The first three are the per-principal grants. The next eight are what
|
||||
# `swarm-bao-controller-policy` does besides grants: the KV and pki mounts and
|
||||
# the services root. No `sys/auth`: the auth mounts are created with the
|
||||
# bootstrap token by `swarm-bao-granter-role`.
|
||||
# the services root. The last six set up the agent PKI mount: the mount, its
|
||||
# root and the `swarm-*` role agent certificates are issued through. No
|
||||
# `root` delete there: every agent's cert-auth role pins that root by value,
|
||||
# so replacing it would lock every agent out. No `sys/auth`: the auth mounts
|
||||
# are created with the bootstrap token by `swarm-bao-granter-role`.
|
||||
#
|
||||
# Piped as a shell-quoted argument like `controllerPolicyText`, so
|
||||
# ../module-eval/bao-grants.nix can read it out of the unit script.
|
||||
|
|
@ -236,6 +239,30 @@ let
|
|||
path "${servicesPkiMountPath}/root/generate/internal" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
|
||||
path "sys/mounts/${agentPkiMountPath}" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
|
||||
path "sys/mounts/${agentPkiMountPath}/tune" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
|
||||
path "${agentPkiMountPath}/issuers" {
|
||||
capabilities = ["list"]
|
||||
}
|
||||
|
||||
path "${agentPkiMountPath}/cert/ca" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "${agentPkiMountPath}/root/generate/internal" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
|
||||
path "${agentPkiMountPath}/roles/swarm-*" {
|
||||
capabilities = ["create", "update"]
|
||||
}
|
||||
'';
|
||||
|
||||
# What a granting unit prints when the store refuses the granter: the
|
||||
|
|
@ -473,6 +500,13 @@ let
|
|||
# and has to spell it the same way.
|
||||
servicesPkiMountPath = baoDeploy.servicesPkiMountPath;
|
||||
|
||||
# The PKI mount agent client certificates are issued from. Its root is
|
||||
# generated inside the store, so the agent CA's key never exists outside it.
|
||||
# A mount of its own because the services mount holds exactly one issuer; a
|
||||
# root apart from ./glue-bao-tls.nix's CA because that is what keeps an
|
||||
# agent's certificate from satisfying any host role.
|
||||
agentPkiMountPath = baoDeploy.agentPkiMountPath;
|
||||
|
||||
# Subject of the root generated into that mount. A label for a human reading
|
||||
# a chain, not an identity anything authenticates against — same fall-through
|
||||
# ./swarm-ca.nix:29-37 uses, and for the same reason: a hive that has set
|
||||
|
|
@ -1221,6 +1255,20 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
agentPkiMountPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "pki-agents";
|
||||
description = ''
|
||||
Mount path of the PKI engine agent client certificates are issued
|
||||
from. Its root is generated inside the store and its key never leaves
|
||||
it.
|
||||
|
||||
An option rather than a literal because the store host sets the mount
|
||||
up while swarm-controller, possibly on another host, issues through
|
||||
it: both have to spell it identically.
|
||||
'';
|
||||
};
|
||||
|
||||
servicesPkiRoleName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "swarm-services";
|
||||
|
|
|
|||
Loading…
Reference in a new issue