@tideorg/mcp 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/GAP_REGISTER.md +117 -0
  2. package/README.md +38 -0
  3. package/adapters/AGENTS.md +241 -0
  4. package/adapters/CLAUDE.md +146 -0
  5. package/adapters/replit.md +224 -0
  6. package/canon/anti-patterns.md +2133 -0
  7. package/canon/concepts.md +816 -0
  8. package/canon/custom-contracts.md +533 -0
  9. package/canon/delegation.md +195 -0
  10. package/canon/feature-mapping.md +637 -0
  11. package/canon/framework-matrix.md +1125 -0
  12. package/canon/invariants.md +851 -0
  13. package/canon/redirect-handler.md +254 -0
  14. package/canon/tidecloak-bootstrap.md +287 -0
  15. package/canon/tidecloak-endpoints.md +294 -0
  16. package/canon/troubleshooting.md +1494 -0
  17. package/canon/version-policy.md +89 -0
  18. package/mcp-server/dist/index.d.ts +2 -0
  19. package/mcp-server/dist/index.js +605 -0
  20. package/package.json +45 -0
  21. package/playbooks/add-auth-nextjs-existing.md +799 -0
  22. package/playbooks/add-auth-nextjs-fresh.md +654 -0
  23. package/playbooks/add-rbac-nextjs.md +190 -0
  24. package/playbooks/bootstrap-realm-from-template.md +170 -0
  25. package/playbooks/configure-e2ee-roles-and-policies.md +196 -0
  26. package/playbooks/deploy-tidecloak-docker.md +792 -0
  27. package/playbooks/diagnose-broken-login.md +234 -0
  28. package/playbooks/diagnose-missing-roles-or-claims.md +253 -0
  29. package/playbooks/initialize-admin-and-link-account.md +235 -0
  30. package/playbooks/migrate-from-existing-auth.md +198 -0
  31. package/playbooks/protect-api-nextjs.md +451 -0
  32. package/playbooks/protect-routes-nextjs.md +544 -0
  33. package/playbooks/setup-forseti-e2ee.md +756 -0
  34. package/playbooks/setup-iga-admin-panel.md +344 -0
  35. package/playbooks/setup-server-delegation.md +142 -0
  36. package/playbooks/start-tidecloak-dev.md +130 -0
  37. package/playbooks/verify-jwt-server-side.md +439 -0
  38. package/prompts/add-admin-approval-flow.md +50 -0
  39. package/prompts/build-private-customer-portal.md +85 -0
  40. package/prompts/migrate-generic-auth-to-tide.md +67 -0
  41. package/prompts/secure-existing-app.md +80 -0
  42. package/reference-apps/INDEX.md +87 -0
  43. package/reference-apps/encrypted-communication/anti-patterns.md +123 -0
  44. package/reference-apps/encrypted-communication/bootstrap-sequence.md +152 -0
  45. package/reference-apps/encrypted-communication/manifest.yaml +100 -0
  46. package/reference-apps/encrypted-communication/role-policy-matrix.md +80 -0
  47. package/reference-apps/encrypted-communication/scenario.md +134 -0
  48. package/reference-apps/git-pr-signing-service/anti-patterns.md +61 -0
  49. package/reference-apps/git-pr-signing-service/bootstrap-sequence.md +157 -0
  50. package/reference-apps/git-pr-signing-service/manifest.yaml +80 -0
  51. package/reference-apps/git-pr-signing-service/role-policy-matrix.md +99 -0
  52. package/reference-apps/git-pr-signing-service/scenario.md +169 -0
  53. package/reference-apps/iga-admin-governance/anti-patterns.md +133 -0
  54. package/reference-apps/iga-admin-governance/bootstrap-sequence.md +153 -0
  55. package/reference-apps/iga-admin-governance/manifest.yaml +87 -0
  56. package/reference-apps/iga-admin-governance/role-policy-matrix.md +67 -0
  57. package/reference-apps/iga-admin-governance/scenario.md +126 -0
  58. package/reference-apps/organisation-password-manager/anti-patterns.md +71 -0
  59. package/reference-apps/organisation-password-manager/bootstrap-sequence.md +127 -0
  60. package/reference-apps/organisation-password-manager/manifest.yaml +86 -0
  61. package/reference-apps/organisation-password-manager/role-policy-matrix.md +59 -0
  62. package/reference-apps/organisation-password-manager/scenario.md +107 -0
  63. package/reference-apps/policy-governed-signing/anti-patterns.md +67 -0
  64. package/reference-apps/policy-governed-signing/bootstrap-sequence.md +128 -0
  65. package/reference-apps/policy-governed-signing/manifest.yaml +78 -0
  66. package/reference-apps/policy-governed-signing/role-policy-matrix.md +62 -0
  67. package/reference-apps/policy-governed-signing/scenario.md +113 -0
  68. package/skills/tide-diagnostics/SKILL.md +99 -0
  69. package/skills/tide-integration/SKILL.md +136 -0
  70. package/skills/tide-learning-capture/SKILL.md +174 -0
  71. package/skills/tide-rbac-and-e2ee/SKILL.md +214 -0
  72. package/skills/tide-reviewer/SKILL.md +133 -0
  73. package/skills/tide-route-and-api-protection/SKILL.md +201 -0
  74. package/skills/tide-scenario-resolver/SKILL.md +81 -0
  75. package/skills/tide-setup/SKILL.md +218 -0
  76. package/skills/tide-solutions-architect/SKILL.md +130 -0
@@ -0,0 +1,799 @@
1
+ # Add Tide Auth to Existing Next.js Project
2
+
3
+ Manual setup for integrating Tide authentication into an existing Next.js application, potentially with existing auth.
4
+
5
+ ---
6
+
7
+ ## When to Use
8
+
9
+ - Have existing Next.js app (App Router or Pages Router)
10
+ - Want to migrate to Tide from another auth provider
11
+ - Want to add Tide alongside existing auth (migration period)
12
+ - Have existing routes, components, and state management
13
+ - Have an existing app with no auth yet (skip Steps 1-2; the rest applies as-is)
14
+
15
+ **Do not use** if starting fresh. See [add-auth-nextjs-fresh.md](add-auth-nextjs-fresh.md) instead.
16
+
17
+ ---
18
+
19
+ ## Prerequisites
20
+
21
+ ### Existing App Assessment
22
+
23
+ Before proceeding, understand your existing setup:
24
+
25
+ ```bash
26
+ # Check router type
27
+ ls -la app/ 2>/dev/null && echo "App Router" || echo "Pages Router"
28
+
29
+ # Check for existing auth
30
+ grep -r "auth\|login\|session" pages/ app/ components/ --include="*.tsx" --include="*.ts" | head -20
31
+ # Note any existing auth providers, middleware, or session management
32
+
33
+ # Check for existing request interception (proxy.ts for Next.js 16+, middleware.ts for 15 and earlier)
34
+ ls -la proxy.ts middleware.ts 2>/dev/null
35
+
36
+ # Check dependencies
37
+ cat package.json | grep -E "(auth|session|jwt)"
38
+ # Note existing auth packages
39
+ ```
40
+
41
+ ### Running Services
42
+
43
+ - TideCloak instance accessible
44
+ - TideCloak realm created and configured
45
+ - TideCloak client created
46
+ - IGA enabled on realm
47
+
48
+ ### Required Information
49
+
50
+ - TideCloak URL
51
+ - Realm name
52
+ - Client ID
53
+ - Adapter JSON exported
54
+
55
+ ---
56
+
57
+ ## Migration Strategy Decision
58
+
59
+ Choose one:
60
+
61
+ ### Option A: Clean Migration (Recommended)
62
+
63
+ Remove existing auth entirely, replace with Tide.
64
+
65
+ **Pros**: Simpler, no conflicts, full Tide integration
66
+ **Cons**: Requires re-authentication for all users
67
+ **When**: Existing auth is simple or can be deprecated
68
+
69
+ ### Option B: Parallel Auth (Temporary)
70
+
71
+ Run both auth systems during migration.
72
+
73
+ **Pros**: Gradual migration, test with subset of users
74
+ **Cons**: Complex, two auth flows, potential conflicts
75
+ **When**: Large user base, need phased rollout
76
+
77
+ **This playbook focuses on Option A (Clean Migration).**
78
+
79
+ ---
80
+
81
+ ## Files to Inspect First
82
+
83
+ ```bash
84
+ # Existing auth patterns
85
+ grep -r "useAuth\|useSession\|getServerSideProps.*session" app/ pages/ --include="*.tsx" --include="*.ts"
86
+
87
+ # Existing request interception
88
+ cat proxy.ts 2>/dev/null || cat middleware.ts 2>/dev/null
89
+
90
+ # Existing _app or layout
91
+ cat pages/_app.tsx 2>/dev/null
92
+ cat app/layout.tsx 2>/dev/null
93
+
94
+ # Existing API routes with auth
95
+ find pages/api/ app/api/ -name "*.ts" -o -name "*.tsx" 2>/dev/null | xargs grep -l "auth\|session\|jwt"
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Files to Edit
101
+
102
+ 1. Remove/replace existing auth provider
103
+ 2. Install Tide SDK
104
+ 3. Add Tide provider
105
+ 4. Update auth checks in components
106
+ 5. Update API route protection
107
+ 6. Add silent SSO file (if missing)
108
+ 7. Configure CSP
109
+
110
+ ---
111
+
112
+ ## Exact Step Sequence
113
+
114
+ ### Step 1: Backup Current Auth Setup
115
+
116
+ ```bash
117
+ # Create backup branch
118
+ git checkout -b backup-before-tide
119
+ git add .
120
+ git commit -m "Backup before Tide migration"
121
+ git checkout main # or your working branch
122
+ git checkout -b add-tide-auth
123
+ ```
124
+
125
+ **Document existing auth**:
126
+ ```bash
127
+ # List all files using existing auth
128
+ grep -r "useAuth\|useSession\|signIn\|signOut" . --include="*.tsx" --include="*.ts" > auth-migration-checklist.txt
129
+
130
+ # Review this file to plan replacements
131
+ ```
132
+
133
+ ---
134
+
135
+ ### Step 2: Remove Existing Auth Dependencies
136
+
137
+ ```bash
138
+ # Example: Remove NextAuth (adjust for your auth provider)
139
+ npm uninstall next-auth
140
+
141
+ # Or Auth0
142
+ npm uninstall @auth0/nextjs-auth0
143
+
144
+ # Or Clerk
145
+ npm uninstall @clerk/nextjs
146
+
147
+ # Verify removal
148
+ cat package.json | grep -E "(auth|session)"
149
+ ```
150
+
151
+ ---
152
+
153
+ ### Step 3: Install Tide SDK
154
+
155
+ ```bash
156
+ npm install @tidecloak/nextjs
157
+ ```
158
+
159
+ ---
160
+
161
+ ### Step 4: Export and Store Adapter JSON
162
+
163
+ Same as fresh setup. See [add-auth-nextjs-fresh.md Step 2](add-auth-nextjs-fresh.md#step-2-export-adapter-json-from-tidecloak).
164
+
165
+ ```bash
166
+ mkdir -p data
167
+ # Download adapter JSON to data/tidecloak.json
168
+ # Verify Tide extensions present
169
+ ```
170
+
171
+ ---
172
+
173
+ ### Step 5: Update Environment Variables
174
+
175
+ Edit `.env.local`:
176
+ ```bash
177
+ # Remove old auth vars (e.g., NEXTAUTH_SECRET, AUTH0_CLIENT_SECRET)
178
+
179
+ # Tide connection details are read from data/tidecloak.json (adapter config),
180
+ # not from environment variables. Remove any old auth env vars.
181
+ ```
182
+
183
+ ---
184
+
185
+ ### Step 6: Replace Auth Provider
186
+
187
+ #### App Router
188
+
189
+ **Before** (example with NextAuth):
190
+ ```typescript
191
+ // app/layout.tsx
192
+ import { SessionProvider } from 'next-auth/react';
193
+
194
+ export default function RootLayout({ children }) {
195
+ return (
196
+ <html>
197
+ <body>
198
+ <SessionProvider>{children}</SessionProvider>
199
+ </body>
200
+ </html>
201
+ );
202
+ }
203
+ ```
204
+
205
+ **After** (Tide):
206
+ ```typescript
207
+ // app/layout.tsx
208
+ import { Providers } from './providers';
209
+
210
+ export default function RootLayout({ children }) {
211
+ return (
212
+ <html>
213
+ <body>
214
+ <Providers>{children}</Providers>
215
+ </body>
216
+ </html>
217
+ );
218
+ }
219
+ ```
220
+
221
+ Create `app/providers.tsx`:
222
+ ```typescript
223
+ // app/providers.tsx
224
+ 'use client';
225
+
226
+ import { TideCloakProvider } from '@tidecloak/nextjs';
227
+ import tcConfig from '../data/tidecloak.json';
228
+
229
+ export function Providers({ children }: { children: React.ReactNode }) {
230
+ return (
231
+ <TideCloakProvider
232
+ config={{ ...tcConfig, useDPoP: { mode: 'strict', alg: 'ES256' } }}
233
+ >
234
+ {children}
235
+ </TideCloakProvider>
236
+ );
237
+ }
238
+ ```
239
+
240
+ **DPoP** requires both server-side config (client attribute `"dpop.bound.access.tokens": "true"`) AND client-side config (`useDPoP` prop). Without `useDPoP`, `secureFetch` does not attach DPoP proofs and API calls fail with 401. See [add-auth-nextjs-fresh.md Step 4a](add-auth-nextjs-fresh.md#step-4a-provider-setup-app-router) for details.
241
+
242
+ #### Pages Router
243
+
244
+ **Before**:
245
+ ```typescript
246
+ // pages/_app.tsx
247
+ import { SessionProvider } from 'next-auth/react';
248
+
249
+ export default function App({ Component, pageProps }) {
250
+ return (
251
+ <SessionProvider>
252
+ <Component {...pageProps} />
253
+ </SessionProvider>
254
+ );
255
+ }
256
+ ```
257
+
258
+ **After**:
259
+ ```typescript
260
+ // pages/_app.tsx
261
+ import { TideCloakProvider } from '@tidecloak/nextjs';
262
+ import tcConfig from '../data/tidecloak.json';
263
+
264
+ export default function App({ Component, pageProps }) {
265
+ return (
266
+ <TideCloakProvider
267
+ config={{ ...tcConfig, useDPoP: { mode: 'strict', alg: 'ES256' } }}
268
+ >
269
+ <Component {...pageProps} />
270
+ </TideCloakProvider>
271
+ );
272
+ }
273
+ ```
274
+
275
+ ---
276
+
277
+ ### Step 7: Update Component Auth Checks
278
+
279
+ Replace existing auth hooks with Tide hooks.
280
+
281
+ **Before** (NextAuth):
282
+ ```typescript
283
+ import { useSession, signIn, signOut } from 'next-auth/react';
284
+
285
+ export function ProfileButton() {
286
+ const { data: session } = useSession();
287
+
288
+ if (!session) {
289
+ return <button onClick={() => signIn()}>Login</button>;
290
+ }
291
+
292
+ return <button onClick={() => signOut()}>Logout</button>;
293
+ }
294
+ ```
295
+
296
+ **After** (Tide):
297
+ ```typescript
298
+ import { useTideCloak } from '@tidecloak/nextjs';
299
+
300
+ export function ProfileButton() {
301
+ const { authenticated, user, login, logout } = useTideCloak();
302
+
303
+ if (!authenticated) {
304
+ return <button onClick={login}>Login</button>;
305
+ }
306
+
307
+ return <button onClick={logout}>Logout</button>;
308
+ }
309
+ ```
310
+
311
+ **Batch find-and-replace**:
312
+ ```bash
313
+ # Find all uses of old auth hook
314
+ grep -r "useSession\|useAuth" components/ app/ pages/ --include="*.tsx" --include="*.ts" | cut -d: -f1 | sort -u
315
+
316
+ # Update each file manually or with sed (review carefully)
317
+ ```
318
+
319
+ ---
320
+
321
+ ### Step 8: Update API Route Protection
322
+
323
+ **Before** (NextAuth API route):
324
+ ```typescript
325
+ // pages/api/users.ts or app/api/users/route.ts
326
+ import { getServerSession } from 'next-auth';
327
+
328
+ export async function GET(req) {
329
+ const session = await getServerSession();
330
+ if (!session) {
331
+ return new Response('Unauthorized', { status: 401 });
332
+ }
333
+ return Response.json({ users: [...] });
334
+ }
335
+ ```
336
+
337
+ **After** (Tide - manual JWT verification):
338
+
339
+ You must implement server-side JWT verification. Tide SDK does not provide automatic API protection.
340
+
341
+ See [verify-jwt-server-side.md](verify-jwt-server-side.md) for full implementation.
342
+
343
+ **Quick pattern** (based on keylessh):
344
+ ```typescript
345
+ // app/api/users/route.ts
346
+ import { NextRequest } from 'next/server';
347
+ import { verifyTideJWT } from '@/lib/auth/tideJWT'; // See verify-jwt-server-side.md
348
+
349
+ export async function GET(req: NextRequest) {
350
+ const authHeader = req.headers.get('authorization');
351
+ if (!authHeader) {
352
+ return Response.json({ error: 'Unauthorized' }, { status: 401 });
353
+ }
354
+
355
+ try {
356
+ const jwt = await verifyTideJWT(authHeader.replace('Bearer ', ''));
357
+ return Response.json({ users: [...] });
358
+ } catch (err) {
359
+ return Response.json({ error: 'Invalid token' }, { status: 401 });
360
+ }
361
+ }
362
+ ```
363
+
364
+ **Critical**: You must create `lib/auth/tideJWT.ts` with local JWKS verification. See [verify-jwt-server-side.md](verify-jwt-server-side.md) for exact implementation.
365
+
366
+ ---
367
+
368
+ ### Step 9: Update proxy.ts / middleware.ts (If Exists)
369
+
370
+ Check for existing request interception:
371
+ ```bash
372
+ ls -la proxy.ts middleware.ts 2>/dev/null
373
+ ```
374
+
375
+ Check the installed Next.js version to determine the correct filename:
376
+ ```bash
377
+ NEXT_MAJOR=$(node -e "try{console.log(require('next/package.json').version.split('.')[0])}catch{console.log('unknown')}" 2>/dev/null)
378
+ # 16+ → proxy.ts | 15 or earlier → middleware.ts
379
+ ```
380
+
381
+ Next.js 16+ uses `proxy.ts`. Next.js 15 and earlier use `middleware.ts`. If migrating from `middleware.ts` to `proxy.ts`, rename the file.
382
+
383
+ **Before** (NextAuth middleware):
384
+ ```typescript
385
+ // middleware.ts (Next.js ≤15) or proxy.ts (Next.js 16+)
386
+ export { default } from 'next-auth/middleware';
387
+
388
+ export const config = {
389
+ matcher: ['/dashboard/:path*', '/admin/:path*']
390
+ };
391
+ ```
392
+
393
+ **After** (Tide - client-side route guard):
394
+
395
+ **Remove proxy.ts / middleware.ts** if it only checks auth. Tide provider handles client-side auth state.
396
+
397
+ For API protection, use server-side JWT verification (Step 8), not proxy/middleware.
398
+
399
+ **Warning**: `proxy.ts` (and legacy `middleware.ts`) route protection is UI gating only, NOT real authorization. See [canon/feature-mapping.md](../canon/feature-mapping.md#protected-routes-vs-protected-apis).
400
+
401
+ If you want client-side route guards, implement in component:
402
+ ```typescript
403
+ // app/dashboard/layout.tsx
404
+ 'use client';
405
+
406
+ import { useTideCloak } from '@tidecloak/nextjs';
407
+ import { useEffect } from 'react';
408
+
409
+ export default function DashboardLayout({ children }) {
410
+ const { authenticated, isInitializing, login } = useTideCloak();
411
+
412
+ useEffect(() => {
413
+ if (!isInitializing && !authenticated) {
414
+ login();
415
+ }
416
+ }, [isInitializing, authenticated, login]);
417
+
418
+ if (isInitializing || !authenticated) {
419
+ return <div>Checking authentication...</div>;
420
+ }
421
+
422
+ return <>{children}</>;
423
+ }
424
+ ```
425
+
426
+ **Why `isInitializing`**: Calling `login()` before the SDK finishes initializing throws `"TideCloak client not initialized"`. Always gate on `isInitializing`. See [canon/anti-patterns.md AP-28](../canon/anti-patterns.md#ap-28-calling-login-before-sdk-initialization).
427
+
428
+ ---
429
+
430
+ ### Step 10: Add Post-Auth Redirect Handler
431
+
432
+ Check if exists:
433
+ ```bash
434
+ # App Router
435
+ test -f app/auth/redirect/page.tsx || test -f src/app/auth/redirect/page.tsx
436
+
437
+ # Pages Router
438
+ test -f pages/auth/redirect.tsx || test -f src/pages/auth/redirect.tsx
439
+ ```
440
+
441
+ If missing, create the handler. See [add-auth-nextjs-fresh.md Step 6](add-auth-nextjs-fresh.md#step-6-create-post-auth-redirect-handler) for exact file contents and [canon/redirect-handler.md](../canon/redirect-handler.md) for framework-specific details.
442
+
443
+ Ensure the redirect URI in `data/tidecloak.json` matches the handler path (e.g., `http://localhost:3000/auth/redirect`). This is configured when exporting the adapter JSON from TideCloak Admin Console.
444
+
445
+ ---
446
+
447
+ ### Step 11: Add Silent SSO File
448
+
449
+ Check if exists:
450
+ ```bash
451
+ ls -la public/silent-check-sso.html
452
+ ```
453
+
454
+ If missing, create:
455
+ ```bash
456
+ cat > public/silent-check-sso.html << 'EOF'
457
+ <html>
458
+ <body>
459
+ <script>
460
+ parent.postMessage(location.href, location.origin);
461
+ </script>
462
+ </body>
463
+ </html>
464
+ EOF
465
+ ```
466
+
467
+ ---
468
+
469
+ ### Step 12: Configure CSP
470
+
471
+ Check existing CSP:
472
+ ```bash
473
+ grep -r "Content-Security-Policy\|frame-src" next.config.js next.config.ts proxy.ts middleware.ts 2>/dev/null
474
+ ```
475
+
476
+ Add Tide domains to `frame-src`:
477
+
478
+ **If CSP exists**, update `frame-src` to permit any ORK host:
479
+ ```javascript
480
+ // next.config.js
481
+ const nextConfig = {
482
+ async headers() {
483
+ return [{
484
+ source: '/:path*',
485
+ headers: [{
486
+ key: 'Content-Security-Policy',
487
+ value: [
488
+ // Existing CSP directives
489
+ "frame-src 'self' *", // Allow any ORK (users can re-home sessions)
490
+ // ... other directives
491
+ ].join(' ')
492
+ }]
493
+ }];
494
+ }
495
+ };
496
+ ```
497
+
498
+ **Why `*`**: The SWE iframe must permit any Tide ORK host because users can re-home their sessions to any ORK they trust. This is a core Tide security design feature.
499
+
500
+ **For production**, you may restrict to known domains, but this limits user choice:
501
+ ```javascript
502
+ "frame-src 'self' https://*.tideprotocol.com https://*.dauth.me"
503
+ ```
504
+
505
+ **If CSP missing**, see [add-auth-nextjs-fresh.md Step 6](add-auth-nextjs-fresh.md#step-6-configure-csp-for-swe-iframe) for complete setup.
506
+
507
+ ---
508
+
509
+ ### Step 13: Update TideCloak Client Configuration
510
+
511
+ In TideCloak Admin Console:
512
+
513
+ 1. Clients → {your-client} → Settings
514
+ 2. **Valid Redirect URIs**: Add all app URLs
515
+ ```
516
+ http://localhost:3000/*
517
+ https://app.example.com/*
518
+ ```
519
+ 3. **Valid Post Logout Redirect URIs**: Same as above
520
+ 4. **Web Origins**: Add for CORS
521
+ ```
522
+ http://localhost:3000
523
+ https://app.example.com
524
+ ```
525
+ 5. Save
526
+
527
+ ---
528
+
529
+ ### Step 14: Test Migration
530
+
531
+ ```bash
532
+ # Clear browser state (old auth cookies/tokens)
533
+ # DevTools → Application → Storage → Clear site data
534
+
535
+ # Start dev server
536
+ npm run dev
537
+
538
+ # Test flows:
539
+ # 1. Visit protected route (should redirect to Tide login)
540
+ # 2. Login with Tide credentials
541
+ # 3. Verify redirect back to app
542
+ # 4. Verify protected content accessible
543
+ # 5. Logout
544
+ # 6. Verify redirect to login
545
+ ```
546
+
547
+ ---
548
+
549
+ ## Verification Checklist
550
+
551
+ ### Login Flow
552
+
553
+ - [ ] Unauthenticated user redirected to Tide login
554
+ - [ ] Credentials accepted
555
+ - [ ] Redirect back to original URL
556
+ - [ ] Auth state preserved across page refreshes
557
+
558
+ ### Component Rendering
559
+
560
+ - [ ] All components using auth hooks render correctly
561
+ - [ ] User info displays (name, email, etc.)
562
+ - [ ] Role-based UI elements show/hide appropriately (UI gating)
563
+
564
+ ### API Protection
565
+
566
+ - [ ] Protected API routes reject unauthenticated requests (401)
567
+ - [ ] Protected API routes accept valid Tide JWTs (200)
568
+ - [ ] Role-based API routes enforce role checks (403 if wrong role)
569
+
570
+ ### Session Management
571
+
572
+ - [ ] Silent token refresh works (no forced re-login after 10 min)
573
+ - [ ] Logout clears session completely
574
+ - [ ] Multiple tabs stay synchronized (all logout together)
575
+
576
+ ### No Conflicts
577
+
578
+ - [ ] No errors from old auth packages
579
+ - [ ] No duplicate providers in React tree
580
+ - [ ] No conflicting middleware
581
+ - [ ] No old auth API routes responding
582
+
583
+ ---
584
+
585
+ ## Common Failures
586
+
587
+ ### Old Auth Tokens Cached
588
+
589
+ **Symptom**: App shows logged in but APIs return 401. Or infinite redirect loop.
590
+
591
+ **Cause**: Browser still has old auth cookies/tokens.
592
+
593
+ **Fix**:
594
+ ```bash
595
+ # Browser: DevTools → Application → Storage → Clear site data
596
+ # Or incognito window for clean test
597
+ ```
598
+
599
+ ---
600
+
601
+ ### Missing API JWT Verification
602
+
603
+ **Symptom**: APIs still check old auth. Or no auth check at all.
604
+
605
+ **Cause**: Forgot to update API routes from old auth to Tide JWT verification.
606
+
607
+ **Fix**: Review all API routes. Replace old auth checks with Tide JWT verification. See [verify-jwt-server-side.md](verify-jwt-server-side.md).
608
+
609
+ ---
610
+
611
+ ### Component Import Errors
612
+
613
+ **Symptom**: `Cannot find module 'next-auth/react'` after uninstall.
614
+
615
+ **Cause**: Components still import old auth package.
616
+
617
+ **Fix**:
618
+ ```bash
619
+ # Find all old imports
620
+ grep -r "from 'next-auth\|from \"next-auth" . --include="*.tsx" --include="*.ts"
621
+
622
+ # Update to Tide imports
623
+ # Old: import { useSession } from 'next-auth/react';
624
+ # New: import { useTideCloak } from '@tidecloak/nextjs';
625
+ ```
626
+
627
+ ---
628
+
629
+ ### Proxy / Middleware Conflicts
630
+
631
+ **Symptom**: Routes protected by proxy/middleware but Tide auth not checked.
632
+
633
+ **Cause**: Old auth proxy or middleware still active.
634
+
635
+ **Fix**: Remove or update `proxy.ts` (or legacy `middleware.ts`). Tide has no built-in Next.js request interception. Implement client-side route guards (Step 9) or server-side JWT verification.
636
+
637
+ ---
638
+
639
+ ### User Data Mismatch
640
+
641
+ **Symptom**: App expects `session.user.id` but Tide provides `user.sub`.
642
+
643
+ **Cause**: Different auth providers use different claim names.
644
+
645
+ **Fix**: Update components to use Tide SDK accessors:
646
+ ```typescript
647
+ const { getValueFromToken, getValueFromIdToken, hasRealmRole } = useTideCloak();
648
+
649
+ // Old: session.user.id
650
+ // New: getValueFromToken("sub")
651
+
652
+ // Old: session.user.email
653
+ // New: getValueFromIdToken("email")
654
+
655
+ // Old: session.user.name
656
+ // New: getValueFromIdToken("preferred_username")
657
+
658
+ // Old: session.user.role check
659
+ // New: hasRealmRole("admin")
660
+ ```
661
+
662
+ Or create adapter:
663
+ ```typescript
664
+ function adaptTideUser(tc: ReturnType<typeof useTideCloak>) {
665
+ return {
666
+ id: tc.getValueFromToken("sub"),
667
+ email: tc.getValueFromIdToken("email"),
668
+ name: tc.getValueFromIdToken("preferred_username"),
669
+ };
670
+ }
671
+ ```
672
+
673
+ ---
674
+
675
+ ## Repair Path
676
+
677
+ If migration blocked:
678
+
679
+ 1. **Rollback option**:
680
+ ```bash
681
+ git checkout backup-before-tide
682
+ npm install
683
+ # Old auth restored
684
+ ```
685
+
686
+ 2. **Isolate issue**:
687
+ - Test Tide auth in minimal page first
688
+ - Gradually migrate pages/components
689
+ - Keep old auth working in parallel temporarily
690
+
691
+ 3. **Verify each layer**:
692
+ - Client-side auth state (DevTools → Components → TideCloakContext)
693
+ - API protection (curl with JWT, verify 200 vs 401)
694
+ - Silent refresh (wait 10 min, verify no re-login)
695
+
696
+ 4. **Check migration checklist**:
697
+ ```bash
698
+ cat auth-migration-checklist.txt
699
+ # Did you update every file listed?
700
+ ```
701
+
702
+ ---
703
+
704
+ ## Do Not Do This
705
+
706
+ ### ❌ Do Not Run Two Auth Providers Simultaneously (Long-Term)
707
+
708
+ ```typescript
709
+ // ❌ WRONG: Both providers active
710
+ <SessionProvider>
711
+ <TideCloakProvider config={tcConfig}>
712
+ {children}
713
+ </TideCloakProvider>
714
+ </SessionProvider>
715
+ ```
716
+
717
+ **Why**: Conflicts, confusion, security risks. One auth system should be authoritative. Parallel auth only acceptable during short migration period with clear boundaries.
718
+
719
+ ---
720
+
721
+ ### ❌ Do Not Keep Old Auth API Routes Active
722
+
723
+ ```typescript
724
+ // ❌ WRONG: Old NextAuth API still responding
725
+ // pages/api/auth/[...nextauth].ts still exists
726
+ ```
727
+
728
+ **Why**: Creates backdoor. If old auth has vulnerabilities or uses weaker security, attackers can exploit it. Remove completely.
729
+
730
+ ---
731
+
732
+ ### ❌ Do Not Mix Auth Checks in Same Component
733
+
734
+ ```typescript
735
+ // ❌ WRONG: Checking both old and new auth
736
+ const { data: oldSession } = useSession();
737
+ const { authenticated } = useTideCloak();
738
+
739
+ if (oldSession || authenticated) {
740
+ return <ProtectedContent />;
741
+ }
742
+ ```
743
+
744
+ **Why**: Ambiguous authority. Which auth is trusted? If one is compromised, both paths are vulnerable. Choose one.
745
+
746
+ ---
747
+
748
+ ### ❌ Do Not Skip Server-Side Migration
749
+
750
+ ```typescript
751
+ // ❌ WRONG: Updated client-side but APIs still use old auth
752
+ // UI uses Tide, APIs check NextAuth session
753
+ ```
754
+
755
+ **Why**: Broken. Client sends Tide JWT, server expects old session cookie. All API calls fail. Must migrate both client and server together.
756
+
757
+ ---
758
+
759
+ ## Known Uncertainties
760
+
761
+ Same as fresh setup. See [add-auth-nextjs-fresh.md Known Uncertainties](add-auth-nextjs-fresh.md#known-uncertainties).
762
+
763
+ Additional migration-specific:
764
+
765
+ ### User Migration
766
+
767
+ User accounts from old auth must be re-created in TideCloak realm or imported. Account migration procedures not covered in SDK docs. Contact Tide team for user migration guidance.
768
+
769
+ ### Session Transition
770
+
771
+ Existing logged-in users will be logged out during migration. No automatic session transfer. Plan maintenance window or communicate to users.
772
+
773
+ ---
774
+
775
+ ## Next Steps
776
+
777
+ After migration complete:
778
+
779
+ 1. [Protect routes](protect-routes-nextjs.md) - Standardize route protection
780
+ 2. [Protect APIs](protect-api-nextjs.md) - Verify all API protection migrated correctly
781
+ 3. [Add RBAC](add-rbac-nextjs.md) - Add role-based access control
782
+ 4. Clean up old auth remnants:
783
+ ```bash
784
+ # Remove backup branch after testing
785
+ git branch -D backup-before-tide
786
+
787
+ # Remove old auth config files
788
+ rm auth.config.ts # or whatever your old auth used
789
+ ```
790
+
791
+ ---
792
+
793
+ ## References
794
+
795
+ - [add-auth-nextjs-fresh.md](add-auth-nextjs-fresh.md) - Fresh setup steps
796
+ - [verify-jwt-server-side.md](verify-jwt-server-side.md) - API protection implementation
797
+ - [canon/concepts.md](../canon/concepts.md) - Tide core concepts
798
+ - [canon/anti-patterns.md](../canon/anti-patterns.md) - Migration pitfalls
799
+ - [canon/troubleshooting.md](../canon/troubleshooting.md) - Debug failed migration