@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,201 @@
|
|
|
1
|
+
# Role: Security Engineer
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Add client-side route guards (UI gating) and server-side API authorization (real security) to a Tide-enabled Next.js app. Ensure every protected API verifies JWTs with embedded JWKS and optionally verifies DPoP proofs.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## When to Trigger
|
|
12
|
+
|
|
13
|
+
- User asks to "protect routes", "protect pages", or "add auth guards"
|
|
14
|
+
- User asks to "protect API", "secure endpoints", or "add server-side auth"
|
|
15
|
+
- User asks to add JWT verification or DPoP verification
|
|
16
|
+
- User reports that API routes return data without authentication
|
|
17
|
+
|
|
18
|
+
### Scenario-disambiguation gate (I-17)
|
|
19
|
+
|
|
20
|
+
Before proceeding, confirm the task is route/API protection and not a different concern:
|
|
21
|
+
|
|
22
|
+
| Branch | How to resolve |
|
|
23
|
+
|--------|---------------|
|
|
24
|
+
| Protection vs setup | Is the app Tide-enabled? If not → `tide-setup` first. |
|
|
25
|
+
| Protection vs diagnosis | Is auth broken (401s, hangs), or does protection not exist yet? If broken → `diagnose-broken-login`. |
|
|
26
|
+
| Route protection vs encryption | Is the user asking about protecting routes, or about encrypting data? If encryption → `tide-rbac-and-e2ee` or `setup-forseti-e2ee`. |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## When NOT to Trigger
|
|
31
|
+
|
|
32
|
+
- App is not Tide-enabled (no SDK, no provider, no adapter JSON). Route to `tide-setup` skill first.
|
|
33
|
+
- User is asking about RBAC role hierarchies or private E2EE encryption (no sharing). Route to `tide-rbac-and-e2ee` skill.
|
|
34
|
+
- User is asking about shared/group encryption where multiple users decrypt the same data. Route to playbook `setup-forseti-e2ee` directly.
|
|
35
|
+
- User is asking about TideCloak server setup or realm configuration. Use playbook `deploy-tidecloak-docker`.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Required Repo Inspection
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# 1. Confirm Tide setup is complete
|
|
43
|
+
grep -E '@tidecloak/(nextjs|react|js)' package.json || echo "FAIL: no Tide SDK"
|
|
44
|
+
grep -r 'TideCloakProvider\|TideCloakContextProvider' app/layout.tsx app/providers.tsx pages/_app.tsx 2>/dev/null || echo "FAIL: no provider"
|
|
45
|
+
test -f data/tidecloak.json || echo "FAIL: no adapter JSON"
|
|
46
|
+
|
|
47
|
+
# 2. Check for existing route guards
|
|
48
|
+
grep -r 'useTideCloak\|AuthGuard\|authenticated' app/ pages/ components/ --include="*.tsx" --include="*.ts" 2>/dev/null | head -10
|
|
49
|
+
|
|
50
|
+
# 3. Check for existing API routes
|
|
51
|
+
find app/api pages/api -name "*.ts" -o -name "*.tsx" 2>/dev/null
|
|
52
|
+
|
|
53
|
+
# 4. Check for existing JWT verification
|
|
54
|
+
grep -r 'verifyTideJWT\|jwtVerify\|createLocalJWKSet' lib/auth/ --include="*.ts" 2>/dev/null
|
|
55
|
+
|
|
56
|
+
# 5. Check for auth middleware files
|
|
57
|
+
ls lib/auth/tideJWT.ts lib/auth/tidecloakConfig.ts lib/auth/protect.ts lib/auth/dpop.ts 2>/dev/null
|
|
58
|
+
|
|
59
|
+
# 6. Diagnose unprotected APIs
|
|
60
|
+
grep -rL 'verifyTideJWT\|withAuth\|withRole\|extractToken' app/api/ --include="*.ts" 2>/dev/null
|
|
61
|
+
# Any file listed here is an unprotected API route
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If check 1 fails on any item, stop. Run the `tide-setup` skill first.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Preconditions
|
|
69
|
+
|
|
70
|
+
- Tide setup complete (SDK installed, provider wired, adapter JSON present with `jwk` field)
|
|
71
|
+
- Login flow working (user can authenticate and see their name)
|
|
72
|
+
- At least one API route exists or will be created
|
|
73
|
+
- `jose` package installed (or will be installed in Step 1)
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Execution Workflow
|
|
78
|
+
|
|
79
|
+
This skill follows three playbooks in sequence. Each builds on the previous.
|
|
80
|
+
|
|
81
|
+
### Phase 1: Route Protection (UI Gating)
|
|
82
|
+
|
|
83
|
+
**Playbook**: `protect-routes-nextjs`
|
|
84
|
+
|
|
85
|
+
Adds client-side guards that redirect unauthenticated users. This is UX convenience only — it has zero security value for APIs.
|
|
86
|
+
|
|
87
|
+
**Key decision**: Choose the guard pattern that fits the app structure:
|
|
88
|
+
- Layout-based guards (App Router): protect entire sections via `app/{section}/layout.tsx`
|
|
89
|
+
- Page-level guards: protect individual pages
|
|
90
|
+
- Reusable `AuthGuard` component: wrap pages that need protection
|
|
91
|
+
|
|
92
|
+
**Critical rule**: Always check `isInitializing` before checking `authenticated` or calling `login()`. Calling `login()` before SDK init throws `"TideCloak client not initialized"`.
|
|
93
|
+
|
|
94
|
+
### Phase 2: API Protection (Server-Side JWT Verification)
|
|
95
|
+
|
|
96
|
+
**Playbook**: `protect-api-nextjs`
|
|
97
|
+
|
|
98
|
+
Creates `lib/auth/` files for JWT verification against embedded JWKS and reusable middleware. **This is where real authorization happens.** Every API route that handles sensitive data must use these. See the playbook for exact file contents.
|
|
99
|
+
|
|
100
|
+
### Phase 3: Complete JWT + DPoP Verification
|
|
101
|
+
|
|
102
|
+
**Playbook**: `verify-jwt-server-side`
|
|
103
|
+
|
|
104
|
+
**Replaces** the files created in Phase 2 with richer versions that add:
|
|
105
|
+
- DPoP proof verification (`lib/auth/dpop.ts`)
|
|
106
|
+
- `extractToken()` supporting both Bearer and DPoP schemes
|
|
107
|
+
- Client-role checking in `hasRole()`
|
|
108
|
+
- `iat` future-validation
|
|
109
|
+
|
|
110
|
+
**Important**: Phase 3 files replace Phase 2 files. Do not run both and keep duplicates. If the user only needs basic JWT verification without DPoP, Phase 2 alone is functional but degrades Tide's security guarantees.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Diagnosing Existing API Code
|
|
115
|
+
|
|
116
|
+
If the app already has API routes, audit them:
|
|
117
|
+
|
|
118
|
+
| Check | Command | Fail means |
|
|
119
|
+
|-------|---------|-----------|
|
|
120
|
+
| Reads from Authorization header? | `grep -r "authorization" app/api/ --include="*.ts"` | API trusts cookies or has no auth |
|
|
121
|
+
| Uses embedded JWKS? | `grep -r "createLocalJWKSet" lib/auth/` | May use remote endpoint (AP-01) |
|
|
122
|
+
| Validates issuer + audience? | `grep -r "issuer\|audience" lib/auth/` | JWT claims not verified |
|
|
123
|
+
| Enforces roles after verification? | `grep -r "hasRole\|withRole\|realm_access" app/api/` | Returns data without role check |
|
|
124
|
+
| Verifies DPoP if present? | `grep -r "verifyDPoP\|dpop" lib/auth/` | Token replay possible |
|
|
125
|
+
|
|
126
|
+
Any failure means the API route is not properly protected. Apply the playbook sequence above.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Safety Checks
|
|
131
|
+
|
|
132
|
+
- **Route proxy is not API auth.** Next.js `proxy.ts` (16+) or `middleware.ts` (≤15) runs at the edge and cannot access adapter JSON for JWT signature verification. Use it only for UI redirects. Check the installed Next.js version to determine the correct filename.
|
|
133
|
+
- **Use embedded JWKS only.** `createLocalJWKSet(config.jwk)` is the only supported path. `createRemoteJWKSet` is forbidden. If `jwk` is missing, fix the adapter export — do not add remote fallback. (I-04)
|
|
134
|
+
- **Do not preserve fake auth helpers.** If existing code has `isAuthenticated: () => true` or hardcoded role arrays, remove them and replace with real JWT verification.
|
|
135
|
+
- For the full safety rule set (UI gating, DPoP, forbidden shortcuts), see `adapters/AGENTS.md`.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Verification Checklist
|
|
140
|
+
|
|
141
|
+
### Route Protection (Phase 1)
|
|
142
|
+
- [ ] Unauthenticated user redirected to TideCloak login
|
|
143
|
+
- [ ] After login, user returned to original page
|
|
144
|
+
- [ ] Protected pages show loading state during init (no flash of content)
|
|
145
|
+
- [ ] Public pages remain accessible without login
|
|
146
|
+
|
|
147
|
+
### API Protection (Phase 2/3)
|
|
148
|
+
- [ ] `curl http://localhost:3000/api/protected` returns 401 (no token)
|
|
149
|
+
- [ ] `curl -H "Authorization: Bearer INVALID" ...` returns 401 (bad token)
|
|
150
|
+
- [ ] `curl -H "Authorization: Bearer VALID_TOKEN" ...` returns 200 (good token)
|
|
151
|
+
- [ ] Request with wrong role returns 403
|
|
152
|
+
- [ ] DPoP-protected request without proof returns 401 (if Phase 3 applied)
|
|
153
|
+
|
|
154
|
+
### Cross-Layer
|
|
155
|
+
- [ ] Bypassing route guard (direct API call from DevTools) still returns 401/403
|
|
156
|
+
- [ ] Disabling JavaScript does not expose protected API data
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Repair Path
|
|
161
|
+
|
|
162
|
+
### JWT verification always fails (401)
|
|
163
|
+
1. Check adapter JSON has `jwk` field: `node -e "console.log(!!require('./data/tidecloak.json').jwk)"`
|
|
164
|
+
2. Check issuer matches: compare `config['auth-server-url'] + '/realms/' + config.realm` with token's `iss` claim
|
|
165
|
+
3. Check audience matches: compare `config.resource` with token's `azp` claim
|
|
166
|
+
4. Decode token at jwt.io and inspect claims
|
|
167
|
+
5. See playbook `diagnose-broken-login` or `canon/troubleshooting.md` T-02
|
|
168
|
+
|
|
169
|
+
### Role check always fails (403)
|
|
170
|
+
See `tide-rbac-and-e2ee` skill Repair Path. Role debugging is that skill's responsibility.
|
|
171
|
+
|
|
172
|
+
### DPoP verification fails
|
|
173
|
+
1. Confirm client sends DPoP header (check Network tab)
|
|
174
|
+
2. Check server clock sync (120s freshness window on `iat`)
|
|
175
|
+
3. Confirm `cnf.jkt` in access token matches DPoP proof thumbprint
|
|
176
|
+
4. Check `jti` replay cache is not rejecting fresh proofs
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Handoff Trace
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
[TRACE]
|
|
184
|
+
Scenario: <scenario>
|
|
185
|
+
Role: Security Engineer
|
|
186
|
+
Reason: <routes unprotected | APIs unprotected | DPoP not verified>
|
|
187
|
+
Preconditions: SDK installed, provider wired, tidecloak.json loaded
|
|
188
|
+
Next: IAM / Policy Engineer | Reviewer | STOP
|
|
189
|
+
[/TRACE]
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Do Not Do This
|
|
195
|
+
|
|
196
|
+
- **Do not use Next.js `proxy.ts` (16+) or `middleware.ts` (≤15) as your API auth layer.** It runs at the edge and cannot access adapter JSON for JWT signature verification. Use it only for UI redirects.
|
|
197
|
+
- **Do not use `createRemoteJWKSet` at all.** Use `createLocalJWKSet(config.jwk)` only. Remote JWKS is forbidden, not even as a fallback. If `jwk` is missing from `tidecloak.json`, route to adapter re-export (setup/bootstrap), not remote key fetching.
|
|
198
|
+
- **Do not skip JWT verification because route guards exist.** Route guards are trivially bypassed.
|
|
199
|
+
- **Do not cache DPoP proofs.** Each request needs a fresh proof. Cached proofs fail `jti` replay and `htm`/`htu` checks.
|
|
200
|
+
- **Do not trust the `Authorization` header without verifying the JWT signature.** Extracting the token is not the same as verifying it.
|
|
201
|
+
- **Do not mix auth check with data fetching in the same component.** Check `authenticated` first, then fetch. Otherwise the API call fires before auth is ready.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Role: Scenario Resolver
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Determine what kind of problem this is before any build work begins. Resolve every ambiguity that would cause the wrong specialist to act. Surface unresolved ambiguity to the Tech Lead instead of guessing.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Owns
|
|
12
|
+
|
|
13
|
+
- Fresh app vs existing app retrofit
|
|
14
|
+
- App-only integration vs full TideCloak bootstrap
|
|
15
|
+
- Self-encryption vs shared/policy-governed encryption
|
|
16
|
+
- Setup vs diagnosis
|
|
17
|
+
- Private user app vs organisation/shared app
|
|
18
|
+
- Simple RBAC vs Forseti policy governance
|
|
19
|
+
- Scenario-pattern matching against `reference-apps/INDEX.md`
|
|
20
|
+
- Surfacing the discriminating question when ambiguity remains
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## When to Trigger
|
|
25
|
+
|
|
26
|
+
- Tech Lead has inspected the request and repo but has not yet resolved the scenario
|
|
27
|
+
- Multiple valid specialist paths are plausible
|
|
28
|
+
- The request mentions encryption, sharing, roles, or governance without enough detail to choose a path
|
|
29
|
+
- A scenario match returned multiple close results from the MCP server
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## When NOT to Trigger
|
|
34
|
+
|
|
35
|
+
- The request unambiguously maps to one scenario or one specialist
|
|
36
|
+
- The Tech Lead has already resolved the scenario
|
|
37
|
+
- The task is purely diagnostic (→ Learnings / Pack Curator)
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Execution
|
|
42
|
+
|
|
43
|
+
### Step 1: Check scenario index
|
|
44
|
+
Read `reference-apps/INDEX.md`. If the MCP server is connected, use the `tide_choose_scenario` tool (pass the user's request as `situation`). The tool scores all scenarios and auto-selects clear winners (score >= 6, gap >= 3) or surfaces disambiguation questions. If MCP is not available, manually match against the scenario keywords and discriminating questions below.
|
|
45
|
+
|
|
46
|
+
### Step 2: Apply discriminating questions
|
|
47
|
+
|
|
48
|
+
| Branch | Question | If yes | If no |
|
|
49
|
+
|--------|----------|--------|-------|
|
|
50
|
+
| Encryption vs signing | Does the app encrypt/decrypt data, or produce signatures? | Check sharing next | Signing → `policy-governed-signing` scenario |
|
|
51
|
+
| Self vs shared encryption | Do other users need to decrypt the same ciphertext? | → shared/policy path (IAM / Policy Engineer) | → self-encryption (IAM / Policy Engineer) |
|
|
52
|
+
| Fresh vs retrofit | Does the project have existing auth? | → Application Engineer (retrofit) | → Application Engineer (fresh) |
|
|
53
|
+
| Bootstrap needed? | Is TideCloak running with a configured realm? | Skip Setup | → Setup / Platform Engineer |
|
|
54
|
+
| Setup vs diagnosis | Is something broken, or not built yet? | → Learnings / Pack Curator | → appropriate specialist |
|
|
55
|
+
|
|
56
|
+
### Step 3: Conclude
|
|
57
|
+
- If resolved: name the first specialist role and hand off to the Tech Lead for sequencing.
|
|
58
|
+
- If unresolved: state the remaining ambiguity and the question that would resolve it. Do NOT guess.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Handoff Trace
|
|
63
|
+
|
|
64
|
+
Emit on entry and on conclusion:
|
|
65
|
+
```
|
|
66
|
+
[TRACE]
|
|
67
|
+
Scenario: <resolved scenario or "unresolved — asking user">
|
|
68
|
+
Role: Scenario Resolver
|
|
69
|
+
Reason: <what branches were ambiguous>
|
|
70
|
+
Preconditions: reference-apps/INDEX.md checked, discriminating questions applied
|
|
71
|
+
Next: <first specialist role or STOP if unresolved>
|
|
72
|
+
[/TRACE]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Must Not
|
|
78
|
+
|
|
79
|
+
- Guess when ambiguity remains. Surface the question.
|
|
80
|
+
- Start implementation. Scenario resolution produces a routing decision, not code.
|
|
81
|
+
- Override the Tech Lead's sequencing. The Scenario Resolver resolves *what*; the Tech Lead decides *when*.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Role: Setup / Platform Engineer
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Detect whether TideCloak infrastructure is running and correctly bootstrapped. Own the TideCloak container lifecycle, realm creation, licensing, IGA enablement, admin user, account linking, and adapter JSON export. Hand off app-level integration to `tide-integration`.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## When to Trigger
|
|
12
|
+
|
|
13
|
+
- User asks to "add login", "add auth", "set up Tide", or "start TideCloak"
|
|
14
|
+
- Another skill's repo inspection detects missing Tide setup (no SDK, no provider, or no adapter JSON)
|
|
15
|
+
- User reports login issues and CHECK-1 or CHECK-2 below have not been confirmed yet
|
|
16
|
+
- User asks about realm creation, licensing, or admin setup
|
|
17
|
+
|
|
18
|
+
### Scenario-disambiguation gate (I-17)
|
|
19
|
+
|
|
20
|
+
Before running any checks or writing code, resolve these branches if ambiguous:
|
|
21
|
+
|
|
22
|
+
| Branch | How to resolve |
|
|
23
|
+
|--------|---------------|
|
|
24
|
+
| Fresh app vs existing app | Check for existing auth (NextAuth, Clerk, custom JWT) in the repo |
|
|
25
|
+
| Generated app vs manual bootstrap | Check for `"init"` script in `package.json` or `scripts/init-tidecloak.sh` |
|
|
26
|
+
| Setup vs diagnosis | Is something broken (login hangs, roles missing)? Or does auth not exist yet? |
|
|
27
|
+
| App-only integration vs full TideCloak bootstrap | Is TideCloak already running and configured, or does it need to be started? |
|
|
28
|
+
|
|
29
|
+
If multiple paths are plausible and the repo does not resolve it, ask the user before proceeding.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## When NOT to Trigger
|
|
34
|
+
|
|
35
|
+
- App already has working Tide auth (provider present, adapter JSON loaded, login functional). Proceed to route-and-api-protection or rbac-and-e2ee skill instead.
|
|
36
|
+
- User is asking about migrating from Keycloak. Migration is not yet documented (GAP-023). Say so and stop.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Required Repo Inspection
|
|
41
|
+
|
|
42
|
+
Run these checks before any code changes. Results determine the execution path.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# CHECK-0: Is TideCloak running?
|
|
46
|
+
curl -sf http://localhost:8080 > /dev/null 2>&1 && echo "TideCloak reachable" || echo "TideCloak NOT reachable"
|
|
47
|
+
|
|
48
|
+
# CHECK-0b: Does an init script exist? (generated-app bootstrap)
|
|
49
|
+
grep -q '"init"' package.json 2>/dev/null && echo "Init script found — run: npm run init" || echo "No init script"
|
|
50
|
+
test -f scripts/init-tidecloak.sh && echo "Init script file exists" || true
|
|
51
|
+
|
|
52
|
+
# CHECK-1: Is a Tide SDK package installed?
|
|
53
|
+
grep -E '@tidecloak/(nextjs|react|js)' package.json
|
|
54
|
+
|
|
55
|
+
# CHECK-2: Is TideCloakProvider wired into the app?
|
|
56
|
+
grep -r 'TideCloakProvider\|TideCloakContextProvider' app/layout.tsx app/providers.tsx pages/_app.tsx src/app/providers.tsx 2>/dev/null
|
|
57
|
+
|
|
58
|
+
# CHECK-2b: Is config loaded from tidecloak.json (not env vars)?
|
|
59
|
+
grep -r 'NEXT_PUBLIC_TIDECLOAK' app/providers.tsx app/layout.tsx src/app/providers.tsx 2>/dev/null && echo "WARNING: Provider reads env vars — should import data/tidecloak.json instead (AP-38)"
|
|
60
|
+
grep -r 'tidecloak.json' app/providers.tsx src/app/providers.tsx 2>/dev/null || echo "WARNING: Provider does not import tidecloak.json"
|
|
61
|
+
|
|
62
|
+
# CHECK-3: Does tidecloak.json exist with Tide extensions?
|
|
63
|
+
# Next.js (server-side): check data/
|
|
64
|
+
test -f data/tidecloak.json && node -e "const c=require('./data/tidecloak.json'); console.log(!!c.jwk && !!c.vendorId && !!c.homeOrkUrl)"
|
|
65
|
+
# React/Vite or Vanilla JS (client-side): check public/
|
|
66
|
+
test -f public/tidecloak.json && echo "Found at public/tidecloak.json" || echo "Not in public/"
|
|
67
|
+
# Wrong filename? (common mistake)
|
|
68
|
+
ls data/adapter.json data/keycloak.json public/adapter.json public/keycloak.json 2>/dev/null && echo "WRONG FILENAME — must be tidecloak.json"
|
|
69
|
+
|
|
70
|
+
# CHECK-3b: Does the config API route exist? (Next.js only)
|
|
71
|
+
# Required so the client-side SDK can fetch adapter JSON (default configUrl is /adapter.json which won't exist)
|
|
72
|
+
ls app/api/config/route.ts src/app/api/config/route.ts 2>/dev/null && echo "Config API route found" || echo "Config API route MISSING"
|
|
73
|
+
grep -r 'configUrl' app/providers.tsx src/app/providers.tsx 2>/dev/null || echo "WARNING: configUrl not set on provider — SDK will try /adapter.json"
|
|
74
|
+
|
|
75
|
+
# CHECK-4: Is DPoP configured?
|
|
76
|
+
grep -r 'useDPoP\|enableDpop' app/providers.tsx app/layout.tsx pages/_app.tsx src/main.tsx 2>/dev/null
|
|
77
|
+
|
|
78
|
+
# CHECK-5: Does silent-check-sso.html exist?
|
|
79
|
+
test -f public/silent-check-sso.html && echo "Found" || echo "Missing"
|
|
80
|
+
|
|
81
|
+
# CHECK-6: Is CSP configured for SWE iframe?
|
|
82
|
+
grep -r "frame-src" next.config.* 2>/dev/null
|
|
83
|
+
|
|
84
|
+
# CHECK-6b: What Next.js version is installed? (determines proxy.ts vs middleware.ts)
|
|
85
|
+
NEXT_MAJOR=$(node -e "try{console.log(require('next/package.json').version.split('.')[0])}catch{console.log('unknown')}" 2>/dev/null)
|
|
86
|
+
echo "Next.js major version: $NEXT_MAJOR"
|
|
87
|
+
# 16+ → request interception file is proxy.ts
|
|
88
|
+
# 15 or earlier → request interception file is middleware.ts
|
|
89
|
+
|
|
90
|
+
# CHECK-7: Does the post-auth redirect handler exist?
|
|
91
|
+
# Next.js App Router:
|
|
92
|
+
test -f app/auth/redirect/page.tsx || test -f src/app/auth/redirect/page.tsx && echo "Found" || echo "Missing"
|
|
93
|
+
# Next.js Pages Router:
|
|
94
|
+
test -f pages/auth/redirect.tsx || test -f src/pages/auth/redirect.tsx && echo "Found" || echo "Missing"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Preconditions
|
|
100
|
+
|
|
101
|
+
- A Next.js (or React/Vite) project exists with `package.json` (for app integration paths)
|
|
102
|
+
- Docker installed (for bootstrap paths)
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Execution Workflow
|
|
107
|
+
|
|
108
|
+
### Pre-step: Scenario matching
|
|
109
|
+
|
|
110
|
+
Before running checks, determine if the user's request matches a known scenario in `reference-apps/INDEX.md`.
|
|
111
|
+
|
|
112
|
+
If the user describes an app that matches a scenario (e.g., "build me a password manager", "shared credential vault"):
|
|
113
|
+
1. Read the scenario's `manifest.yaml` for roles, policies, and playbook sequence.
|
|
114
|
+
2. Use the manifest's `playbook_sequence` instead of the default ordering below.
|
|
115
|
+
3. Use the manifest's `roles` to generate or validate the realm template.
|
|
116
|
+
4. Follow the scenario's `bootstrap-sequence.md` for pre-user admin setup.
|
|
117
|
+
|
|
118
|
+
If no scenario matches, continue with the standard detection flow below.
|
|
119
|
+
|
|
120
|
+
### Path 0: TideCloak not running (CHECK-0 fails)
|
|
121
|
+
|
|
122
|
+
The user needs infrastructure before app integration. Choose the right bootstrap path:
|
|
123
|
+
|
|
124
|
+
**If the project has an init script** (`npm run init` in package.json or `scripts/init-tidecloak.sh` exists):
|
|
125
|
+
|
|
126
|
+
1. Run `npm run init`. This handles the full TideCloak bootstrap automatically.
|
|
127
|
+
2. After init completes, return to CHECK-1 for app integration verification.
|
|
128
|
+
|
|
129
|
+
**If no init script exists** (manual / BYO TideCloak):
|
|
130
|
+
|
|
131
|
+
1. Route to bootstrap playbook chain:
|
|
132
|
+
- `start-tidecloak-dev` → start TideCloak container
|
|
133
|
+
- `bootstrap-realm-from-template` → create realm, enable licensing + IGA
|
|
134
|
+
- `initialize-admin-and-link-account` → admin user, invite link, adapter export
|
|
135
|
+
2. If E2EE is needed or scenario requires it: also `configure-e2ee-roles-and-policies`
|
|
136
|
+
3. If scenario has policies: also `setup-forseti-e2ee` after bootstrap
|
|
137
|
+
4. After bootstrap, return to CHECK-1 for app integration.
|
|
138
|
+
|
|
139
|
+
**Do not** attempt app-level Tide integration without a running TideCloak.
|
|
140
|
+
|
|
141
|
+
### Path A/B/C/D: App integration needed
|
|
142
|
+
|
|
143
|
+
**Hand off to `tide-integration` skill.** This skill does not own SDK install, provider wiring, config loading, or hardening.
|
|
144
|
+
|
|
145
|
+
- CHECK-1 or CHECK-2 fail (no SDK or no provider) → `tide-integration`
|
|
146
|
+
- CHECK-3 fails (adapter JSON missing but TideCloak running) → export via `initialize-admin-and-link-account` Step 7, then `tide-integration`
|
|
147
|
+
- CHECK-3 fails and TideCloak not running → Path 0 first, then `tide-integration`
|
|
148
|
+
- CHECK-4/5/6 fail (missing DPoP, silent SSO, redirect handler, CSP) → `tide-integration`
|
|
149
|
+
|
|
150
|
+
### Path E: All checks pass
|
|
151
|
+
|
|
152
|
+
Bootstrap and integration are complete. Route to the next subagent:
|
|
153
|
+
- Need route guards or API protection → `tide-route-and-api-protection`
|
|
154
|
+
- Need RBAC or private E2EE (no sharing) → `tide-rbac-and-e2ee`
|
|
155
|
+
- Need E2EE with sharing / multiple users decrypt → `tide-rbac-and-e2ee` (sharing gate routes to `setup-forseti-e2ee`)
|
|
156
|
+
- Something is broken → `tide-diagnostics`
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Safety Checks
|
|
161
|
+
|
|
162
|
+
- **Do not use the scaffold command** (`npm init @tidecloak/nextjs@latest`) unless the user explicitly requests it. Manual setup is more inspectable.
|
|
163
|
+
- See `adapters/AGENTS.md` Forbidden Shortcuts for the full safety rule set (fake auth, plain-text cookies, custom passwords, DPoP skip).
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Verification Checklist
|
|
168
|
+
|
|
169
|
+
After setup is complete, verify:
|
|
170
|
+
|
|
171
|
+
- [ ] TideCloak running and reachable
|
|
172
|
+
- [ ] `@tidecloak/nextjs` (or equivalent) in `package.json`
|
|
173
|
+
- [ ] `TideCloakProvider` (Next.js) or `TideCloakContextProvider` (React) wraps the app with `useDPoP` in config object
|
|
174
|
+
- [ ] `data/tidecloak.json` exists with `jwk`, `vendorId`, `homeOrkUrl` fields
|
|
175
|
+
- [ ] `public/silent-check-sso.html` exists
|
|
176
|
+
- [ ] Post-auth redirect handler exists at configured `redirectUri` path (I-16)
|
|
177
|
+
- [ ] CSP includes `frame-src '*'`
|
|
178
|
+
- [ ] `npm run dev` starts without import errors
|
|
179
|
+
- [ ] Login redirects to TideCloak and returns with authenticated state
|
|
180
|
+
- [ ] Browser console shows no CSP violations or 404s
|
|
181
|
+
- [ ] Logout clears session
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Repair Path
|
|
186
|
+
|
|
187
|
+
If login hangs after setup:
|
|
188
|
+
1. Check browser console for CSP violations → fix CSP
|
|
189
|
+
2. Check for 404 on `silent-check-sso.html` → create the file
|
|
190
|
+
3. Check TideCloak reachability: `curl ${TIDECLOAK_URL}/realms/${REALM}/.well-known/openid-configuration`
|
|
191
|
+
4. Check adapter JSON validity: `node -e "console.log(require('./data/tidecloak.json'))"`
|
|
192
|
+
5. Test in incognito browser (stale localStorage can cause hangs)
|
|
193
|
+
6. If all else fails, use playbook `diagnose-broken-login`
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Handoff Trace
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
[TRACE]
|
|
201
|
+
Scenario: <scenario>
|
|
202
|
+
Role: Setup / Platform Engineer
|
|
203
|
+
Reason: <TideCloak not running | realm not configured | init script available>
|
|
204
|
+
Preconditions: Docker available, port 8080 free
|
|
205
|
+
Next: Application Engineer | STOP if bootstrap failed
|
|
206
|
+
[/TRACE]
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Do Not Do This
|
|
212
|
+
|
|
213
|
+
- **Do not diagnose Tide issues on an app without Tide installed.** Route to setup playbook first.
|
|
214
|
+
- **Do not create a mock TideCloak provider** or stub that simulates auth without a real TideCloak instance.
|
|
215
|
+
- **Do not fabricate adapter JSON** or create placeholder configs. The file must be exported from TideCloak.
|
|
216
|
+
- **Do not hardcode TideCloak URLs in source files.** Use `data/tidecloak.json` (Next.js) or `public/tidecloak.json` (React/Vite). Do not use `NEXT_PUBLIC_TIDECLOAK_*` env vars (AP-38). Server-side code may use `CLIENT_ADAPTER` or `TIDECLOAK_CONFIG_B64` env vars for deployment.
|
|
217
|
+
- **Do not skip TideCloak bootstrap** when the server is not running. App integration depends on a configured realm.
|
|
218
|
+
- For additional prohibitions (fake auth helpers, custom password flows, ESM import pitfalls), see `adapters/AGENTS.md` Forbidden Shortcuts.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Role: Solutions Architect
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Discover safe implementation patterns that meet the user's goal while staying inside pack rules and security invariants. This subagent explores when the pack does not already provide a clear direct path. It proposes — it does not override doctrine.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Boundary
|
|
12
|
+
|
|
13
|
+
| Allowed to explore | Forbidden to change |
|
|
14
|
+
|-------------------|---------------------|
|
|
15
|
+
| Implementation patterns | Security invariants (I-01 through I-18) |
|
|
16
|
+
| Developer workflow | Trust boundaries |
|
|
17
|
+
| Template structure | Encryption model semantics |
|
|
18
|
+
| Scenario modeling | JWK/JWKS rules (I-04) |
|
|
19
|
+
| Initialization ergonomics | Policy requirements |
|
|
20
|
+
| App architecture choices inside pack constraints | Role model truth |
|
|
21
|
+
| Safe alternatives to missing playbooks | Already-settled doctrine |
|
|
22
|
+
|
|
23
|
+
The Solutions Architect does not override doctrine. It does not weaken invariants. It does not bypass scenario disambiguation. It does not silently promote a new pattern into default pack behavior.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## When to Trigger
|
|
28
|
+
|
|
29
|
+
- No existing scenario cleanly matches the request
|
|
30
|
+
- Multiple safe implementation paths are possible and the choice is non-obvious
|
|
31
|
+
- The pack has a known gap (documented in GAP_REGISTER.md) but the user's goal is still legitimate
|
|
32
|
+
- The user explicitly asks for alternatives or a novel pattern
|
|
33
|
+
- Normal subagents are blocked because the pattern is not yet encoded in the pack
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## When NOT to Trigger
|
|
38
|
+
|
|
39
|
+
- Normal known workflows already covered by existing scenarios/playbooks
|
|
40
|
+
- Routine bootstrap/setup (→ `tide-setup`)
|
|
41
|
+
- Standard auth/protection/RBAC flows (→ `tide-integration`, `tide-route-and-api-protection`, `tide-rbac-and-e2ee`)
|
|
42
|
+
- Diagnostic work (→ `tide-diagnostics`)
|
|
43
|
+
- Compliance checking (→ `tide-reviewer`)
|
|
44
|
+
|
|
45
|
+
If the pack already has a clear path, use it. The Solutions Architect is for the gaps, not the defaults.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Execution
|
|
50
|
+
|
|
51
|
+
### Step 1: Define the goal
|
|
52
|
+
State what the user wants to achieve in one sentence.
|
|
53
|
+
|
|
54
|
+
### Step 2: Identify constraints
|
|
55
|
+
List the pack constraints that apply:
|
|
56
|
+
- Which invariants are relevant?
|
|
57
|
+
- Which anti-patterns must be avoided?
|
|
58
|
+
- Which scenario (if any) partially matches?
|
|
59
|
+
- What is documented as deferred or unresolved (GAP_REGISTER)?
|
|
60
|
+
|
|
61
|
+
### Step 3: Generate candidate patterns
|
|
62
|
+
Propose 2–3 safe implementation approaches. For each:
|
|
63
|
+
- Describe the pattern
|
|
64
|
+
- Identify what is VERIFIED, what is INFERRED, what is ASSUMED
|
|
65
|
+
- Note which pack layers support it (canon, playbook, exemplar, none)
|
|
66
|
+
|
|
67
|
+
### Step 4: Recommend
|
|
68
|
+
Select the best pattern. Explain:
|
|
69
|
+
- Why it fits the pack
|
|
70
|
+
- What risks remain
|
|
71
|
+
- What open questions exist
|
|
72
|
+
|
|
73
|
+
### Step 5: Classify the pattern
|
|
74
|
+
Recommend whether the discovered pattern should become:
|
|
75
|
+
|
|
76
|
+
| Classification | Meaning |
|
|
77
|
+
|---------------|---------|
|
|
78
|
+
| **New scenario** | Pattern is reusable across apps. Add to `reference-apps/`. |
|
|
79
|
+
| **New playbook** | Procedure is reusable. Add to `playbooks/`. |
|
|
80
|
+
| **New template pattern** | Implementation is reusable. Add to `templates/`. |
|
|
81
|
+
| **MCP learning** | Routing/detection rule. Update MCP server. |
|
|
82
|
+
| **App-specific** | Pattern is one-off. Do NOT promote to pack. |
|
|
83
|
+
| **Needs runtime validation** | Pattern is plausible but unverified. Tag ASSUMED. |
|
|
84
|
+
|
|
85
|
+
### Step 6: Hand off
|
|
86
|
+
- If the pattern is ready to implement → hand to the appropriate execution subagent
|
|
87
|
+
- If the pattern should be validated → hand to `tide-reviewer`
|
|
88
|
+
- If the pattern should be taught back → hand to `tide-diagnostics` for learning extraction
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Expected Output
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
Goal: <one sentence>
|
|
96
|
+
Constraints: <relevant invariants, anti-patterns, gaps>
|
|
97
|
+
Candidate patterns:
|
|
98
|
+
1. <pattern A> — <VERIFIED|INFERRED|ASSUMED>
|
|
99
|
+
2. <pattern B> — <VERIFIED|INFERRED|ASSUMED>
|
|
100
|
+
Recommended: <which and why>
|
|
101
|
+
Risks: <what could go wrong>
|
|
102
|
+
Open questions: <what is not yet known>
|
|
103
|
+
Classification: <scenario | playbook | template | MCP learning | app-specific | needs validation>
|
|
104
|
+
Hand off to: <subagent name>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Handoff Trace
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
[TRACE]
|
|
113
|
+
Scenario: <none — no existing path covers this request>
|
|
114
|
+
Role: Solutions Architect
|
|
115
|
+
Reason: <what gap or novel pattern triggered this>
|
|
116
|
+
Preconditions: Scenario Resolver found no match, existing playbooks insufficient
|
|
117
|
+
Next: <execution specialist | Reviewer | Pack Curator>
|
|
118
|
+
[/TRACE]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Do Not Do This
|
|
124
|
+
|
|
125
|
+
- Do not override security invariants to make a pattern work.
|
|
126
|
+
- Do not bypass scenario disambiguation (I-17). If ambiguity exists, resolve it first.
|
|
127
|
+
- Do not silently promote a new pattern into default pack behavior. Classify it explicitly.
|
|
128
|
+
- Do not act as a replacement for the Reviewer. The Reviewer validates compliance; the Solutions Architect explores possibilities.
|
|
129
|
+
- Do not act as a replacement for execution subagents. Propose patterns; let the execution subagent implement them.
|
|
130
|
+
- Do not invent certainty. If something is uncertain, mark it ASSUMED and note the open question.
|