Watch
0
0
Fork
You've already forked hyperhive
0

swarm: drop the -agent client suffix refusal from authelia and the queue responder

authelia.agentClientSuffix is removed (tombstoned) and the responder
takes no --agent-client-suffix: hive-<name>-agent is parsed as hive
<name>-agent like any other id. The reserved word agent still keeps a
hive from being named *-agent.
This commit is contained in:
atlas 2026-10-24 14:42:55 +02:00 • committed by mara
commit e01770c056
12 changed files with 33 additions and 233 deletions

View file

@ -125,21 +125,6 @@ struct Args {
#[arg(long, default_value = "hive-")]
hive_client_prefix: String,
/// Suffix appended to a hive's own client id: `hive-<name>-agent`. No
/// client is minted with it — agents authenticate with their own secret —
/// so the responder refuses it; the suffix is what tells such an id apart
/// from the hive `<name>-agent`.
///
/// 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
/// this identity does not carry.
///
/// A suffix starts with `-`, so it has to be accepted as a value rather
/// than read as a short-flag cluster — without this the default below
/// cannot be passed back in on the command line that produced it.
#[arg(long, default_value = "-agent", allow_hyphen_values = true)]
agent_client_suffix: String,
/// Client ids allowed to read every hive's status. Repeatable. The
/// default is the swarm controller, which is the only reader that exists.
#[arg(long = "reader-client", default_values_t = [String::from("swarm-controller")])]
@ -239,7 +224,6 @@ async fn serve(args: Args) -> anyhow::Result<()> {
// silently over-broad grant is not.
let policy = policy::Policy::new(
args.hive_client_prefix.clone(),
args.agent_client_suffix.clone(),
swarm_queue_client::status::BUCKET.to_owned(),
args.reader_clients.clone(),
args.hive_publish_subjects.clone(),
@ -607,11 +591,10 @@ mod tests {
})
}
/// The argument vector `swarm-nats.nix` actually builds, in the form it
/// builds it: every flag space-separated, and the suffix's value opening
/// with `-`. Read as a short-flag cluster it aborts before `main` runs,
/// and a responder that never starts denies every client — which reaches
/// the operator as `authorization violation` on an unrelated process.
/// The argument vector `swarm-nats.nix` actually builds, every flag
/// space-separated. A parse failure aborts before `main` runs, and a
/// responder that never starts denies every client — which reaches the
/// operator as `authorization violation` on an unrelated process.
#[test]
fn the_units_own_argument_vector_parses() {
let args = responder([
@ -620,8 +603,6 @@ mod tests {
"https://auth.example/api/oidc/introspection",
"--hive-client-prefix",
"hive-",
"--agent-client-suffix",
"-agent",
"--agent-token-publish-subject",
"$SWARM.term.{agent}",
"--agent-token-publish-subject",
@ -638,7 +619,6 @@ mod tests {
"swarm-nats-auth",
])
.expect("the unit's own argument vector must parse");
assert_eq!(args.agent_client_suffix, "-agent");
assert_eq!(args.agent_token_publish_subjects.len(), 6);
}
@ -704,16 +684,11 @@ mod tests {
"https://auth.example/api/oidc/introspection",
])
.expect("the required flags alone must parse");
let policy = policy::Policy::new(
"hive-".to_owned(),
"-agent".to_owned(),
"hive-status".to_owned(),
vec![],
vec![],
)
.expect("valid")
.with_agent_token_subjects(vec!["$SWARM.term.{agent}".to_owned()])
.expect("valid");
let policy =
policy::Policy::new("hive-".to_owned(), "hive-status".to_owned(), vec![], vec![])
.expect("valid")
.with_agent_token_subjects(vec!["$SWARM.term.{agent}".to_owned()])
.expect("valid");
let client_secret =
oidc_secret::OidcSecret::new(swarm_secret_client::stored_secret::StoredSecret::new(
"swarm-nats",
@ -847,35 +822,6 @@ mod tests {
assert!(!expired(None, at(1_760_000_001_000)));
}
/// The control for the case above: an ordinary value parses through the
/// same flag, so a failure there is about the leading `-` and not about
/// the argument being unknown.
#[test]
fn an_agent_suffix_without_a_leading_dash_parses_too() {
let args = responder([
"swarm-nats-auth",
"--introspection-url",
"https://auth.example/api/oidc/introspection",
"--agent-client-suffix",
"agent",
])
.expect("an ordinary suffix must parse");
assert_eq!(args.agent_client_suffix, "agent");
}
/// The default is the value the deployment passes, so the two cannot
/// drift into disagreeing about what an agent client is called.
#[test]
fn the_default_suffix_is_what_the_module_passes() {
let args = responder([
"swarm-nats-auth",
"--introspection-url",
"https://auth.example/api/oidc/introspection",
])
.expect("the required flags alone must parse");
assert_eq!(args.agent_client_suffix, "-agent");
}
/// The verb as `swarm-bao-nats-callout-xkey` runs it, with none of the
/// responder's required flags.
#[test]