Watch
0
0
Fork
You've already forked hyperhive
0

swarm: drop the stale claim that authelia mints hive-<name>-agent

This commit is contained in:
atlas 2026-10-13 10:16:30 +02:00 • committed by mara
commit 495c45c2c2
6 changed files with 23 additions and 32 deletions

View file

@ -75,21 +75,15 @@ in
type = lib.types.bool; type = lib.types.bool;
default = true; default = true;
description = '' description = ''
Mint machine clients per hive in Mint one machine client per hive in
{option}`services.hyperhive.swarm.hives`, so each hive can {option}`services.hyperhive.swarm.hives`, so each hive can
authenticate to swarm services as itself: `hive-<name>` for the authenticate to swarm services as itself: `hive-<name>`, for the
hive's own daemons, and `hive-<name>-agent` for the agent containers hive's own daemons.
running on it.
Two clients rather than one because they are not the same Agent containers get no client here: agents are created at runtime,
principal — a hive's daemons run on the host and an agent runs and a per-agent client would make creating one a config change plus
in a container the host hands a credential to, so a swarm an authelia reload. An agent authenticates with its own secret from
service has to be able to grant them different things. It is the swarm store instead.
one client per *hive* on the agent side, not per agent: agents
are created at runtime, and a per-agent client would make
creating one a config change plus an authelia reload. The cost
is that agents on a hive are indistinguishable from each other,
tracked as a follow-up rather than papered over.
On by default: a swarm's hives have identities, and that is a On by default: a swarm's hives have identities, and that is a
fact about the swarm rather than about any one host. It does not fact about the swarm rather than about any one host. It does not

View file

@ -360,8 +360,9 @@ in
fragments = reservedFragments; fragments = reservedFragments;
why = '' why = ''
Hive-scoped identifiers are composed from a hive name — Hive-scoped identifiers are composed from a hive name —
`hive-<name>`, `hive-<name>-agent` — so a name containing one of `hive-<name>`, and that id with a suffix the queue's responder
these produces an identifier that is also somebody else's. The refuses — so a name containing one of these produces an identifier
that is also somebody else's, or one the responder refuses. The
failure is a wrong grant rather than an error: the client failure is a wrong grant rather than an error: the client
authenticates and receives another principal's permissions, and a authenticates and receives another principal's permissions, and a
NATS denial arrives as a timeout. Rename the hive. NATS denial arrives as a timeout. Rename the hive.

View file

@ -9,8 +9,8 @@
# `hive-<name>` — every hive's OIDC client id, and the string the queue's # `hive-<name>` — every hive's OIDC client id, and the string the queue's
# auth-callout responder strips to decide which hive a connection is. # auth-callout responder strips to decide which hive a connection is.
"hive" "hive"
# `hive-<name>-agent` — the client its agent containers present. A hive named # `hive-<name>-agent` — an id the queue's responder refuses. A hive named
# `foo-agent` mints exactly the id hive `foo`'s agents do. # `foo-agent` would mint exactly that id for itself.
"agent" "agent"
# Also an exact-match entry next door, for the collector's `<kind>/<owner>` # Also an exact-match entry next door, for the collector's `<kind>/<owner>`
# components. Here because it is the word this swarm composes identifiers # components. Here because it is the word this swarm composes identifiers

View file

@ -125,15 +125,10 @@ struct Args {
#[arg(long, default_value = "hive-")] #[arg(long, default_value = "hive-")]
hive_client_prefix: String, hive_client_prefix: String,
/// Suffix that marks an agent container, appended to the hive's own client /// Suffix appended to a hive's own client id: `hive-<name>-agent`. No
/// id: `swarm-authelia.nix` mints one machine client per roster entry as /// client is minted with it — agents authenticate with their own secret —
/// `hive-<name>-agent` — per **hive**, not per agent, because agents are /// so the responder refuses it; the suffix is what tells such an id apart
/// created at runtime and a per-agent client would make creating one a /// from the hive `<name>-agent`.
/// config change plus a reload.
///
/// So this identity says which hive an agent belongs to and never which
/// agent: two agents on one hive are indistinguishable under it. The
/// responder refuses it; the suffix is what tells it apart from a hive.
/// ///
/// A suffix on the hive's id rather than a prefix of its own, because /// A suffix on the hive's id rather than a prefix of its own, because
/// `agent-<name>` reads as *the agent called `<name>`* — the one thing /// `agent-<name>` reads as *the agent called `<name>`* — the one thing
@ -413,8 +408,8 @@ impl<S: swarm_agent_verify::CredentialSource> Responder<S> {
}; };
// The caller is an identifier, not a credential: a client id, or // The caller is an identifier, not a credential: a client id, or
// `agent:<name>` for an agent token. One line per auth request, a connect // `agent:<name>` for an agent token. One line per auth request, a connect
// or a reconnect, so `hive-<h>-agent` lines count requests made on a // or a reconnect, so a `hive-<h>` line counts requests made on
// hive's shared credential, not agents. // a hive's own credential.
tracing::info!( tracing::info!(
user_nkey = %req.user_nkey, user_nkey = %req.user_nkey,
server_id = %req.server_id.id, server_id = %req.server_id.id,

View file

@ -63,7 +63,7 @@ const AGENT_PLACEHOLDER: &str = "{agent}";
impl Policy { impl Policy {
/// `hive_prefix` is the client-id prefix that marks a hive and /// `hive_prefix` is the client-id prefix that marks a hive and
/// `agent_suffix` what a hive's agent containers carry **on top of** it — /// `agent_suffix` the suffix the responder refuses **on top of** it —
/// `hive-<name>` and `hive-<name>-agent`. `bucket` is the KV bucket hives /// `hive-<name>` and `hive-<name>-agent`. `bucket` is the KV bucket hives
/// report status in, `readers` the client ids allowed to read every hive's /// report status in, `readers` the client ids allowed to read every hive's
/// key, and `extra_hive_subjects` additional subjects a hive may publish to /// key, and `extra_hive_subjects` additional subjects a hive may publish to

View file

@ -65,8 +65,9 @@ pub fn hive_object_name(hive: &str) -> Result<String, Error> {
/// `hive-<hive>`, so a collision needs a hive named `agent-<agent>` — and /// `hive-<hive>`, so a collision needs a hive named `agent-<agent>` — and
/// `nix/reserved-hive-fragments.nix` forbids the substring `agent` in any hive /// `nix/reserved-hive-fragments.nix` forbids the substring `agent` in any hive
/// name (and `hive` too), applied to every entry of the swarm directory in /// name (and `hive` too), applied to every entry of the swarm directory in
/// `swarm.nix`. That guard was written for the queue's `hive-<name>-agent` /// `swarm.nix`. That guard also keeps a hive's client id clear of the
/// client ids; this is a second identifier family leaning on it, which is why /// `hive-<name>-agent` form the queue refuses; this is a second identifier
/// family leaning on it, which is why
/// the fragment list is what to read before renaming either. /// the fragment list is what to read before renaming either.
/// ///
/// Host principals' **common names** are operator-set options /// Host principals' **common names** are operator-set options