From 856106174a6260dabe55c96409dd694fc4908eca Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Thu, 11 Jun 2026 12:47:14 -0400 Subject: [PATCH] =?UTF-8?q?fix(nats):=20no=5Fauth=5Fuser=20is=20top-level,?= =?UTF-8?q?=20not=20inside=20authorization{}=20=E2=80=94=20broke=20broker?= =?UTF-8?q?=20startup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caught during the live cutover: nats-server rejects 'unknown field no_auth_user' when it is nested in the authorization block, taking the whole broker down. Both the generator (open stage) and the committed bootstrap default emitted it nested. Moved to top level. Enforce-stage output was unaffected (no no_auth_user), which is what the live broker now runs. Co-Authored-By: Claude Fable 5 --- docker/nats-auth.conf | 4 +++- scripts/generate-nats-auth.mjs | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docker/nats-auth.conf b/docker/nats-auth.conf index dd9329f..001e445 100644 --- a/docker/nats-auth.conf +++ b/docker/nats-auth.conf @@ -8,9 +8,11 @@ # On every real deploy, scripts/generate-nats-auth.mjs OVERWRITES this file # (on the host, not in git) with the privileged internal user + per-license # scoped users. NATS_AUTH_STAGE defaults to "enforce" (anonymous rejected). +# +# NOTE: no_auth_user is a TOP-LEVEL field, NOT inside authorization { }. authorization { users: [ { user: "anonymous", password: "", permissions: { publish: { allow: ["corrosion.unclaimed.>"] }, subscribe: { allow: ["corrosion.unclaimed.>"] } } } ] - no_auth_user: "anonymous" } +no_auth_user: "anonymous" diff --git a/scripts/generate-nats-auth.mjs b/scripts/generate-nats-auth.mjs index df600d4..11c951e 100644 --- a/scripts/generate-nats-auth.mjs +++ b/scripts/generate-nats-auth.mjs @@ -86,10 +86,12 @@ const main = async () => { lines.push(' { user: "anonymous", password: "", permissions: { publish: { allow: ["corrosion.unclaimed.>"] }, subscribe: { allow: ["corrosion.unclaimed.>"] } } }'); } lines.push(' ]'); - if (NATS_AUTH_STAGE === 'open') { - lines.push(' no_auth_user: "anonymous"'); - } lines.push('}'); + // no_auth_user is a TOP-LEVEL field, NOT inside authorization { } — nesting + // it makes nats-server reject the whole config ("unknown field no_auth_user"). + if (NATS_AUTH_STAGE === 'open') { + lines.push('no_auth_user: "anonymous"'); + } process.stdout.write(lines.join('\n') + '\n'); };