Skip to content
This repository was archived by the owner on Apr 13, 2026. It is now read-only.

Commit 7dd574d

Browse files
authored
Disable demo auth when SSO providers are configured (#77)
### Motivation - Prevent the insecure demo login from remaining enabled when any SSO provider is configured, reducing risk of accidental public demo access. - Align provider registration to the validated `env` surface so server-side feature gating uses the same canonical env values. ### Description - Compute `ssoProvidersEnabled` and make `demoModeEnabled` require no SSO in `src/server/auth/config.ts`, and register providers using `env.*` instead of `process.env.*`. - Update the sign-in page `src/app/(public-routes)/auth/signin/page.tsx` to hide the demo button when any SSO provider is enabled by computing `ssoEnabled` and gating `demoEnabled` accordingly. - Add a short note to `docs/installation.md` explaining that demo mode is automatically disabled when any SSO provider is configured. ### Testing - No automated tests were run as part of this change. ------ [Codex Task](https://chatgpt.com/codex/tasks/task_e_696b5fbdbcfc8323ab20ae16f2ea516b)
1 parent f181ced commit 7dd574d

3 files changed

Lines changed: 28 additions & 20 deletions

File tree

docs/installation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Minimum values to edit:
2929
RTAP supports SSO or a demo login button. Supported SSO providers today are Google, GitHub, GitLab, Keycloak, and Okta. If you need another provider, open an issue and we can add it.
3030

3131
- **SSO (recommended):** configure your provider's details (client ID/secret, plus issuer for Keycloak/Okta) using the variable names provided in the .env file.
32-
- **Demo mode:** set `ENABLE_DEMO_MODE=true`. This exposes a “Sign in as Demo Admin” button and **anyone with access to the sign-in page can log in without an account**. Use only for isolated testing or demos.
32+
- **Demo mode:** set `ENABLE_DEMO_MODE=true`. This exposes a “Sign in as Demo Admin” button and **anyone with access to the sign-in page can log in without an account**. Use only for isolated testing or demos. Demo mode is automatically disabled when any SSO provider is configured.
3333

3434
For any SSO provider, configure the following in your identity provider console:
3535

src/app/(public-routes)/auth/signin/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ export default async function SignInPage(props: { searchParams?: Promise<{ callb
1010
}
1111

1212
const { callbackUrl = "/", error } = (await props.searchParams) ?? {};
13-
const demoEnabled = env.ENABLE_DEMO_MODE === "true";
1413
const googleEnabled = Boolean(env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET);
1514
const githubEnabled = Boolean(env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET);
1615
const gitlabEnabled = Boolean(env.GITLAB_CLIENT_ID && env.GITLAB_CLIENT_SECRET);
1716
const keycloakEnabled = Boolean(env.KEYCLOAK_CLIENT_ID && env.KEYCLOAK_CLIENT_SECRET && env.KEYCLOAK_ISSUER);
1817
const oktaEnabled = Boolean(env.OKTA_CLIENT_ID && env.OKTA_CLIENT_SECRET && env.OKTA_ISSUER);
18+
const ssoEnabled = googleEnabled || githubEnabled || gitlabEnabled || keycloakEnabled || oktaEnabled;
19+
const demoEnabled = env.ENABLE_DEMO_MODE === "true" && !ssoEnabled;
1920

2021
return (
2122
<SignInPageClient

src/server/auth/config.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,14 @@ declare module "@auth/core/adapters" {
4343
// Local extension for JWT to carry role information
4444
type AugmentedJWT = NextAuthJWT & { role?: UserRole };
4545

46-
const demoModeEnabled = env.ENABLE_DEMO_MODE === "true";
46+
const ssoProvidersEnabled = [
47+
env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET,
48+
env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET,
49+
env.GITLAB_CLIENT_ID && env.GITLAB_CLIENT_SECRET,
50+
env.KEYCLOAK_CLIENT_ID && env.KEYCLOAK_CLIENT_SECRET && env.KEYCLOAK_ISSUER,
51+
env.OKTA_CLIENT_ID && env.OKTA_CLIENT_SECRET && env.OKTA_ISSUER,
52+
].some(Boolean);
53+
const demoModeEnabled = env.ENABLE_DEMO_MODE === "true" && !ssoProvidersEnabled;
4754
const oauthProviders = new Set(["google", "github", "gitlab", "keycloak", "okta"]);
4855

4956
const isRecord = (value: unknown): value is Record<string, unknown> =>
@@ -196,51 +203,51 @@ export const authConfig = {
196203
: []),
197204
// Conditionally register providers when env credentials are available.
198205
// Actual enablement is enforced via DB in the signIn callback/UI.
199-
...(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET
206+
...(env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET
200207
? [
201208
GoogleProvider({
202-
clientId: process.env.GOOGLE_CLIENT_ID,
203-
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
209+
clientId: env.GOOGLE_CLIENT_ID,
210+
clientSecret: env.GOOGLE_CLIENT_SECRET,
204211
// We trust the locally provisioned accounts and block unknown e-mails in the
205212
// sign-in callback, so allow Auth.js to link Google users directly by e-mail.
206213
allowDangerousEmailAccountLinking: true,
207214
}),
208215
]
209216
: []),
210-
...(process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET
217+
...(env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET
211218
? [
212219
GitHubProvider({
213-
clientId: process.env.GITHUB_CLIENT_ID,
214-
clientSecret: process.env.GITHUB_CLIENT_SECRET,
220+
clientId: env.GITHUB_CLIENT_ID,
221+
clientSecret: env.GITHUB_CLIENT_SECRET,
215222
allowDangerousEmailAccountLinking: true,
216223
}),
217224
]
218225
: []),
219-
...(process.env.GITLAB_CLIENT_ID && process.env.GITLAB_CLIENT_SECRET
226+
...(env.GITLAB_CLIENT_ID && env.GITLAB_CLIENT_SECRET
220227
? [
221228
GitLabProvider({
222-
clientId: process.env.GITLAB_CLIENT_ID,
223-
clientSecret: process.env.GITLAB_CLIENT_SECRET,
229+
clientId: env.GITLAB_CLIENT_ID,
230+
clientSecret: env.GITLAB_CLIENT_SECRET,
224231
allowDangerousEmailAccountLinking: true,
225232
}),
226233
]
227234
: []),
228-
...(process.env.KEYCLOAK_CLIENT_ID && process.env.KEYCLOAK_CLIENT_SECRET && process.env.KEYCLOAK_ISSUER
235+
...(env.KEYCLOAK_CLIENT_ID && env.KEYCLOAK_CLIENT_SECRET && env.KEYCLOAK_ISSUER
229236
? [
230237
KeycloakProvider({
231-
clientId: process.env.KEYCLOAK_CLIENT_ID,
232-
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET,
233-
issuer: process.env.KEYCLOAK_ISSUER,
238+
clientId: env.KEYCLOAK_CLIENT_ID,
239+
clientSecret: env.KEYCLOAK_CLIENT_SECRET,
240+
issuer: env.KEYCLOAK_ISSUER,
234241
allowDangerousEmailAccountLinking: true,
235242
}),
236243
]
237244
: []),
238-
...(process.env.OKTA_CLIENT_ID && process.env.OKTA_CLIENT_SECRET && process.env.OKTA_ISSUER
245+
...(env.OKTA_CLIENT_ID && env.OKTA_CLIENT_SECRET && env.OKTA_ISSUER
239246
? [
240247
OktaProvider({
241-
clientId: process.env.OKTA_CLIENT_ID,
242-
clientSecret: process.env.OKTA_CLIENT_SECRET,
243-
issuer: process.env.OKTA_ISSUER,
248+
clientId: env.OKTA_CLIENT_ID,
249+
clientSecret: env.OKTA_CLIENT_SECRET,
250+
issuer: env.OKTA_ISSUER,
244251
allowDangerousEmailAccountLinking: true,
245252
}),
246253
]

0 commit comments

Comments
 (0)