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

Commit d2dfeec

Browse files
authored
Simplify auth to SSO with optional demo mode (#69)
### Motivation - Remove the passkey / one‑time login complexity and legacy scripts to simplify startup and deployments. - Make it easy for developers to trial the system without passkeys by exposing an optional demo admin sign‑in. - Reduce surface area and legacy dependencies related to passkeys/login links and keep the auth story SSO‑first. ### Description - Replaced passkey / login‑link flows with an optional demo credentials provider gated by `ENABLE_DEMO_MODE`, and removed the one‑time login link code and helper (`src/server/auth/login-link.ts` and related constants and script). - Added `ENABLE_DEMO_MODE` to the env schema and wiring (`src/env.ts`, `.env.example`, `deploy/docker/.env.example`, and `deploy/docker/docker-compose.yml`) and made UI sign‑in pages honor the toggle (`src/app/(public-routes)/auth/signin/page.tsx`, `src/features/shared/auth/sign-in-page.tsx`). - Simplified user/profile shapes and surfaces to remove passkey metadata, updated router/service shapes to return core profile fields only, and trimmed UI that referenced passkey flows (`src/server/api/routers/users.ts`, `src/server/services/userService.ts`, `src/features/settings/components/users-tab.tsx`, `src/app/(protected-routes)/account/page.tsx`, and `src/features/shared/users/user-validators.ts`). - Updated NextAuth config to register a `demo` credentials provider when enabled, removed passkey experimental enablement and login‑link provider, and adjusted sign‑in callback logic to enforce provider rules (`src/server/auth/config.ts`). - Cleaned up tooling/docs: removed the admin login generation script and tests targeting login links, removed simplewebauthn package references, and updated README / docs / AGENTS.md to reflect the SSO‑first + demo mode approach. ### Testing - No automated test suites were executed in this rollout; unit/integration tests were adjusted to the new user/profile shapes but `npm run test` and `npm run check` were not run here. - Manual local dependency operations (`npm uninstall`/`npm install`) were performed to align package.json changes; no test failures were observed because tests were not executed. - Recommend running `npm run check` and `npm run test` after pulling these changes and before merging to validate type/lint/test coverage in CI. ------ [Codex Task](https://chatgpt.com/codex/tasks/task_e_6968d0695ea48323a8df1ca927593204)
1 parent 2f13cda commit d2dfeec

27 files changed

Lines changed: 156 additions & 504 deletions

.env.example

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ AUTH_TRUST_HOST=true
2020
#GOOGLE_CLIENT_ID=
2121
#GOOGLE_CLIENT_SECRET=
2222

23-
# Optional: enable passkey auth (default: enabled)
24-
# Set to "true" to allow passkey login and enrollment.
25-
AUTH_PASSKEYS_ENABLED=true
23+
# Optional: enable demo login (default: disabled)
24+
# Set to "true" to expose a demo admin login button on the sign-in screen.
25+
ENABLE_DEMO_MODE=false
2626

2727
# Optional: logging level (default: debug in dev, info in prod)
2828
#LOG_LEVEL=info

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ Use `eslint-plugin-boundaries` and `no-restricted-imports` to discourage cross
7272
- Do not duplicate auth checks in child layouts/pages under the group. Rely on the group layout for auth.
7373
- Keep `src/app/(protected-routes)/settings/layout.tsx` for the admin-only rule; it should only enforce `session.user.role === ADMIN` (assumes auth already passed).
7474
- Keep public auth at `src/app/(public-routes)/auth/signin/**`.
75-
- Passkey enrollment happens from the account page after first login via a one-time link.
75+
- Demo mode login is optional; when enabled it should expose a single button for the initial admin on the sign-in page.
7676
- The homepage `/` is under the protected group and does not need page-level `auth()`.
7777

7878
## API Architecture

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Red Team Assessment Platform (RTAP) is built for internal Red Teams to plan and
1616

1717
User Docs:
1818
- [Installation](docs/installation.md)
19-
- [Getting Started Workflow](docs/getting-started.md)
19+
- [Getting Started Workflow](docs/getting-started.md) (look here for UI screenshots)
2020

2121
Development Docs:
2222
- [Development](docs/development.md)
@@ -41,7 +41,7 @@ Initially based on the T3 Stack - Next.js, tRPC, Prisma, TypeScript. Type-safe A
4141

4242
Local development runs the Next.js dev server against a local PostgreSQL container. Production workloads also use Docker (web + Postgres) behind your own reverse proxy.
4343

44-
Authentication is all passwordless using NextAuth - with an option for passkeys and/or OAuth providers (initial support includes Google SSO).
44+
Authentication is passwordless and SSO-only using NextAuth. For development and trials you can enable a demo admin sign-in button via `ENABLE_DEMO_MODE=true`.
4545

4646
## Licensing
4747

deploy/docker/.env.example

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
# Full base URL where the app will be reachable (include http:// or https://).
22
# Cookies are sent over HTTPS only when this starts with https://.
33
# If you put a TLS-terminating proxy in front of rtap-web, use its public URL.
4-
# Important: Passkey auth works only over HTTPS or on localhost
54
RTAP_AUTH_URL=http://localhost:3000
65

76
# Secure values: generate with `openssl rand -base64 32`
87
RTAP_AUTH_SECRET=REPLACE_WITH_A_SECURE_RANDOM_VALUE
98
RTAP_INITIAL_ADMIN_EMAIL=admin@example.com
109

1110
# Optional SSO
12-
# Toggle passkey provider (default enabled)
13-
RTAP_AUTH_PASSKEYS_ENABLED=true
11+
# Demo mode (default disabled): expose a demo admin login button
12+
RTAP_ENABLE_DEMO_MODE=false
1413
# Register Google provider when present (optional)
1514
#RTAP_GOOGLE_CLIENT_ID=
1615
#RTAP_GOOGLE_CLIENT_SECRET=

deploy/docker/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ services:
2222
AUTH_URL: ${RTAP_AUTH_URL}
2323
AUTH_SECRET: ${RTAP_AUTH_SECRET}
2424
INITIAL_ADMIN_EMAIL: ${RTAP_INITIAL_ADMIN_EMAIL}
25-
AUTH_PASSKEYS_ENABLED: ${RTAP_AUTH_PASSKEYS_ENABLED}
25+
ENABLE_DEMO_MODE: ${RTAP_ENABLE_DEMO_MODE}
2626
GOOGLE_CLIENT_ID: ${RTAP_GOOGLE_CLIENT_ID}
2727
GOOGLE_CLIENT_SECRET: ${RTAP_GOOGLE_CLIENT_SECRET}
2828
ports:

docs/dev/DESIGN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Plan and execute red‑team operations and measure defensive effectiveness (dete
1818

1919
- Next.js 15 (App Router) + TypeScript
2020
- tRPC v11 (Zod validation); Prisma targeting PostgreSQL (local dev uses a Docker container, production uses managed Postgres)
21-
- NextAuth (passkey-first, with optional OAuth)
21+
- NextAuth (SSO-first, with optional demo admin login in development)
2222
- Access helpers enforce scoping and rights: `getAccessibleOperationFilter`, `checkOperationAccess`.
2323

2424
### Conventions (where things live)

docs/development.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ docker compose -f deploy/docker/docker-compose.dev.yml up -d
1717
# Apply migrations and seed first-run admin + MITRE content
1818
npm run init
1919

20-
# If not using SSO, generate a one-time login URL to enroll your first passkey
21-
npm run generate-admin-login
20+
# Optional: enable demo admin login (set ENABLE_DEMO_MODE=true in .env)
2221

2322
# Optionally seed demo taxonomy/operation data (FOR DEMO PURPOSES ONLY)
2423
npm run seed:demo
@@ -43,4 +42,4 @@ All PRs should pass the following:
4342
npm run check
4443
npm run test
4544
npm run build
46-
```
45+
```

docs/installation.md

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Installation
22

3-
Follow these instructions to set up Red Team Assessment Platform (RTAP) in local development or production environments.
3+
Follow these instructions to set up Red Team Assessment Platform (RTAP) for production or local testing purposes. This uses pre-built Docker containers.
4+
5+
For development environments, you'll probably instead want to run a local npm dev server - not a pre-built container. Additional information is available [here](./development.md).
46

57
## Docker Installation
68

@@ -17,36 +19,27 @@ docker compose up -d
1719
# Optionally - seed demo taxonomy/operation data (FOR DEMO PURPOSES ONLY)
1820
docker exec rtap-web npm run seed:demo
1921

20-
# If not using SSO, generate 1-time login URL to set up your first passkey
21-
docker exec rtap-web npm run generate-admin-login
22+
# Optional: enable demo admin login for trials (see Authentication below)
2223
```
2324

2425
## Authentication
2526

2627
### How it Works
2728

28-
Let's be the change we want to see in the world. There is no support for passwords! Currently supported options are:
29-
30-
- Passkeys (required TLS or localhost)
31-
- Google OAuth (SSO)
29+
Authentication is SSO-only, with an optional demo-mode button for trials.
3230

33-
The platform uses NextAuth, so adding additional SSO providers would be pretty easy.
31+
Currently, only Google SSO is enabled. However, [NextAuth supports tons of providers](https://next-auth.js.org/v3/configuration/providers#oauth-providers). Open an issue and I will add providers for you.
3432

3533
**Admin bootstrap:**
3634

3735
- On first run, the application creates an admin account using `INITIAL_ADMIN_EMAIL` from your `.env`.
38-
- If using Google SSO, just sign in with the matching Google account.
39-
- If using passkeys, you must generate a one-time login URL (`npm run generate-admin-login`) and register a passkey for that account.
36+
- If using SSO, sign in with the matching account and it will just work.
37+
- If using demo mode, click "Sign in as Demo Admin" (requires `ENABLE_DEMO_MODE=true`).
4038

4139
**Ongoing user management:**
4240

4341
- Once logged in as admin, you can create additional users.
44-
- Google SSO users: just log in with the matching Google email.
45-
- Passkey users: must receive a one-time login URL from the admin, then register a passkey.
46-
47-
**Recovery:**
48-
49-
- If locked out, re-run `npm run generate-admin-login` to obtain another single-use login URL for the initial admin account.
42+
- SSO users: log in with the matching email.
5043

5144
Accounts must be created inside the platform; SSO logins for unknown emails will be rejected.
5245

@@ -55,10 +48,10 @@ Accounts must be created inside the platform; SSO logins for unknown emails will
5548
Authentication options are configured in your `.env` file. The names are slightly different depending on whether you are doing local development or docker compose - the correct values are provided in the appropriate `.env-example` files.
5649

5750
```
58-
# Enable or disable passkey authentication
59-
AUTH_PASSKEYS_ENABLED=true
51+
# Demo mode: expose a demo admin login button on the sign-in page
52+
ENABLE_DEMO_MODE=false
6053
61-
# Configuring the follow values will enable Google SSO
54+
# Configuring the following values will enable Google SSO
6255
GOOGLE_CLIENT_ID=
6356
GOOGLE_CLIENT_SECRET=
6457
```

package-lock.json

Lines changed: 41 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"build": "next build",
88
"check": "eslint . && tsc --project tsconfig.check.json --noEmit",
99
"init": "tsx scripts/init.ts",
10-
"generate-admin-login": "tsx scripts/generate-admin-login.ts",
1110
"db:migrate": "prisma migrate dev --schema prisma/schema.prisma",
1211
"db:deploy": "prisma migrate deploy --schema prisma/schema.prisma",
1312
"db:reset": "prisma migrate reset --force --skip-generate --skip-seed --schema prisma/schema.prisma && npm run init",
@@ -38,8 +37,6 @@
3837
"@hookform/resolvers": "^5.2.2",
3938
"@prisma/client": "^6.19.0",
4039
"@radix-ui/react-select": "^2.2.6",
41-
"@simplewebauthn/browser": "^9.0.1",
42-
"@simplewebauthn/server": "^9.0.3",
4340
"@t3-oss/env-nextjs": "^0.13.0",
4441
"@tanstack/react-query": "^5.90.11",
4542
"@trpc/client": "^11.7.2",

0 commit comments

Comments
 (0)