fix(swarm): name the account by aud, never issuer_account

The responder answered granted=true and the server still refused every
client:

  Error non operator mode account "AUTH": attempted to use issuer_account

nats_jwt::Token::new_user always sets issuer_account, which is an
operator-mode field naming the account when a signing key rather than the
account identity key signed the token. In server-config mode - what this
module renders - its mere presence is fatal, and the account is named by
the claims' aud instead.

nats-jwt can express neither aud nor the omission, so the user JWT is now
hand-built by the same signer as the response wrapper, and nats-jwt moves
to dev-dependencies as the encoder's test oracle.

Every unit test passed throughout: they assert fields that must be
present, and the defect was a field that must be absent.
This commit is contained in:
atlas 2026-08-14 22:26:02 +02:00 committed by mara
commit 188e27478a
4 changed files with 144 additions and 36 deletions

View file

@ -63,6 +63,13 @@ struct Args {
#[arg(long, default_value = "swarm-nats")]
client_id: String,
/// Account an admitted client is placed in. Must name an entry in the
/// server's own `accounts` block — in server-config mode the account is
/// resolved by *name*, so a value the server does not know is a grant it
/// refuses. The module passes its `clientAccount`; the default mirrors it.
#[arg(long, default_value = "APP")]
account: String,
/// Path to this responder's own OIDC client secret.
#[arg(long)]
client_secret_file: PathBuf,
@ -162,12 +169,7 @@ async fn main() -> anyhow::Result<()> {
continue;
};
let token = if granted {
respond::grant(
&issuer,
&issuer.public_key(),
&req.server_id.id,
&req.user_nkey,
)
respond::grant(&issuer, &args.account, &req.server_id.id, &req.user_nkey)
} else {
respond::deny(&issuer, &req.server_id.id, &req.user_nkey)
};