@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,195 @@
1
+ # Server-Side Delegation - Canon
2
+
3
+ Canonical reference for server-side admin API calls via delegation tokens.
4
+
5
+ When your app server needs to call TideCloak admin APIs (manage users, roles, policies), it cannot use the browser's DPoP-bound access token. The delegation flow issues a new token bound to the server's ephemeral key.
6
+
7
+ ---
8
+
9
+ ## Packages
10
+
11
+ | Package | Side | Purpose |
12
+ |---------|------|---------|
13
+ | `@tidecloak/server` | Server | `TideDelegation` class, middleware, DPoP proof generation |
14
+ | `@tidecloak/js` | Browser | `createTideFetch` wrapper, `signDelegationRequest`, `signDpopApproval` |
15
+
16
+ ---
17
+
18
+ ## Flow: Forgetful Interrupt Pattern
19
+
20
+ 1. Browser calls server endpoint (e.g., `GET /api/admin/users`)
21
+ 2. Server `requireDelegation()` middleware checks cache. No cached token.
22
+ 3. Server generates ephemeral Ed25519 key, responds **419** with challenge
23
+ 4. `createTideFetch` intercepts 419, calls `IAMService.signDelegationRequest(payload)` and `IAMService.signDpopApproval(serverJkt)`
24
+ 5. Browser POSTs signed artifacts to `/api/delegation`
25
+ 6. Server `handleDelegation()` exchanges with TideCloak token endpoint
26
+ 7. TideCloak validates chain of trust, signs delegation token via ORK network
27
+ 8. Server caches delegation token, responds `{ delegated: true }`
28
+ 9. `createTideFetch` retries original request. Server finds cached token, proceeds.
29
+
30
+ Subsequent requests use the cached token until it expires.
31
+
32
+ ---
33
+
34
+ ## Setup
35
+
36
+ ### Server
37
+
38
+ ```js
39
+ import { TideDelegation } from '@tidecloak/server';
40
+
41
+ const delegation = new TideDelegation({
42
+ tidecloakUrl: process.env.TIDECLOAK_URL,
43
+ realm: process.env.TIDECLOAK_REALM,
44
+ clientId: process.env.TIDECLOAK_CLIENT_ID,
45
+ });
46
+
47
+ // Exchange endpoint
48
+ app.post('/api/delegation', authenticate, delegation.handleDelegation());
49
+
50
+ // Protected route with delegation
51
+ app.get('/api/admin/users',
52
+ authenticate,
53
+ delegation.requireDelegation(),
54
+ async (req, res) => {
55
+ const users = await req.delegation.fetch(adminUrl + '/users');
56
+ res.json(users);
57
+ }
58
+ );
59
+ ```
60
+
61
+ ### Browser
62
+
63
+ ```js
64
+ import { createTideFetch } from '@tidecloak/js';
65
+
66
+ const appFetch = createTideFetch(window.fetch);
67
+
68
+ // Delegation is transparent
69
+ const users = await appFetch('/api/admin/users');
70
+ ```
71
+
72
+ ---
73
+
74
+ ## Scoped Delegation
75
+
76
+ Limit roles in the delegation token. If `roles` is specified, only listed roles/clients appear. Everything else is stripped.
77
+
78
+ ```js
79
+ // Only read role for my-app client
80
+ delegation.requireDelegation({
81
+ roles: {
82
+ clients: { 'my-app': ['read'] }
83
+ }
84
+ })
85
+
86
+ // Realm + multiple clients
87
+ delegation.requireDelegation({
88
+ roles: {
89
+ realm: ['admin'],
90
+ clients: {
91
+ 'my-app': ['read', 'write'],
92
+ 'other-app': ['view']
93
+ }
94
+ }
95
+ })
96
+
97
+ // No filtering (default)
98
+ delegation.requireDelegation()
99
+ ```
100
+
101
+ Rules:
102
+ - Omitting `roles` entirely keeps all user roles
103
+ - Once `roles` is specified, unlisted realms/clients are stripped
104
+ - Cannot escalate. Requesting a role the user does not have silently drops it.
105
+
106
+ ---
107
+
108
+ ## Token Exchange Endpoint
109
+
110
+ The server exchanges artifacts at TideCloak's standard OIDC token endpoint:
111
+
112
+ ```
113
+ POST /realms/{realm}/protocol/openid-connect/token
114
+ ```
115
+
116
+ Parameters (form-encoded):
117
+ - `grant_type`: `urn:ietf:params:oauth:grant-type:token-exchange`
118
+ - `client_id`: app client ID
119
+ - `subject_token`: user's access token
120
+ - `subject_token_type`: `urn:ietf:params:oauth:token-type:access_token`
121
+ - `actor_token`: browser-signed delegation request JWT
122
+ - `actor_token_type`: `urn:ietf:params:oauth:token-type:jwt`
123
+ - `dpop_approval`: session key approval of server's DPoP key
124
+
125
+ Headers:
126
+ - `DPoP`: server's DPoP proof JWT (Ed25519, contains server's public key)
127
+
128
+ Response: `{ access_token, token_type: "DPoP", expires_in, issued_token_type }`
129
+
130
+ ---
131
+
132
+ ## Chain of Trust
133
+
134
+ Two-hop validation ensures the delegation token is legitimately authorized:
135
+
136
+ **HOP 1**: `subject_token.cnf.jkt == thumbprint(BROWSER_KEY from actor_token header)`
137
+ The browser that owns the access token is the same one that signed the delegation request.
138
+
139
+ **HOP 2**: `actor_token.cnf.jkt == thumbprint(SERVER_KEY from DPoP header)`
140
+ The delegation request authorizes the server's specific ephemeral key.
141
+
142
+ Validated at two layers:
143
+ 1. TideCloak authenticator (Java) - before token is built
144
+ 2. ORK signing model (C#) - before token is threshold-signed
145
+
146
+ ---
147
+
148
+ ## Using req.delegation.fetch()
149
+
150
+ The `fetch` helper on `req.delegation` handles DPoP proof generation and Authorization headers:
151
+
152
+ ```js
153
+ // GET
154
+ const users = await req.delegation.fetch(url);
155
+
156
+ // POST with JSON
157
+ await req.delegation.fetch(url, { method: 'POST', body: { name: 'role' } });
158
+
159
+ // PUT
160
+ await req.delegation.fetch(url, { method: 'PUT', body: { enabled: true } });
161
+
162
+ // DELETE
163
+ await req.delegation.fetch(url, { method: 'DELETE' });
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Anti-Patterns
169
+
170
+ - **Do not use master admin credentials** for server-side admin calls. Use delegation.
171
+ - **Do not forward the user's browser token** to admin API. It is DPoP-bound to the browser's key.
172
+ - **Do not skip DPoP on delegation requests**. The delegation token is DPoP-bound to the server's ephemeral key. Every admin API call needs a fresh DPoP proof with `ath` claim.
173
+ - **Do not share delegation tokens across users**. They are cached per session ID.
174
+ - **Do not hardcode server keys**. They are ephemeral Ed25519 keys, generated per session.
175
+
176
+ ---
177
+
178
+ ## Prerequisites
179
+
180
+ - TideCloak with `tide-chain-of-trust` client authenticator enabled (added by default in recent TideCloak builds)
181
+ - `DelegationToken:1` in the VRK model whitelist (requires VRK rotation after adding)
182
+ - DPoP enabled on the client
183
+ - `@tidecloak/server` installed on the backend
184
+ - `createTideFetch` wrapping fetch on the frontend
185
+ - An `authenticate` middleware that sets `req.accessToken` from the Authorization header
186
+
187
+ ---
188
+
189
+ ## Invariants
190
+
191
+ - Delegation tokens are short-lived (max 600s / 10 minutes)
192
+ - Server key is ephemeral per session, cleared when delegation cache expires
193
+ - The browser must approve each server key via ORK enclave (DPoP approval)
194
+ - Scoped delegation can only reduce roles, never add them
195
+ - Delegation tokens have `act: { sub: clientId }` per RFC 8693