Skip to content

fix(chatbot): fail loudly on a weak or missing AUTH_SECRET - #644

Open
harrymove-ctrl wants to merge 1 commit into
devfrom
fix/auth-secret-validation
Open

fix(chatbot): fail loudly on a weak or missing AUTH_SECRET#644
harrymove-ctrl wants to merge 1 commit into
devfrom
fix/auth-secret-validation

Conversation

@harrymove-ctrl

@harrymove-ctrl harrymove-ctrl commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • While debugging why Enoki sign-in was broken on researcher-demo-staging, found the root cause: staging's researcher-frontend has an AUTH_SECRET that's only 8 characters long. apps/researcher/lib/auth/enoki-challenge.ts correctly rejects it (AUTH_SECRET must contain at least 32 characters), which is what surfaces as the generic "Unable to verify wallet ownership" error in the UI.
  • Checked the other two apps that touch staging auth for the same issue:
    • noter-frontend — not affected. Its Enoki challenge flow (apps/noter/package/feature/auth/lib/enoki-challenge.ts) is stateless via Redis nonces, no AUTH_SECRET dependency at all.
    • chatbot-frontendhas the same 8-character AUTH_SECRET value as researcher-frontend, but nothing validates it, so NextAuth just signs session/guest JWTs with a short HS256 key instead of erroring. Silent security weakness, not a visible bug — which is why it hadn't been caught.
  • This PR adds the same defensive check chatbot is missing: getAuthSecret() (mirrors researcher's existing guard) throws if AUTH_SECRET is unset or under 32 chars, wired into the three places chatbot reads it directly (auth.ts, guest/route.ts, proxy.ts).

Not included here (needs a separate ops action, not code)

The actual staging secrets still need to be rotated to real random values on Railway (in progress, separately — not via this PR):

  • researcher-frontend (staging): currently broken (Enoki login 500s) until rotated
  • chatbot-frontend (staging): currently "working" but weakly signed until rotated

Both are runtime config changes, not something this PR touches — flagging for a follow-up once this merges, so chatbot starts failing loudly the same way researcher already does if it's ever deployed with a weak value again.

Test plan

  • CI (lint/build/typecheck) passes
  • Manually confirm chatbot boots normally on an environment with a proper AUTH_SECRET
  • Confirm chatbot fails fast (clear error, not silent) if AUTH_SECRET is unset or short, e.g. locally with AUTH_SECRET=short pnpm --filter chatbot dev

NextAuth silently accepts any AUTH_SECRET value, including an unset or
short one, and just signs session/guest JWTs with it. Staging currently
has an 8-character AUTH_SECRET on chatbot-frontend — same weak value as
researcher-frontend, which is caught and rejected by its own
getSecret() guard (enoki-challenge.ts). Chatbot had no equivalent
check, so the weak secret degrades security silently instead of
surfacing an error.

Adds getAuthSecret() (apps/chatbot/lib/auth-secret.ts), mirroring
researcher's >=32-char validation, and wires it into the three places
that read AUTH_SECRET directly: auth.ts, guest/route.ts, proxy.ts.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants