@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.
- package/GAP_REGISTER.md +117 -0
- package/README.md +38 -0
- package/adapters/AGENTS.md +241 -0
- package/adapters/CLAUDE.md +146 -0
- package/adapters/replit.md +224 -0
- package/canon/anti-patterns.md +2133 -0
- package/canon/concepts.md +816 -0
- package/canon/custom-contracts.md +533 -0
- package/canon/delegation.md +195 -0
- package/canon/feature-mapping.md +637 -0
- package/canon/framework-matrix.md +1125 -0
- package/canon/invariants.md +851 -0
- package/canon/redirect-handler.md +254 -0
- package/canon/tidecloak-bootstrap.md +287 -0
- package/canon/tidecloak-endpoints.md +294 -0
- package/canon/troubleshooting.md +1494 -0
- package/canon/version-policy.md +89 -0
- package/mcp-server/dist/index.d.ts +2 -0
- package/mcp-server/dist/index.js +605 -0
- package/package.json +45 -0
- package/playbooks/add-auth-nextjs-existing.md +799 -0
- package/playbooks/add-auth-nextjs-fresh.md +654 -0
- package/playbooks/add-rbac-nextjs.md +190 -0
- package/playbooks/bootstrap-realm-from-template.md +170 -0
- package/playbooks/configure-e2ee-roles-and-policies.md +196 -0
- package/playbooks/deploy-tidecloak-docker.md +792 -0
- package/playbooks/diagnose-broken-login.md +234 -0
- package/playbooks/diagnose-missing-roles-or-claims.md +253 -0
- package/playbooks/initialize-admin-and-link-account.md +235 -0
- package/playbooks/migrate-from-existing-auth.md +198 -0
- package/playbooks/protect-api-nextjs.md +451 -0
- package/playbooks/protect-routes-nextjs.md +544 -0
- package/playbooks/setup-forseti-e2ee.md +756 -0
- package/playbooks/setup-iga-admin-panel.md +344 -0
- package/playbooks/setup-server-delegation.md +142 -0
- package/playbooks/start-tidecloak-dev.md +130 -0
- package/playbooks/verify-jwt-server-side.md +439 -0
- package/prompts/add-admin-approval-flow.md +50 -0
- package/prompts/build-private-customer-portal.md +85 -0
- package/prompts/migrate-generic-auth-to-tide.md +67 -0
- package/prompts/secure-existing-app.md +80 -0
- package/reference-apps/INDEX.md +87 -0
- package/reference-apps/encrypted-communication/anti-patterns.md +123 -0
- package/reference-apps/encrypted-communication/bootstrap-sequence.md +152 -0
- package/reference-apps/encrypted-communication/manifest.yaml +100 -0
- package/reference-apps/encrypted-communication/role-policy-matrix.md +80 -0
- package/reference-apps/encrypted-communication/scenario.md +134 -0
- package/reference-apps/git-pr-signing-service/anti-patterns.md +61 -0
- package/reference-apps/git-pr-signing-service/bootstrap-sequence.md +157 -0
- package/reference-apps/git-pr-signing-service/manifest.yaml +80 -0
- package/reference-apps/git-pr-signing-service/role-policy-matrix.md +99 -0
- package/reference-apps/git-pr-signing-service/scenario.md +169 -0
- package/reference-apps/iga-admin-governance/anti-patterns.md +133 -0
- package/reference-apps/iga-admin-governance/bootstrap-sequence.md +153 -0
- package/reference-apps/iga-admin-governance/manifest.yaml +87 -0
- package/reference-apps/iga-admin-governance/role-policy-matrix.md +67 -0
- package/reference-apps/iga-admin-governance/scenario.md +126 -0
- package/reference-apps/organisation-password-manager/anti-patterns.md +71 -0
- package/reference-apps/organisation-password-manager/bootstrap-sequence.md +127 -0
- package/reference-apps/organisation-password-manager/manifest.yaml +86 -0
- package/reference-apps/organisation-password-manager/role-policy-matrix.md +59 -0
- package/reference-apps/organisation-password-manager/scenario.md +107 -0
- package/reference-apps/policy-governed-signing/anti-patterns.md +67 -0
- package/reference-apps/policy-governed-signing/bootstrap-sequence.md +128 -0
- package/reference-apps/policy-governed-signing/manifest.yaml +78 -0
- package/reference-apps/policy-governed-signing/role-policy-matrix.md +62 -0
- package/reference-apps/policy-governed-signing/scenario.md +113 -0
- package/skills/tide-diagnostics/SKILL.md +99 -0
- package/skills/tide-integration/SKILL.md +136 -0
- package/skills/tide-learning-capture/SKILL.md +174 -0
- package/skills/tide-rbac-and-e2ee/SKILL.md +214 -0
- package/skills/tide-reviewer/SKILL.md +133 -0
- package/skills/tide-route-and-api-protection/SKILL.md +201 -0
- package/skills/tide-scenario-resolver/SKILL.md +81 -0
- package/skills/tide-setup/SKILL.md +218 -0
- 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
|