drop the shared hive agent login
Every agent now connects to the queue and reads logs with its own secret from the store (#5181), so the per-hive `hive-<h>-agent` OIDC client has no reader left. Remove it end to end: - hive-c0re no longer forwards `hive-queue-agent-{secret,client-id}` into containers, and no longer forwards HIVE_AGENT_OIDC_TOKEN_ENDPOINT; the agent module that loaded them (nix/agent-modules/queue.nix) is gone, its options refused with a removal message. - The host reader (glue-queue-agent-credential.nix, swarm-bao-queue-agent), its store role and policy unit (swarm-bao-queue-agent-policy), its PKI leaf and the deploy.bao.queueAgent* / queue.agentCredentialDir options are gone; the options are refused with a removal message. - authelia mints no `hive-<h>-agent` client, and swarm-secret-publish no longer writes swarm/hives/<h>/queue/agent. - swarm-secret-client drops queue::agent_client_path / queue::Credential. - HIVE_AGENT_NATS_URL is now gated on the agents' queue address alone. The log store's authelia check stays for operators. swarm-nats-auth still refuses a `-agent` client id; that refusal and `agentClientSuffix` are left for a follow-up. Refs #4459 Refs #4765
This commit is contained in:
parent
d19bd83aa5
commit
868c6cf96c
41 changed files with 286 additions and 1410 deletions
|
|
@ -106,14 +106,11 @@ let
|
|||
deploy.matrix.enable = true;
|
||||
};
|
||||
|
||||
# The store with none of the readers beside it. Grafana and the collector are
|
||||
# simply off; the queue reader renders on any host holding
|
||||
# its leaf, which ./glue-bao-tls.nix mints here, so that leaf is taken away.
|
||||
# The store with none of the readers beside it: Grafana and the collector are
|
||||
# off.
|
||||
baoGrantNoReaders = hiveWithController {
|
||||
deploy.bao.enable = true;
|
||||
deploy.bao.bootstrapTokenFile = "/run/secrets/bao-bootstrap.token";
|
||||
deploy.bao.queueAgentClientCertFile = lib.mkForce null;
|
||||
deploy.bao.queueAgentClientKeyFile = lib.mkForce null;
|
||||
};
|
||||
|
||||
# The store with the forwarder's own pair taken away. The forwarder renders
|
||||
|
|
@ -131,8 +128,6 @@ let
|
|||
deploy.swarm-otel.enable = true;
|
||||
deploy.bao.clientCertFile = "/etc/pki/bao-client.pem";
|
||||
deploy.bao.clientKeyFile = "/etc/pki/bao-client-key.pem";
|
||||
deploy.bao.queueAgentClientCertFile = "/etc/pki/bao-queue-agent.pem";
|
||||
deploy.bao.queueAgentClientKeyFile = "/etc/pki/bao-queue-agent-key.pem";
|
||||
deploy.bao.grafanaOidcClientCertFile = "/etc/pki/bao-grafana-oidc.pem";
|
||||
deploy.bao.grafanaOidcClientKeyFile = "/etc/pki/bao-grafana-oidc-key.pem";
|
||||
deploy.bao.otelOidcClientCertFile = "/etc/pki/bao-otel-oidc.pem";
|
||||
|
|
@ -142,7 +137,6 @@ let
|
|||
# The readers ./glue-bao-readers-policy-order.nix orders after their policy
|
||||
# units.
|
||||
policyReaders = [
|
||||
"swarm-bao-queue-agent"
|
||||
"swarm-bao-grafana-oidc"
|
||||
"swarm-bao-otel-oidc"
|
||||
];
|
||||
|
|
@ -175,7 +169,6 @@ let
|
|||
"swarm-bao-controller-policy"
|
||||
"swarm-bao-secret-publisher-policy"
|
||||
"swarm-bao-matrix-ctl-policy"
|
||||
"swarm-bao-queue-agent-policy"
|
||||
"swarm-bao-grafana-oidc-policy"
|
||||
"swarm-bao-otel-oidc-policy"
|
||||
"swarm-bao-forwarder-oidc-policy"
|
||||
|
|
@ -599,19 +592,18 @@ let
|
|||
# arms pin what each principal must NOT reach, so a later widening fails
|
||||
# here instead of being noticed in a store.
|
||||
{
|
||||
name = "the queue-credential reader's grant is one hive's queue credential and nothing else";
|
||||
# A hive holds no shared queue credential for its agents: no unit writes
|
||||
# a role or policy for one, none reads one, and no granting unit names
|
||||
# its path. The control: the same scan finds a reader's grant.
|
||||
name = "no unit grants, reads or writes a hive-shared agent queue credential";
|
||||
ok =
|
||||
let
|
||||
s = baoGrantHere.systemd.services.swarm-bao-queue-agent-policy.script;
|
||||
scripts = lib.mapAttrsToList (_: u: u.script or "") baoGrantWithConsumers.systemd.services;
|
||||
in
|
||||
lib.hasInfix "path \"secret/data/swarm/hives/h1/queue/agent\" {" s
|
||||
&& lib.hasInfix "capabilities = [\"read\"]" s
|
||||
&& !(lib.hasInfix "secret/data/swarm/agents" s)
|
||||
&& !(lib.hasInfix "secret/data/swarm/services" s)
|
||||
&& !(lib.hasInfix "secret/data/swarm/hives/h1/*" s)
|
||||
&& !(lib.hasInfix "secret/data/swarm/hives/h1/matrix" s)
|
||||
&& !(lib.hasInfix "secret/data/swarm/hives/*" s)
|
||||
&& !(lib.hasInfix "sys/policies/acl" s);
|
||||
!(baoGrantWithConsumers.systemd.services ? swarm-bao-queue-agent-policy)
|
||||
&& !(baoGrantWithConsumers.systemd.services ? swarm-bao-queue-agent)
|
||||
&& !(lib.any (lib.hasInfix "/queue/agent") scripts)
|
||||
&& lib.any (lib.hasInfix "/oidc/client") scripts;
|
||||
}
|
||||
{
|
||||
# ⚠️ The client id is the path segment, so the negative arm that matters
|
||||
|
|
@ -856,11 +848,7 @@ let
|
|||
# through a token that carries it, and a token is minted by a cert-auth
|
||||
# role matching a CN. Distinct subjects is the whole mechanism — one
|
||||
# subject for every reader is one principal however the policies read.
|
||||
#
|
||||
# The per-hive subject carries the hive name because its path does; the
|
||||
# service subjects do not, because an OIDC client is registered once
|
||||
# per swarm. Pinned so neither shape is tidied into the other.
|
||||
name = "each of the four readers logs in under a subject of its own";
|
||||
name = "each of the three readers logs in under a subject of its own";
|
||||
ok =
|
||||
let
|
||||
subjectOf =
|
||||
|
|
@ -875,8 +863,7 @@ let
|
|||
# the reason the three service principals above state.
|
||||
&& !(lib.hasInfix "auth/cert/certs/hive-" s);
|
||||
in
|
||||
subjectOf "swarm-bao-queue-agent-policy" "swarm-queue-agent-h1" "swarm-bao-queue-agent-h1"
|
||||
&& subjectOf "swarm-bao-grafana-oidc-policy" "swarm-grafana-oidc" "swarm-bao-grafana-oidc"
|
||||
subjectOf "swarm-bao-grafana-oidc-policy" "swarm-grafana-oidc" "swarm-bao-grafana-oidc"
|
||||
&& subjectOf "swarm-bao-otel-oidc-policy" "swarm-otel-oidc" "swarm-bao-otel-oidc"
|
||||
&& subjectOf "swarm-bao-forwarder-oidc-policy" "swarm-forwarder-oidc" "swarm-bao-forwarder-oidc";
|
||||
}
|
||||
|
|
@ -889,7 +876,7 @@ let
|
|||
#
|
||||
# Each pair is asserted whole: a certificate with no key authenticates
|
||||
# nothing, so a half-set pair is a reader that does not render.
|
||||
name = "each of the four readers presents its own leaf, never the hive's";
|
||||
name = "each of the three readers presents its own leaf, never the hive's";
|
||||
ok =
|
||||
let
|
||||
b = baoGrantWithConsumers.services.hyperhive.deploy.bao;
|
||||
|
|
@ -898,8 +885,6 @@ let
|
|||
b.clientKeyFile
|
||||
];
|
||||
own = [
|
||||
b.queueAgentClientCertFile
|
||||
b.queueAgentClientKeyFile
|
||||
b.grafanaOidcClientCertFile
|
||||
b.grafanaOidcClientKeyFile
|
||||
b.otelOidcClientCertFile
|
||||
|
|
@ -915,7 +900,6 @@ let
|
|||
lib.all (p: p != null) own
|
||||
&& !(lib.any (p: lib.elem p hiveLeaf) own)
|
||||
&& lib.length (lib.unique own) == lib.length own
|
||||
&& presents "swarm-bao-queue-agent" b.queueAgentClientCertFile b.queueAgentClientKeyFile
|
||||
&& presents "swarm-bao-grafana-oidc" b.grafanaOidcClientCertFile b.grafanaOidcClientKeyFile
|
||||
&& presents "swarm-bao-otel-oidc" b.otelOidcClientCertFile b.otelOidcClientKeyFile
|
||||
&& presents "swarm-bao-forwarder-oidc" b.forwarderOidcClientCertFile b.forwarderOidcClientKeyFile;
|
||||
|
|
@ -923,9 +907,7 @@ let
|
|||
{
|
||||
# The minting side of the same claim. A role matching a subject nothing
|
||||
# signs is a reader that cannot log in, so the leaves and the roles have
|
||||
# to be asserted against each other — and the per-hive leaf carries
|
||||
# THIS host's hive name, which is what makes one hive's leaf useless
|
||||
# against another hive's role.
|
||||
# to be asserted against each other.
|
||||
name = "the PKI unit signs a leaf per reader, each under that reader's own subject";
|
||||
ok =
|
||||
let
|
||||
|
|
@ -936,8 +918,6 @@ let
|
|||
# literal spanning both would pin this file's line wrapping rather than
|
||||
# the pairing it means to.
|
||||
lib.all (lib.flip lib.hasInfix s) [
|
||||
"/queue-agent.pem ]"
|
||||
"swarm-bao-queue-agent-h1 \"\" clientAuth"
|
||||
"/grafana-oidc.pem ]"
|
||||
"swarm-bao-grafana-oidc \"\" clientAuth"
|
||||
"/otel-oidc.pem ]"
|
||||
|
|
@ -965,11 +945,10 @@ let
|
|||
# client certificate and the host is the side that has one, so a unit
|
||||
# rendered inside the store's container would have neither an identity
|
||||
# nor a route. Plus the ordering that makes the mounts exist first.
|
||||
name = "the four readers' granting units are ordered after the mounts and rendered on the host";
|
||||
name = "the three readers' granting units are ordered after the mounts and rendered on the host";
|
||||
ok =
|
||||
let
|
||||
units = [
|
||||
"swarm-bao-queue-agent-policy"
|
||||
"swarm-bao-grafana-oidc-policy"
|
||||
"swarm-bao-otel-oidc-policy"
|
||||
"swarm-bao-forwarder-oidc-policy"
|
||||
|
|
@ -990,7 +969,7 @@ let
|
|||
# The forwarder is listed apart from `policyReaders`: it renders wherever
|
||||
# the store does, so it is never absent on a store host and never present
|
||||
# on a remote one, and the two cases below would fail on it for that.
|
||||
name = "each of the four readers is ordered after the unit writing its role";
|
||||
name = "each of the three readers is ordered after the unit writing its role";
|
||||
ok =
|
||||
let
|
||||
s = baoGrantWithConsumers.systemd.services;
|
||||
|
|
@ -1483,9 +1462,9 @@ let
|
|||
}
|
||||
{
|
||||
# The other hives' side: every hive in the directory but this one gets
|
||||
# the same three leaves, under its own name, in a directory of its own
|
||||
# the same two leaves, under its own name, in a directory of its own
|
||||
# that the operator copies to its host.
|
||||
name = "the PKI unit signs every other hive's reader, queue-agent and gateway-leaf identities";
|
||||
name = "the PKI unit signs every other hive's reader and gateway-leaf identities";
|
||||
ok =
|
||||
let
|
||||
s = baoGrantTwoHives.systemd.services.swarm-bao-pki.script;
|
||||
|
|
@ -1494,7 +1473,6 @@ let
|
|||
file: cn: lib.hasInfix "/hives/h2/${file}.pem ]" s && lib.hasInfix " ${cn} \"\" clientAuth" s;
|
||||
in
|
||||
signs "client" "h2"
|
||||
&& signs "queue-agent" "${b.queueAgentCommonNamePrefix}-h2"
|
||||
&& signs "hive-leaf" "${b.hiveLeafCommonNamePrefix}-h2"
|
||||
# This hive's own leaves stay at the top of the directory.
|
||||
&& !(lib.hasInfix "/hives/h1/" s);
|
||||
|
|
|
|||
Loading…
Reference in a new issue