@kya-os/mcp-i-core 1.3.12 → 1.3.14

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 (254) hide show
  1. package/dist/config/remote-config.js +9 -12
  2. package/dist/runtime/base.js +11 -0
  3. package/dist/services/access-control.service.js +5 -0
  4. package/dist/services/tool-protection.service.js +17 -8
  5. package/package.json +2 -2
  6. package/.turbo/turbo-build.log +0 -4
  7. package/.turbo/turbo-test$colon$coverage.log +0 -4586
  8. package/.turbo/turbo-test.log +0 -3169
  9. package/COMPLIANCE_IMPROVEMENT_REPORT.md +0 -483
  10. package/Composer 3.md +0 -615
  11. package/GPT-5.md +0 -1169
  12. package/OPUS-plan.md +0 -352
  13. package/PHASE_3_AND_4.1_SUMMARY.md +0 -585
  14. package/PHASE_3_SUMMARY.md +0 -317
  15. package/PHASE_4.1.3_SUMMARY.md +0 -428
  16. package/PHASE_4.1_COMPLETE.md +0 -525
  17. package/PHASE_4_USER_DID_IDENTITY_LINKING_PLAN.md +0 -1240
  18. package/SCHEMA_COMPLIANCE_REPORT.md +0 -275
  19. package/TEST_PLAN.md +0 -571
  20. package/coverage/coverage-final.json +0 -60
  21. package/dist/cache/oauth-config-cache.d.ts.map +0 -1
  22. package/dist/cache/oauth-config-cache.js.map +0 -1
  23. package/dist/cache/tool-protection-cache.d.ts.map +0 -1
  24. package/dist/cache/tool-protection-cache.js.map +0 -1
  25. package/dist/compliance/index.d.ts.map +0 -1
  26. package/dist/compliance/index.js.map +0 -1
  27. package/dist/compliance/schema-registry.d.ts.map +0 -1
  28. package/dist/compliance/schema-registry.js.map +0 -1
  29. package/dist/compliance/schema-verifier.d.ts.map +0 -1
  30. package/dist/compliance/schema-verifier.js.map +0 -1
  31. package/dist/config/remote-config.d.ts.map +0 -1
  32. package/dist/config/remote-config.js.map +0 -1
  33. package/dist/config.d.ts.map +0 -1
  34. package/dist/config.js.map +0 -1
  35. package/dist/delegation/audience-validator.d.ts.map +0 -1
  36. package/dist/delegation/audience-validator.js.map +0 -1
  37. package/dist/delegation/bitstring.d.ts.map +0 -1
  38. package/dist/delegation/bitstring.js.map +0 -1
  39. package/dist/delegation/cascading-revocation.d.ts.map +0 -1
  40. package/dist/delegation/cascading-revocation.js.map +0 -1
  41. package/dist/delegation/delegation-graph.d.ts.map +0 -1
  42. package/dist/delegation/delegation-graph.js.map +0 -1
  43. package/dist/delegation/did-key-resolver.d.ts.map +0 -1
  44. package/dist/delegation/did-key-resolver.js.map +0 -1
  45. package/dist/delegation/index.d.ts.map +0 -1
  46. package/dist/delegation/index.js.map +0 -1
  47. package/dist/delegation/statuslist-manager.d.ts.map +0 -1
  48. package/dist/delegation/statuslist-manager.js.map +0 -1
  49. package/dist/delegation/storage/index.d.ts.map +0 -1
  50. package/dist/delegation/storage/index.js.map +0 -1
  51. package/dist/delegation/storage/memory-graph-storage.d.ts.map +0 -1
  52. package/dist/delegation/storage/memory-graph-storage.js.map +0 -1
  53. package/dist/delegation/storage/memory-statuslist-storage.d.ts.map +0 -1
  54. package/dist/delegation/storage/memory-statuslist-storage.js.map +0 -1
  55. package/dist/delegation/utils.d.ts.map +0 -1
  56. package/dist/delegation/utils.js.map +0 -1
  57. package/dist/delegation/vc-issuer.d.ts.map +0 -1
  58. package/dist/delegation/vc-issuer.js.map +0 -1
  59. package/dist/delegation/vc-verifier.d.ts.map +0 -1
  60. package/dist/delegation/vc-verifier.js.map +0 -1
  61. package/dist/identity/idp-token-resolver.d.ts.map +0 -1
  62. package/dist/identity/idp-token-resolver.js.map +0 -1
  63. package/dist/identity/idp-token-storage.interface.d.ts.map +0 -1
  64. package/dist/identity/idp-token-storage.interface.js.map +0 -1
  65. package/dist/identity/user-did-manager.d.ts.map +0 -1
  66. package/dist/identity/user-did-manager.js.map +0 -1
  67. package/dist/index.d.ts.map +0 -1
  68. package/dist/index.js.map +0 -1
  69. package/dist/providers/base.d.ts.map +0 -1
  70. package/dist/providers/base.js.map +0 -1
  71. package/dist/providers/memory.d.ts.map +0 -1
  72. package/dist/providers/memory.js.map +0 -1
  73. package/dist/runtime/audit-logger.d.ts.map +0 -1
  74. package/dist/runtime/audit-logger.js.map +0 -1
  75. package/dist/runtime/base.d.ts.map +0 -1
  76. package/dist/runtime/base.js.map +0 -1
  77. package/dist/services/access-control.service.d.ts.map +0 -1
  78. package/dist/services/access-control.service.js.map +0 -1
  79. package/dist/services/authorization/authorization-registry.d.ts.map +0 -1
  80. package/dist/services/authorization/authorization-registry.js.map +0 -1
  81. package/dist/services/authorization/types.d.ts.map +0 -1
  82. package/dist/services/authorization/types.js.map +0 -1
  83. package/dist/services/batch-delegation.service.d.ts.map +0 -1
  84. package/dist/services/batch-delegation.service.js.map +0 -1
  85. package/dist/services/crypto.service.d.ts.map +0 -1
  86. package/dist/services/crypto.service.js.map +0 -1
  87. package/dist/services/errors.d.ts.map +0 -1
  88. package/dist/services/errors.js.map +0 -1
  89. package/dist/services/index.d.ts.map +0 -1
  90. package/dist/services/index.js.map +0 -1
  91. package/dist/services/oauth-config.service.d.ts.map +0 -1
  92. package/dist/services/oauth-config.service.js.map +0 -1
  93. package/dist/services/oauth-provider-registry.d.ts.map +0 -1
  94. package/dist/services/oauth-provider-registry.js.map +0 -1
  95. package/dist/services/oauth-service.d.ts.map +0 -1
  96. package/dist/services/oauth-service.js.map +0 -1
  97. package/dist/services/oauth-token-retrieval.service.d.ts.map +0 -1
  98. package/dist/services/oauth-token-retrieval.service.js.map +0 -1
  99. package/dist/services/proof-verifier.d.ts.map +0 -1
  100. package/dist/services/proof-verifier.js.map +0 -1
  101. package/dist/services/provider-resolver.d.ts.map +0 -1
  102. package/dist/services/provider-resolver.js.map +0 -1
  103. package/dist/services/provider-validator.d.ts.map +0 -1
  104. package/dist/services/provider-validator.js.map +0 -1
  105. package/dist/services/session-registration.service.d.ts.map +0 -1
  106. package/dist/services/session-registration.service.js.map +0 -1
  107. package/dist/services/storage.service.d.ts.map +0 -1
  108. package/dist/services/storage.service.js.map +0 -1
  109. package/dist/services/tool-context-builder.d.ts.map +0 -1
  110. package/dist/services/tool-context-builder.js.map +0 -1
  111. package/dist/services/tool-protection.service.d.ts.map +0 -1
  112. package/dist/services/tool-protection.service.js.map +0 -1
  113. package/dist/types/oauth-required-error.d.ts.map +0 -1
  114. package/dist/types/oauth-required-error.js.map +0 -1
  115. package/dist/types/tool-protection.d.ts.map +0 -1
  116. package/dist/types/tool-protection.js.map +0 -1
  117. package/dist/utils/base58.d.ts.map +0 -1
  118. package/dist/utils/base58.js.map +0 -1
  119. package/dist/utils/base64.d.ts.map +0 -1
  120. package/dist/utils/base64.js.map +0 -1
  121. package/dist/utils/cors.d.ts.map +0 -1
  122. package/dist/utils/cors.js.map +0 -1
  123. package/dist/utils/did-helpers.d.ts.map +0 -1
  124. package/dist/utils/did-helpers.js.map +0 -1
  125. package/dist/utils/index.d.ts.map +0 -1
  126. package/dist/utils/index.js.map +0 -1
  127. package/dist/utils/storage-keys.d.ts.map +0 -1
  128. package/dist/utils/storage-keys.js.map +0 -1
  129. package/docs/API_REFERENCE.md +0 -1362
  130. package/docs/COMPLIANCE_MATRIX.md +0 -691
  131. package/docs/STATUSLIST2021_GUIDE.md +0 -696
  132. package/docs/W3C_VC_DELEGATION_GUIDE.md +0 -710
  133. package/src/__tests__/cache/tool-protection-cache.test.ts +0 -640
  134. package/src/__tests__/config/provider-runtime-config.test.ts +0 -309
  135. package/src/__tests__/delegation-e2e.test.ts +0 -690
  136. package/src/__tests__/identity/user-did-manager.test.ts +0 -232
  137. package/src/__tests__/index.test.ts +0 -56
  138. package/src/__tests__/integration/full-flow.test.ts +0 -789
  139. package/src/__tests__/integration.test.ts +0 -281
  140. package/src/__tests__/providers/base.test.ts +0 -173
  141. package/src/__tests__/providers/memory.test.ts +0 -319
  142. package/src/__tests__/regression/phase2-regression.test.ts +0 -429
  143. package/src/__tests__/runtime/audit-logger.test.ts +0 -154
  144. package/src/__tests__/runtime/base-extensions.test.ts +0 -595
  145. package/src/__tests__/runtime/base.test.ts +0 -869
  146. package/src/__tests__/runtime/delegation-flow.test.ts +0 -164
  147. package/src/__tests__/runtime/proof-client-did.test.ts +0 -376
  148. package/src/__tests__/runtime/route-interception.test.ts +0 -686
  149. package/src/__tests__/runtime/tool-protection-enforcement.test.ts +0 -908
  150. package/src/__tests__/services/agentshield-integration.test.ts +0 -791
  151. package/src/__tests__/services/cache-busting.test.ts +0 -125
  152. package/src/__tests__/services/oauth-service-pkce.test.ts +0 -556
  153. package/src/__tests__/services/provider-resolver-edge-cases.test.ts +0 -591
  154. package/src/__tests__/services/tool-protection-merged-config.test.ts +0 -485
  155. package/src/__tests__/services/tool-protection-oauth-provider.test.ts +0 -480
  156. package/src/__tests__/services/tool-protection.service.test.ts +0 -1373
  157. package/src/__tests__/utils/mock-providers.ts +0 -340
  158. package/src/cache/oauth-config-cache.d.ts +0 -69
  159. package/src/cache/oauth-config-cache.d.ts.map +0 -1
  160. package/src/cache/oauth-config-cache.js.map +0 -1
  161. package/src/cache/oauth-config-cache.ts +0 -123
  162. package/src/cache/tool-protection-cache.ts +0 -171
  163. package/src/compliance/EXAMPLE.md +0 -412
  164. package/src/compliance/__tests__/schema-verifier.test.ts +0 -797
  165. package/src/compliance/index.ts +0 -8
  166. package/src/compliance/schema-registry.ts +0 -460
  167. package/src/compliance/schema-verifier.ts +0 -708
  168. package/src/config/__tests__/merged-config.spec.ts +0 -445
  169. package/src/config/__tests__/remote-config.spec.ts +0 -268
  170. package/src/config/remote-config.ts +0 -264
  171. package/src/config.ts +0 -312
  172. package/src/delegation/__tests__/audience-validator.test.ts +0 -112
  173. package/src/delegation/__tests__/bitstring.test.ts +0 -346
  174. package/src/delegation/__tests__/cascading-revocation.test.ts +0 -628
  175. package/src/delegation/__tests__/delegation-graph.test.ts +0 -584
  176. package/src/delegation/__tests__/did-key-resolver.test.ts +0 -265
  177. package/src/delegation/__tests__/utils.test.ts +0 -152
  178. package/src/delegation/__tests__/vc-issuer.test.ts +0 -442
  179. package/src/delegation/__tests__/vc-verifier.test.ts +0 -922
  180. package/src/delegation/audience-validator.ts +0 -52
  181. package/src/delegation/bitstring.ts +0 -278
  182. package/src/delegation/cascading-revocation.ts +0 -370
  183. package/src/delegation/delegation-graph.ts +0 -299
  184. package/src/delegation/did-key-resolver.ts +0 -179
  185. package/src/delegation/index.ts +0 -14
  186. package/src/delegation/statuslist-manager.ts +0 -353
  187. package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +0 -366
  188. package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +0 -228
  189. package/src/delegation/storage/index.ts +0 -9
  190. package/src/delegation/storage/memory-graph-storage.ts +0 -178
  191. package/src/delegation/storage/memory-statuslist-storage.ts +0 -77
  192. package/src/delegation/utils.ts +0 -221
  193. package/src/delegation/vc-issuer.ts +0 -232
  194. package/src/delegation/vc-verifier.ts +0 -568
  195. package/src/identity/idp-token-resolver.ts +0 -181
  196. package/src/identity/idp-token-storage.interface.ts +0 -94
  197. package/src/identity/user-did-manager.ts +0 -526
  198. package/src/index.ts +0 -310
  199. package/src/providers/base.d.ts +0 -91
  200. package/src/providers/base.d.ts.map +0 -1
  201. package/src/providers/base.js.map +0 -1
  202. package/src/providers/base.ts +0 -96
  203. package/src/providers/memory.ts +0 -142
  204. package/src/runtime/audit-logger.ts +0 -39
  205. package/src/runtime/base.ts +0 -1392
  206. package/src/services/__tests__/access-control.integration.test.ts +0 -443
  207. package/src/services/__tests__/access-control.proof-response-validation.test.ts +0 -578
  208. package/src/services/__tests__/access-control.service.test.ts +0 -970
  209. package/src/services/__tests__/batch-delegation.service.test.ts +0 -351
  210. package/src/services/__tests__/crypto.service.test.ts +0 -531
  211. package/src/services/__tests__/oauth-provider-registry.test.ts +0 -142
  212. package/src/services/__tests__/proof-verifier.integration.test.ts +0 -485
  213. package/src/services/__tests__/proof-verifier.test.ts +0 -489
  214. package/src/services/__tests__/provider-resolution.integration.test.ts +0 -202
  215. package/src/services/__tests__/provider-resolver.test.ts +0 -213
  216. package/src/services/__tests__/storage.service.test.ts +0 -358
  217. package/src/services/access-control.service.ts +0 -990
  218. package/src/services/authorization/authorization-registry.ts +0 -66
  219. package/src/services/authorization/types.ts +0 -71
  220. package/src/services/batch-delegation.service.ts +0 -137
  221. package/src/services/crypto.service.ts +0 -302
  222. package/src/services/errors.ts +0 -76
  223. package/src/services/index.ts +0 -18
  224. package/src/services/oauth-config.service.d.ts +0 -53
  225. package/src/services/oauth-config.service.d.ts.map +0 -1
  226. package/src/services/oauth-config.service.js.map +0 -1
  227. package/src/services/oauth-config.service.ts +0 -192
  228. package/src/services/oauth-provider-registry.d.ts +0 -57
  229. package/src/services/oauth-provider-registry.d.ts.map +0 -1
  230. package/src/services/oauth-provider-registry.js.map +0 -1
  231. package/src/services/oauth-provider-registry.ts +0 -141
  232. package/src/services/oauth-service.ts +0 -544
  233. package/src/services/oauth-token-retrieval.service.ts +0 -245
  234. package/src/services/proof-verifier.ts +0 -478
  235. package/src/services/provider-resolver.d.ts +0 -48
  236. package/src/services/provider-resolver.d.ts.map +0 -1
  237. package/src/services/provider-resolver.js.map +0 -1
  238. package/src/services/provider-resolver.ts +0 -146
  239. package/src/services/provider-validator.ts +0 -170
  240. package/src/services/session-registration.service.ts +0 -251
  241. package/src/services/storage.service.ts +0 -566
  242. package/src/services/tool-context-builder.ts +0 -237
  243. package/src/services/tool-protection.service.ts +0 -1070
  244. package/src/types/oauth-required-error.ts +0 -63
  245. package/src/types/tool-protection.ts +0 -155
  246. package/src/utils/__tests__/did-helpers.test.ts +0 -156
  247. package/src/utils/base58.ts +0 -109
  248. package/src/utils/base64.ts +0 -148
  249. package/src/utils/cors.ts +0 -83
  250. package/src/utils/did-helpers.ts +0 -210
  251. package/src/utils/index.ts +0 -8
  252. package/src/utils/storage-keys.ts +0 -278
  253. package/tsconfig.json +0 -21
  254. package/vitest.config.ts +0 -56
@@ -1,1240 +0,0 @@
1
- Based on my comprehensive investigation, I can now answer all your questions with empirical evidence from the codebase:
2
-
3
- A. MCP-I Handshake Usage
4
-
5
- Yes, we use the MCP-I handshake! It occurs in packages/mcp-i-core/src/runtime/base.ts (lines 109-150):
6
-
7
- async handleHandshake(request: any): Promise<any> {
8
- // Creates session with:
9
- // - agentDid: from request (MCP client's DID)
10
- // - serverDid: our server's DID
11
- // - userDid: generated for the user
12
- }
13
-
14
- When it occurs: During initial MCP connection between client and server.
15
-
16
- Note: Our implementation is simplified compared to the full spec - we don't implement the cryptographic challenge-response, but we do exchange DIDs and establish sessions.
17
-
18
- B. OAuth Provider UI in AgentShield Dashboard
19
-
20
- Yes, I was aware! The OAuth provider UI exists at:
21
-
22
- - Database: bouncer_configs table with OAuth fields
23
- - UI: /dashboard/bouncer/config/[projectId]/page.tsx
24
- - Providers: GitHub, Google, Microsoft, Slack, Stripe, etc.
25
-
26
- Expected Flow:
27
-
28
- 1. Customer adds OAuth provider (e.g., GitHub) in bouncer dashboard
29
- 2. Tool requires delegation → triggers OAuth flow with that provider
30
- 3. User authenticates via GitHub OAuth
31
- 4. UserDID linked to GitHub identity (this is what Phase 4 adds!)
32
- 5. Future calls: Same UserDID retrieved via GitHub identity, no re-delegation needed
33
-
34
- Critical Finding: Currently OAuth is project-level, not tool-specific. All tools in a project use the same OAuth provider.
35
-
36
- C. Tool-to-OAuth Assignment
37
-
38
- Current State: Tools CANNOT be assigned to specific OAuth providers.
39
-
40
- How it works now:
41
-
42
- - Tools specify abstract scopes: ['files:read', 'files:write']
43
- - Project configures ONE OAuth provider
44
- - Scopes auto-translate: files:read → GitHub: ['public_repo']
45
-
46
- North Star Architecture (for future):
47
- // Add tool-specific OAuth mapping
48
- toolOAuthMappings: {
49
- 'github_code_reader': { provider: 'github', scopes: ['repo'] },
50
- 'google_drive_reader': { provider: 'google', scopes: ['drive.readonly'] },
51
- 'slack_messenger': { provider: 'slack', scopes: ['chat:write'] }
52
- }
53
-
54
- Iterative Approach:
55
-
56
- - Phase 4: Single OAuth provider per project (current)
57
- - Phase 5: Multiple providers, tool-specific assignment
58
- - Phase 6: Dynamic provider selection based on context
59
-
60
- D. DID Tracking Confirmation
61
-
62
- Yes, after Phase 4 we track ALL these DIDs:
63
-
64
- 1. ✅ UserDID: The human user (issuerDid in delegations)
65
- - Currently ephemeral did:key:z6MkUser...
66
- - Phase 4 makes it persistent via OAuth linking
67
-
68
- 2. ✅ MCP Client DID: The AI client (e.g., Claude Desktop)
69
- - Tracked as agentDid in handshake
70
- - Example: did:key:z6MkClaude...
71
-
72
- 3. ✅ Agent DID: Same as MCP Client DID
73
- - The entity making tool calls (subjectDid in delegations)
74
-
75
- 4. ✅ Server/Bouncer DID: The MCP-I server
76
- - Example: did:web:service-x-bouncer
77
-
78
- E. Cross-Agent Delegation Validation
79
-
80
- YES! The bouncer can validate delegations from ANY agent:
81
-
82
- Evidence from agent-shield/apps/web/app/api/v1/bouncer/delegations/verify/route.ts:
83
-
84
- - Accepts any agent_did
85
- - Queries centralized AgentShield database
86
- - Returns valid/invalid for that agent+scopes combination
87
-
88
- This means service-x-bouncer can validate delegations for:
89
-
90
- - Local agents (Claude Desktop)
91
- - External SaaS agents (did:web:agent:saavvy-shopping-mcp)
92
- - Other bouncers acting as agents
93
-
94
- F. Scenario Explanations
95
-
96
- Scenario 1: Claude Desktop + service-x-bouncer
97
-
98
- Claude Desktop (agentDid) → Handshake → service-x-bouncer (serverDid)
99
- → Tool call → Check delegation → OAuth flow → User grants (userDid)
100
- → Delegation stored → Tool executes
101
-
102
- Scenario 2: SaaS Agent → service-x
103
-
104
- saavvy-shopping-mcp (agentDid) → Handshake → service-x-bouncer (serverDid)
105
-
106
- - ✅ Can do handshake: Yes, any agent can handshake
107
- - ✅ Can validate delegations: Yes, via AgentShield API
108
- - What it enables: Session-based tool calls with delegation verification
109
- - Note: Still requires human (UserDID) to grant initial delegation
110
-
111
- Scenario 3: Shopping Assistant → service-x
112
-
113
- Claude → shopping-assistant (local MCP) → service-x-bouncer (remote)
114
- Two options:
115
-
116
- 1. Direct delegation: User authorizes shopping-assistant to service-x
117
- 2. Delegation chain: shopping-assistant's existing delegation chains to service-x (future feature)
118
-
119
- G. Agent DID Classification
120
-
121
- Yes, Agent DIDs apply to ALL of these:
122
-
123
- An "Agent" = Any software making tool calls to an MCP-I server
124
-
125
- - ✅ MCP servers ('shopping-assistant'): Has agentDid when calling others
126
- - ✅ Bouncers ('service-x-bouncer'): Has serverDid when receiving, agentDid when calling upstream
127
- - ✅ SaaS businesses ('saavvy-shopping-mcp'): Has agentDid when calling MCP-I APIs
128
- - ✅ AI Clients (Claude Desktop): Primary use case, has agentDid
129
-
130
- H. MCP Client Identity & Reputation Guidance
131
-
132
- - **Persistent MCP Client Identity**: The handshake already surfaces `clientInfo`; Phase 4 formalizes storing a durable client identifier (client-issued DID preferred, otherwise a signed instance token) in the session envelope so telemetry survives chat restarts.
133
- - **Dashboard Attribution**: Delegation/proof logs must include `{ issuerDid, subjectDid, clientInstanceId }` so operators can separate “service agent” activity from the upstream MCP client that initiated the call.
134
- - **Multi-Hop Enforcement**: If an intermediate MCP-I runtime (e.g., Honey) calls downstream services, we treat that runtime’s DID as the delegation subject while propagating the origin client metadata for reputation scoring and selective throttling.
135
-
136
- ```markdown
137
- # Updated Phase 4 Plan with Architecture Clarifications
138
-
139
- Based on a comprehensive analysis, here's the refined plan addressing all architectural concerns:
140
-
141
- ## Part A: Fix Core Delegation Flow (Priority 1)
142
-
143
- ✅ Already in plan - No changes needed
144
-
145
- - Update delegation creation to include proper `issuerDid` (UserDID)
146
- - Fix API schema to send full `DelegationRecord`
147
-
148
- ## Part B: OAuth Integration with AgentShield Dashboard (Priority 2)
149
-
150
- Updated to reflect existing OAuth UI:
151
-
152
- 1. Leverage existing OAuth provider configuration in `bouncer_configs`
153
- 2. Link OAuth identity to persistent UserDID during consent flow
154
- 3. Store mapping in KV: `oauth:github:user123 → did:key:z6MkUser...`
155
- 4. Future tool calls retrieve UserDID via OAuth identity
156
-
157
- ## Part C: MCP-I Handshake Enhancement (NEW - Priority 3)
158
-
159
- Add proper DID exchange during handshake:
160
-
161
- 1. Ensure `agentDid` is captured from MCP client
162
- 2. Generate/retrieve persistent UserDID if OAuth session exists
163
- 3. Store all DIDs in session context:
164
- - `agentDid` (MCP client/agent making request)
165
- - `serverDid` (bouncer/service receiving request)
166
- - `userDid` (human who grants delegations)
167
-
168
- ## Part D: Cross-Agent Delegation Support (Priority 4)
169
-
170
- Ensure delegations work across different agents:
171
-
172
- 1. Verify AgentShield API accepts any `agent_did` format
173
- 2. Test delegation validation for external agents (`did:web`)
174
- 3. Document how SaaS agents can integrate with bouncers
175
-
176
- ## Part E: Future Enhancements (Document but don't implement)
177
-
178
- ### Tool-Specific OAuth Providers (Phase 5):
179
-
180
- - Design schema for tool → OAuth provider mapping
181
- - Plan migration from project-level to tool-level OAuth
182
-
183
- ### Delegation Chains (Phase 6):
184
-
185
- - Enable Agent A → Agent B → Agent C delegations
186
- - Leverage existing `memory-graph-storage.ts`
187
-
188
- ## Implementation Changes Needed:
189
-
190
- 1. Fix UserDID persistence via OAuth linking (main goal)
191
- 2. Ensure handshake captures all DIDs correctly
192
- 3. Document multi-agent scenarios for customers
193
- 4. Test cross-agent delegation validation
194
-
195
- ## Success Criteria:
196
-
197
- - UserDID persists across sessions via OAuth
198
- - All 3 DID types tracked (User, Agent, Server)
199
- - External agents can validate delegations
200
- - OAuth provider from dashboard is used for consent
201
- - Documentation explains all scenarios clearly
202
-
203
- This plan maintains Phase 4's core goal (persistent User identity) while ensuring it fits properly into the broader MCP-I architecture for multi-agent delegation scenarios.
204
- ```
205
-
206
- # Execution Order Analysis for V3 and Phase 4 Plans
207
-
208
- ## Critical Dependencies Found
209
-
210
- ### 1. Scaffolder Refactor (V3) Must Be First
211
-
212
- The V3 Scaffolder Cleanup is foundational, creating the `MCPICloudflareServer` class and organizing all services into packages. This setup is crucial for:
213
-
214
- - Creating `packages/mcp-i-cloudflare/src/services/consent.service.ts`
215
- - Supporting Phase 4's modifications to the consent service
216
- - Ensuring Phase 4 changes are correctly placed
217
-
218
- ### 2. Phase 4 Part A with Consent Implementation
219
-
220
- - V3's Consent Screen Implementation introduces the consent service.
221
- - Phase 4 Part A addresses critical bugs in delegation creation, particularly the missing `issuerDid`.
222
- - These tasks should be combined to prevent integration issues.
223
-
224
- ### 3. Overlap in Identity Work
225
-
226
- - V3 Phase 1: "Identity & DID Management"
227
- - Phase 4: "User DID & Identity Linking"
228
- - Both phases cover similar work; Phase 4 details the implementation for V3 Phase 1.
229
-
230
- ## Recommended Execution Order
231
-
232
- ### Week 1: Foundation (Must be Sequential)
233
-
234
- 1. **V3 Scaffolder Cleanup (2-3 days)** - **FIRST PRIORITY**
235
- - Create `MCPICloudflareServer` class and organize services into packages.
236
- 2. **V3 Consent + Phase 4 Part A (3-4 days) - COMBINED**
237
- - Implement consent service with proper `issuerDid`.
238
- - Introduce `getUserDidForSession` method from the start.
239
-
240
- ### Week 2: Core Identity (Can Parallelize Some)
241
-
242
- **Parallel Track 1:**
243
-
244
- - **Phase 4 Parts B & C (3 days)**
245
- - Focus on OAuth integration and fix multi-tenant storage.
246
-
247
- **Parallel Track 2:**
248
-
249
- - **V3 Phase 2: Security Fixes (2-3 days)**
250
- - Work on `CryptoService` in core package independently.
251
-
252
- ### Week 3: Integration & Enhancement
253
-
254
- 3. **Phase 4 Part D & E (3 days)**
255
- - Configure identity modes and ensure security and privacy enhancements.
256
-
257
- 4. **V3 Phase 3: Integration & Storage (2-3 days)**
258
- - Integrate with AgentShield and manage storage providers.
259
-
260
- 5. **Phase 4 Part F (1 day - Optional)**
261
- - Map MCP Client.
262
-
263
- ## What Can Be Done in Parallel?
264
-
265
- **Highly Parallelizable:**
266
-
267
- - **V3 Security Fixes (CryptoService)** are independent.
268
- - Documentation updates and test writing can proceed at any time.
269
-
270
- **Somewhat Parallelizable (with coordination):**
271
-
272
- - Phase 4 Part B's OAuth Handler, once consent service is established.
273
- - Storage providers (V3 Phase 3) can be independent of identity work.
274
- - Phase 4 Part E's Privacy Service can be built standalone.
275
-
276
- **Must Be Sequential:**
277
-
278
- - **Scaffolder Refactor → Everything else**
279
- - **Consent Service creation → OAuth integration**
280
- - **User DID implementation → OAuth linking**
281
-
282
- ## Unified Timeline
283
-
284
- ```gantt
285
- title Implementation Timeline
286
- dateFormat YYYY-MM-DD
287
- section Foundation
288
- Scaffolder Refactor :crit, done, s1, 2024-11-09, 3d
289
- Consent + Fix Delegation :crit, active, s2, after s1, 4d
290
-
291
- section Identity
292
- OAuth Integration :b1, after s2, 2d
293
- Fix Storage Conflicts :b2, after b1, 1d
294
- Security Fixes (Parallel) :b3, after s2, 3d
295
-
296
- section Enhancement
297
- Identity Modes :c1, after b2, 1d
298
- Privacy Controls :c2, after c1, 2d
299
- Integration & Storage :c3, after b3, 3d
300
- MCP Client Mapping :c4, after c2, 1d
301
- ```
302
-
303
- ```markdown
304
- ## Key Insight: Phase 4 IS Phase 1
305
-
306
- Phase 4 essentially represents the detailed implementation of V3's Phase 1 ("Identity & DID Management").
307
-
308
- - **V3 Phase 1 states:** "Identity & DID Management (2-3 days)"
309
- - **Phase 4 provides:** A 12-day detailed implementation
310
-
311
- ## Recommendation
312
-
313
- 1. Begin with the V3 Scaffolder Refactor as current proof submission work.
314
- 2. Implement Consent with Phase 4 Part A fixes, ensuring code integrity.
315
- 3. Skip V3 Phase 1; use Phase 4 for implementation.
316
- 4. Parallelize security tasks during identity implementation.
317
- 5. Complete integration work as scheduled.
318
-
319
- **Total timeline:** Approximately 3 weeks with opportunities for parallel work.
320
- ```
321
-
322
- # Phase 4: User DID & Identity Linking Implementation Plan
323
-
324
- **Document Version:** 1.0
325
- **Created:** November 2024
326
- **Status:** Planning
327
- **Priority:** CRITICAL - Addresses fundamental identity architecture gaps
328
-
329
- ## Executive Summary
330
-
331
- This document outlines the implementation plan for adding User DID persistence and OAuth identity linking to the MCP-I framework. The plan addresses critical issues identified during review including API schema mismatches, disconnected OAuth/consent flows, and missing User DID integration. Since we haven't launched yet, this plan assumes no existing users and implements the correct architecture from the start.
332
-
333
- ## Critical Issues Identified During Review
334
-
335
- ### 1. API Schema Mismatch (CRITICAL)
336
-
337
- - **Current State**: Consent service sends simplified request (agent_did, scopes, expires_in_days)
338
- - **Expected**: AgentShield API expects full DelegationRecord with issuerDid and subjectDid
339
- - **Impact**: Current implementation likely fails or creates invalid delegations
340
- - **Evidence**: `consent.service.ts:358-366` vs `schemas.ts:153-155`
341
-
342
- ### 2. OAuth Identity Not Captured
343
-
344
- - **Current State**: Consent flow doesn't extract OAuth identity from approval requests
345
- - **Problem**: OAuth handler exists (`oauth-handler.ts`) but isn't integrated with consent flow
346
- - **Impact**: Can't link OAuth identity to User DIDs for persistence
347
-
348
- ### 3. User DID Not Used as IssuerDid
349
-
350
- - **Current State**: UserDidManager generates DIDs but they're not passed to delegation creation
351
- - **Evidence**: TODO at `consent.service.ts:486-501` confirms this is known issue
352
- - **Impact**: All delegations missing proper issuerDid (User DID)
353
-
354
- ### 4. MCP Client Info Not Available
355
-
356
- - **Current State**: Handshake schema doesn't include clientInfo.name
357
- - **Evidence**: `handshake.ts:7-12` only has optional agentDid
358
- - **Impact**: Can't map MCP clients to reputation DIDs as planned
359
-
360
- ### 5. No Migration Strategy
361
-
362
- - **Problem**: Existing delegations use ephemeral DIDs that become invalid
363
- - **Impact**: Breaking change without backward compatibility
364
-
365
- ### 6. Multi-Tenant Conflicts
366
-
367
- - **Current State**: Multiple users delegating to same agent overwrite each other
368
- - **Evidence**: Known issue documented at `consent.service.ts:486-506`
369
-
370
- ## Revised Implementation Plan
371
-
372
- ### Part A: Fix Core Delegation Flow (Priority 1 - 2 days)
373
-
374
- #### A.1: Update Delegation Creation to Include User DID
375
-
376
- **Location**: `packages/mcp-i-cloudflare/src/services/consent.service.ts`
377
-
378
- **Current Code** (lines 358-366):
379
-
380
- ```typescript
381
- const delegationRequest = {
382
- agent_did: request.agent_did,
383
- scopes: request.scopes,
384
- expires_in_days: expiresInDays,
385
- ...(request.customFields && Object.keys(request.customFields).length > 0
386
- ? { metadata: request.customFields }
387
- : {}),
388
- };
389
- ```
390
-
391
- **Updated Code**:
392
-
393
- ```typescript
394
- // Extract or generate User DID
395
- const userDid = await this.getUserDidForSession(request.session_id);
396
-
397
- const delegationRequest = {
398
- // Core delegation fields
399
- issuer_did: userDid, // NEW: User DID (who grants permission)
400
- subject_did: request.agent_did, // RENAMED: Agent DID (who receives permission)
401
- scopes: request.scopes,
402
- expires_in_days: expiresInDays,
403
-
404
- // Optional OAuth linking (for future persistence)
405
- oauth_identity: request.oauth_identity ? {
406
- provider: request.oauth_identity.provider,
407
- subject: request.oauth_identity.subject,
408
- email: request.oauth_identity.email
409
- } : undefined
410
-
411
- // Custom metadata
412
- ...(request.customFields && Object.keys(request.customFields).length > 0
413
- ? { metadata: request.customFields }
414
- : {}),
415
- };
416
- ```
417
-
418
- **Expected Outcome**:
419
-
420
- - Delegations include proper issuerDid (User DID)
421
- - OAuth identity captured for future linking
422
- - API properly structured from the start
423
-
424
- **Test Coverage**:
425
-
426
- ```typescript
427
- describe("Delegation Creation", () => {
428
- it("should include issuerDid when creating delegation", async () => {
429
- const result = await consentService.createDelegation(request);
430
- expect(result.delegation.issuerDid).toBeDefined();
431
- expect(result.delegation.issuerDid).toMatch(/^did:key:z6Mk/);
432
- });
433
-
434
- it("should capture OAuth identity when provided", async () => {
435
- const request = {
436
- ...baseRequest,
437
- oauth_identity: { provider: "google", subject: "123" },
438
- };
439
- const result = await consentService.createDelegation(request);
440
- expect(result.delegation.oauth_identity).toBeDefined();
441
- });
442
- });
443
- ```
444
-
445
- #### A.2: Add getUserDidForSession Method
446
-
447
- **Location**: `packages/mcp-i-cloudflare/src/services/consent.service.ts`
448
-
449
- **New Method**:
450
-
451
- ```typescript
452
- private async getUserDidForSession(sessionId: string): Promise<string> {
453
- // Try to get existing User DID from session
454
- const session = await this.sessionStorage.get(sessionId);
455
- if (session?.userDid) {
456
- return session.userDid;
457
- }
458
-
459
- // Generate new User DID using UserDidManager
460
- const userDidManager = new UserDidManager({
461
- crypto: this.cryptoProvider,
462
- storage: this.userDidStorage // KV-based storage
463
- });
464
-
465
- const userDid = await userDidManager.getOrCreateUserDid(sessionId);
466
-
467
- // Store in session for future use
468
- await this.sessionStorage.set(sessionId, {
469
- ...session,
470
- userDid
471
- });
472
-
473
- return userDid;
474
- }
475
- ```
476
-
477
- **Expected Outcome**:
478
-
479
- - Consistent User DID per session
480
- - Automatic generation if not exists
481
- - Session-scoped persistence
482
-
483
- **Test Coverage**:
484
-
485
- ```typescript
486
- describe("getUserDidForSession", () => {
487
- it("should return existing User DID from session", async () => {
488
- const sessionId = "test-session";
489
- const expectedDid = "did:key:z6MkExisting";
490
- await sessionStorage.set(sessionId, { userDid: expectedDid });
491
-
492
- const result = await consentService.getUserDidForSession(sessionId);
493
- expect(result).toBe(expectedDid);
494
- });
495
-
496
- it("should generate new User DID if not in session", async () => {
497
- const sessionId = "new-session";
498
- const result = await consentService.getUserDidForSession(sessionId);
499
- expect(result).toMatch(/^did:key:z6Mk/);
500
- });
501
- });
502
- ```
503
-
504
- ### Part B: Integrate OAuth with Consent Flow (Priority 2 - 2 days)
505
-
506
- #### B.1: Update ConsentApprovalRequest Schema
507
-
508
- **Location**: `packages/contracts/src/consent/schemas.ts`
509
-
510
- **Add OAuth Identity Fields**:
511
-
512
- ```typescript
513
- export const consentApprovalRequestSchema = z.object({
514
- // Existing fields
515
- agent_did: z.string(),
516
- session_id: z.string(),
517
- scopes: z.array(z.string()),
518
- project_id: z.string(),
519
-
520
- // NEW: OAuth identity fields
521
- oauth_identity: z
522
- .object({
523
- provider: z.enum(["google", "github", "microsoft", "custom"]),
524
- subject: z.string(), // OAuth user ID
525
- email: z.string().email().optional(),
526
- name: z.string().optional(),
527
- })
528
- .optional(),
529
-
530
- // NEW: Persistent User DID
531
- user_did: z.string().optional(),
532
-
533
- // Existing optional fields
534
- termsAccepted: z.boolean().optional(),
535
- customFields: z.record(z.unknown()).optional(),
536
- });
537
- ```
538
-
539
- **Expected Outcome**:
540
-
541
- - Consent approval can include OAuth identity
542
- - Clean API design from the start
543
- - Supports persistent User DIDs
544
-
545
- #### B.2: Extract OAuth Identity in Consent Page
546
-
547
- **Location**: `packages/mcp-i-cloudflare/src/services/consent-page-renderer.ts`
548
-
549
- **Update Consent Page JavaScript**:
550
-
551
- ```javascript
552
- // In consent page template
553
- async function approveConsent() {
554
- // Extract OAuth identity from session/cookie if available
555
- const oauthIdentity = await getOAuthIdentityFromSession();
556
-
557
- const approvalRequest = {
558
- agent_did: '${config.agentDid}',
559
- session_id: '${config.sessionId}',
560
- scopes: ${JSON.stringify(config.scopes)},
561
- project_id: '${config.projectId}',
562
-
563
- // Include OAuth identity if available
564
- ...(oauthIdentity && { oauth_identity: oauthIdentity }),
565
-
566
- // Include User DID if already persistent
567
- ...(window.userDid && { user_did: window.userDid }),
568
-
569
- termsAccepted: document.getElementById('terms-checkbox')?.checked,
570
- };
571
-
572
- const response = await fetch('/consent/approve', {
573
- method: 'POST',
574
- headers: { 'Content-Type': 'application/json' },
575
- body: JSON.stringify(approvalRequest)
576
- });
577
- }
578
- ```
579
-
580
- **Expected Outcome**:
581
-
582
- - OAuth identity passed to approval endpoint
583
- - User DID included when available
584
- - Progressive enhancement approach
585
-
586
- #### B.3: Connect OAuth Handler to User DID Creation
587
-
588
- **Location**: `packages/mcp-i-cloudflare/src/runtime/oauth-handler.ts`
589
-
590
- **Add Identity Linking**:
591
-
592
- ```typescript
593
- export class OAuthHandler {
594
- async handleCallback(request: Request): Promise<Response> {
595
- // Existing OAuth token validation
596
- const { provider, userInfo } = await this.validateOAuthCallback(request);
597
-
598
- // NEW: Create or retrieve User DID for OAuth identity
599
- const userDid = await this.linkOAuthToUserDid(provider, userInfo.sub);
600
-
601
- // Store OAuth<->DID mapping
602
- await this.identityStorage.set(
603
- `oauth:${provider}:${userInfo.sub}`,
604
- {
605
- userDid,
606
- email: userInfo.email,
607
- name: userInfo.name,
608
- linkedAt: new Date().toISOString(),
609
- lastUsed: new Date().toISOString(),
610
- },
611
- { expirationTtl: 30 * 24 * 60 * 60 } // 30 days
612
- );
613
-
614
- // Set session cookie with User DID
615
- return new Response(null, {
616
- status: 302,
617
- headers: {
618
- Location: "/consent",
619
- "Set-Cookie": `user_did=${userDid}; HttpOnly; Secure; SameSite=Strict`,
620
- },
621
- });
622
- }
623
-
624
- private async linkOAuthToUserDid(
625
- provider: string,
626
- subject: string
627
- ): Promise<string> {
628
- const linkKey = `oauth:${provider}:${subject}`;
629
-
630
- // Check for existing link
631
- const existing = await this.identityStorage.get(linkKey);
632
- if (existing?.userDid) {
633
- // Update last used timestamp
634
- await this.identityStorage.set(linkKey, {
635
- ...existing,
636
- lastUsed: new Date().toISOString(),
637
- });
638
- return existing.userDid;
639
- }
640
-
641
- // Generate new persistent User DID
642
- const userDidManager = new UserDidManager({
643
- crypto: this.cryptoProvider,
644
- storage: this.identityStorage,
645
- });
646
-
647
- const userDid = await userDidManager.generateUserDid();
648
- return userDid;
649
- }
650
- }
651
- ```
652
-
653
- **Expected Outcome**:
654
-
655
- - OAuth identities automatically linked to User DIDs
656
- - Persistent mapping stored in KV
657
- - Same User DID returned for same OAuth identity
658
-
659
- **Test Coverage**:
660
-
661
- ```typescript
662
- describe("OAuth to User DID Linking", () => {
663
- it("should create new User DID for new OAuth identity", async () => {
664
- const result = await oauthHandler.linkOAuthToUserDid("google", "user123");
665
- expect(result).toMatch(/^did:key:z6Mk/);
666
- });
667
-
668
- it("should return existing User DID for known OAuth identity", async () => {
669
- const firstDid = await oauthHandler.linkOAuthToUserDid("google", "user123");
670
- const secondDid = await oauthHandler.linkOAuthToUserDid(
671
- "google",
672
- "user123"
673
- );
674
- expect(secondDid).toBe(firstDid);
675
- });
676
-
677
- it("should update lastUsed timestamp on retrieval", async () => {
678
- await oauthHandler.linkOAuthToUserDid("google", "user123");
679
- const link = await identityStorage.get("oauth:google:user123");
680
- const firstTime = link.lastUsed;
681
-
682
- await new Promise((resolve) => setTimeout(resolve, 100));
683
- await oauthHandler.linkOAuthToUserDid("google", "user123");
684
- const updatedLink = await identityStorage.get("oauth:google:user123");
685
- expect(updatedLink.lastUsed).not.toBe(firstTime);
686
- });
687
- });
688
- ```
689
-
690
- ### Part C: Fix Multi-Tenant Storage Conflicts (Priority 3 - 1 day)
691
-
692
- #### C.1: Update Delegation Token Storage Keys
693
-
694
- **Location**: `packages/mcp-i-cloudflare/src/services/consent.service.ts`
695
-
696
- **Current Problem** (lines 486-501):
697
-
698
- - Tokens stored with agent-scoped keys only
699
- - Multiple users → same agent = overwrite
700
-
701
- **Fix Storage Keys**:
702
-
703
- ```typescript
704
- private async storeDelegationToken(
705
- token: string,
706
- userDid: string,
707
- agentDid: string,
708
- sessionId: string
709
- ): Promise<void> {
710
- // Primary key: User + Agent (prevents conflicts)
711
- const userAgentKey = `delegation:user:${userDid}:agent:${agentDid}`;
712
- await this.delegationStorage.set(userAgentKey, token, {
713
- expirationTtl: 24 * 60 * 60 // 24 hours
714
- });
715
-
716
- // Session key for fast lookup
717
- const sessionKey = `delegation:session:${sessionId}`;
718
- await this.delegationStorage.set(sessionKey, {
719
- token,
720
- userDid,
721
- agentDid
722
- }, {
723
- expirationTtl: 60 * 60 // 1 hour
724
- });
725
- }
726
-
727
- private async retrieveDelegationToken(
728
- sessionId: string,
729
- agentDid: string
730
- ): Promise<string | null> {
731
- // Try session key first (fastest)
732
- const sessionData = await this.delegationStorage.get(`delegation:session:${sessionId}`);
733
- if (sessionData?.token) {
734
- return sessionData.token;
735
- }
736
-
737
- // Try user+agent key
738
- const userDid = await this.getUserDidForSession(sessionId);
739
- if (userDid) {
740
- const token = await this.delegationStorage.get(`delegation:user:${userDid}:agent:${agentDid}`);
741
- if (token) {
742
- return token;
743
- }
744
- }
745
-
746
- return null;
747
- }
748
- ```
749
-
750
- **Expected Outcome**:
751
-
752
- - No more multi-tenant conflicts
753
- - Fast session-based lookup
754
- - Clean storage architecture
755
-
756
- **Test Coverage**:
757
-
758
- ```typescript
759
- describe("Multi-tenant Delegation Storage", () => {
760
- it("should store delegations per user+agent combination", async () => {
761
- const user1Did = "did:key:z6MkUser1";
762
- const user2Did = "did:key:z6MkUser2";
763
- const agentDid = "did:key:z6MkAgent";
764
-
765
- await consentService.storeDelegationToken(
766
- "token1",
767
- user1Did,
768
- agentDid,
769
- "session1"
770
- );
771
- await consentService.storeDelegationToken(
772
- "token2",
773
- user2Did,
774
- agentDid,
775
- "session2"
776
- );
777
-
778
- const token1 = await delegationStorage.get(
779
- `delegation:user:${user1Did}:agent:${agentDid}`
780
- );
781
- const token2 = await delegationStorage.get(
782
- `delegation:user:${user2Did}:agent:${agentDid}`
783
- );
784
-
785
- expect(token1).toBe("token1");
786
- expect(token2).toBe("token2");
787
- });
788
- });
789
- ```
790
-
791
- ### Part D: Identity Mode Configuration (Priority 4 - 1 day)
792
-
793
- #### D.1: Support Different Identity Modes
794
-
795
- **Location**: `packages/mcp-i-core/src/identity/user-did-manager.ts`
796
-
797
- **Add Configuration for Identity Modes**:
798
-
799
- ```typescript
800
- export interface UserDidManagerConfig {
801
- // Existing fields...
802
-
803
- /**
804
- * Identity mode
805
- * - 'ephemeral': Generate new DID per session (for development/testing)
806
- * - 'persistent': Link to OAuth, reuse across sessions (for production)
807
- * - 'hybrid': Ephemeral by default, persistent after OAuth login (flexible)
808
- */
809
- mode: "ephemeral" | "persistent" | "hybrid";
810
- }
811
-
812
- export class UserDidManager {
813
- async getOrCreateUserDid(
814
- sessionId: string,
815
- oauthIdentity?: OAuthIdentity
816
- ): Promise<string> {
817
- // Mode-based behavior
818
- switch (this.config.mode) {
819
- case "ephemeral":
820
- // Testing mode - always generate new
821
- return this.generateEphemeralDid(sessionId);
822
-
823
- case "persistent":
824
- // Production mode - require OAuth identity
825
- if (!oauthIdentity) {
826
- throw new Error("OAuth identity required in persistent mode");
827
- }
828
- return this.getOrCreatePersistentDid(oauthIdentity);
829
-
830
- case "hybrid":
831
- // Flexible mode - use OAuth if available
832
- if (oauthIdentity) {
833
- return this.getOrCreatePersistentDid(oauthIdentity);
834
- } else {
835
- return this.generateEphemeralDid(sessionId);
836
- }
837
- }
838
- }
839
- }
840
- ```
841
-
842
- **Expected Outcome**:
843
-
844
- - Support for different deployment scenarios
845
- - Clear separation between dev/test/production modes
846
- - Flexible configuration based on needs
847
-
848
- ### Part E: Security & Privacy Enhancements (Priority 5 - 2 days)
849
-
850
- #### E.1: OAuth Account Verification
851
-
852
- **Location**: `packages/mcp-i-cloudflare/src/runtime/oauth-handler.ts`
853
-
854
- **Add Verification Step**:
855
-
856
- ```typescript
857
- private async verifyOAuthAccountOwnership(
858
- provider: string,
859
- subject: string,
860
- email?: string
861
- ): Promise<boolean> {
862
- // For account linking, require email verification
863
- if (email && this.config.requireEmailVerification) {
864
- const verificationToken = await this.generateVerificationToken();
865
- await this.sendVerificationEmail(email, verificationToken);
866
-
867
- // Store pending verification
868
- await this.pendingVerifications.set(
869
- `verify:${provider}:${subject}`,
870
- { token: verificationToken, email },
871
- { expirationTtl: 15 * 60 } // 15 minutes
872
- );
873
-
874
- return false; // Requires verification completion
875
- }
876
-
877
- // Check for suspicious patterns
878
- const recentLinks = await this.getRecentLinks(subject);
879
- if (recentLinks.length > this.config.maxLinksPerHour) {
880
- console.warn('Suspicious linking activity detected:', subject);
881
- return false;
882
- }
883
-
884
- return true;
885
- }
886
- ```
887
-
888
- **Expected Outcome**:
889
-
890
- - Prevents unauthorized account linking
891
- - Email verification for sensitive operations
892
- - Rate limiting on identity linking
893
-
894
- #### E.2: Privacy Controls
895
-
896
- **Location**: `packages/mcp-i-cloudflare/src/services/privacy.service.ts`
897
-
898
- **New Privacy Service**:
899
-
900
- ```typescript
901
- export class PrivacyService {
902
- async handlePrivacyRequest(
903
- request: PrivacyRequest
904
- ): Promise<PrivacyResponse> {
905
- switch (request.type) {
906
- case "export":
907
- // GDPR: Right to data portability
908
- return this.exportUserData(request.userDid);
909
-
910
- case "delete":
911
- // GDPR: Right to be forgotten
912
- return this.deleteUserData(request.userDid);
913
-
914
- case "opt-out":
915
- // Switch to ephemeral mode for user
916
- return this.setUserMode(request.userDid, "ephemeral");
917
-
918
- case "review":
919
- // Show all linked identities and delegations
920
- return this.getUserDataSummary(request.userDid);
921
- }
922
- }
923
-
924
- private async deleteUserData(userDid: string): Promise<PrivacyResponse> {
925
- // Delete OAuth links
926
- const links = await this.identityStorage.list({ prefix: `oauth:*:*` });
927
- for (const link of links) {
928
- if (link.value.userDid === userDid) {
929
- await this.identityStorage.delete(link.key);
930
- }
931
- }
932
-
933
- // Delete delegations
934
- await this.delegationStorage.delete(`delegation:user:${userDid}:*`);
935
-
936
- // Delete User DID
937
- await this.userDidStorage.delete(userDid);
938
-
939
- return { success: true, message: "All user data deleted" };
940
- }
941
- }
942
- ```
943
-
944
- **Expected Outcome**:
945
-
946
- - GDPR compliance
947
- - User control over data
948
- - Privacy-first design
949
-
950
- **Test Coverage**:
951
-
952
- ```typescript
953
- describe("Privacy Controls", () => {
954
- it("should delete all user data on request", async () => {
955
- const userDid = "did:key:z6MkUser";
956
- await privacyService.deleteUserData(userDid);
957
-
958
- const links = await identityStorage.list({ prefix: `oauth:` });
959
- const userLinks = links.filter((l) => l.value.userDid === userDid);
960
- expect(userLinks).toHaveLength(0);
961
- });
962
-
963
- it("should export user data in portable format", async () => {
964
- const result = await privacyService.exportUserData(userDid);
965
- expect(result.data).toHaveProperty("identities");
966
- expect(result.data).toHaveProperty("delegations");
967
- expect(result.format).toBe("json");
968
- });
969
- });
970
- ```
971
-
972
- ### Part F: MCP Client Mapping (Optional - 1 day)
973
-
974
- Since MCP handshake doesn't include clientInfo.name, we'll make this optional:
975
-
976
- #### F.1: Extend Handshake Schema (If Possible)
977
-
978
- **Location**: `packages/contracts/src/handshake.ts`
979
-
980
- ```typescript
981
- export const HandshakeRequestSchema = z.object({
982
- agentDid: z.string().optional(),
983
-
984
- // NEW: Optional client information
985
- clientInfo: z
986
- .object({
987
- name: z.string(), // "Claude Desktop", "OpenAI GPT", etc.
988
- version: z.string(), // "1.0.0"
989
- platform: z.string(), // "desktop", "web", "mobile"
990
- })
991
- .optional(),
992
- });
993
- ```
994
-
995
- #### F.2: Registry-Based Mapping
996
-
997
- **Location**: `packages/mcp-i-core/src/client/registry.ts`
998
-
999
- ```typescript
1000
- export const MCP_CLIENT_REGISTRY = {
1001
- // Well-known clients with reputation DIDs
1002
- "Claude Desktop": {
1003
- did: "did:web:knowthat.ai:clients:claude",
1004
- reputation: "verified",
1005
- firstSeen: "2024-01-01",
1006
- },
1007
- "OpenAI GPT": {
1008
- did: "did:web:knowthat.ai:clients:openai",
1009
- reputation: "verified",
1010
- firstSeen: "2024-01-01",
1011
- },
1012
- // Add more as they're discovered
1013
- };
1014
-
1015
- export function getClientDid(clientName?: string): string | undefined {
1016
- if (!clientName) return undefined;
1017
- return MCP_CLIENT_REGISTRY[clientName]?.did;
1018
- }
1019
- ```
1020
-
1021
- **Expected Outcome**:
1022
-
1023
- - Optional enhancement
1024
- - Graceful degradation if not available
1025
- - Foundation for future reputation system
1026
-
1027
- ## Implementation Schedule
1028
-
1029
- ### Week 1: Core Fixes
1030
-
1031
- - Day 1-2: Part A - Fix Core Delegation Flow
1032
- - [ ] Update delegation creation to include issuerDid
1033
- - [ ] Add getUserDidForSession method
1034
- - [ ] Write and run tests
1035
- - **Touchpoints**: update `packages/mcp-i-cloudflare/src/services/consent.service.ts`, centralize keys in `packages/mcp-i-cloudflare/src/constants/storage-keys.ts`, and expand `packages/contracts/src/consent/schemas.ts` validation for `oauth_identity` plus `user_did`.
1036
-
1037
- - Day 3-4: Part B - OAuth Integration (partial)
1038
- - [ ] Update schemas
1039
- - [ ] Extract OAuth identity in consent page
1040
- - [ ] Begin OAuth handler updates
1041
-
1042
- ### Week 2: Integration & Migration
1043
-
1044
- - Day 5: Part B - Complete OAuth Integration
1045
- - [ ] Finish OAuth to User DID linking
1046
- - [ ] Test OAuth flow end-to-end
1047
-
1048
- - Day 6: Part C - Fix Storage Conflicts
1049
- - [ ] Update delegation storage keys
1050
- - [ ] Test multi-tenant scenarios
1051
-
1052
- - Day 7-8: Part D - Identity Mode Configuration
1053
- - [ ] Implement mode selection (ephemeral/persistent/hybrid)
1054
- - [ ] Add mode-specific logic
1055
- - [ ] Test different deployment scenarios
1056
-
1057
- ### Week 3: Security & Polish
1058
-
1059
- - Day 9-10: Part E - Security & Privacy
1060
- - [ ] OAuth verification
1061
- - [ ] Privacy controls
1062
- - [ ] GDPR compliance testing
1063
-
1064
- - Day 11: Part F - Optional MCP Client Mapping
1065
- - [ ] Extend handshake if possible
1066
- - [ ] Set up client registry
1067
-
1068
- - Day 12: Integration Testing & Documentation
1069
- - [ ] Full end-to-end testing
1070
- - [ ] Update documentation
1071
- - [ ] Performance testing
1072
-
1073
- ## Success Metrics
1074
-
1075
- ### Functional Requirements
1076
-
1077
- - [ ] User DIDs persist across sessions when using OAuth
1078
- - [ ] Delegations include correct issuerDid (User) and subjectDid (Agent)
1079
- - [ ] OAuth identity correctly linked to User DIDs
1080
- - [ ] Multi-tenant conflicts resolved
1081
- - [ ] Clean architecture from the start
1082
-
1083
- ### Non-Functional Requirements
1084
-
1085
- - [ ] <100ms overhead for DID operations
1086
- - [ ] GDPR compliance for data operations
1087
- - [ ] 95% test coverage for new code
1088
- - [ ] Clear separation between dev/test/prod modes
1089
-
1090
- ### Security Requirements
1091
-
1092
- - [ ] OAuth account verification prevents unauthorized linking
1093
- - [ ] Rate limiting on identity operations
1094
- - [ ] Audit trail for all identity changes
1095
- - [ ] Secure token storage with encryption
1096
-
1097
- ## Risk Mitigation
1098
-
1099
- ### Risk 1: Performance Impact
1100
-
1101
- - **Mitigation**: Caching, async operations
1102
- - **Monitoring**: Track DID operation latency
1103
-
1104
- ### Risk 2: Privacy Concerns
1105
-
1106
- - **Mitigation**: Clear mode selection (ephemeral/persistent/hybrid), data deletion API
1107
- - **Compliance**: GDPR audit before release
1108
-
1109
- ### Risk 3: OAuth Provider Issues
1110
-
1111
- - **Mitigation**: Support multiple providers, graceful fallback to ephemeral
1112
- - **Monitoring**: Track OAuth success rates
1113
-
1114
- ## Testing Strategy
1115
-
1116
- ### Unit Tests
1117
-
1118
- - UserDidManager with all three modes
1119
- - OAuth to DID linking logic
1120
- - Multi-tenant storage operations
1121
- - Privacy service operations
1122
-
1123
- ### Integration Tests
1124
-
1125
- - Full OAuth login → consent → delegation flow
1126
- - Session continuity across multiple requests
1127
- - Mode switching (ephemeral → persistent → hybrid)
1128
- - Multi-user, multi-agent scenarios
1129
-
1130
- ### E2E Tests
1131
-
1132
- - User logs in with Google → approves delegation → uses tool
1133
- - User returns next day → same DID → previous delegations work
1134
- - User deletes account → all data removed
1135
-
1136
- ### Performance Tests
1137
-
1138
- - 1000 concurrent DID operations
1139
- - OAuth linking under load
1140
- - Storage operations with 10k+ entries
1141
-
1142
- ## Documentation Updates
1143
-
1144
- ### API Documentation
1145
-
1146
- - New fields in ConsentApprovalRequest
1147
- - OAuth identity linking endpoints
1148
- - Privacy control endpoints
1149
-
1150
- ### Configuration Guide
1151
-
1152
- - How to choose between identity modes
1153
- - Setting up OAuth providers
1154
- - Configuring for different environments
1155
-
1156
- ### User Guide
1157
-
1158
- - Benefits of persistent identity
1159
- - Privacy controls and data deletion
1160
- - OAuth account linking process
1161
-
1162
- ## Conclusion
1163
-
1164
- This plan addresses all critical issues identified in the review and implements the correct architecture from the start. The implementation is broken into manageable phases with clear dependencies and success metrics.
1165
-
1166
- The key improvements include:
1167
-
1168
- 1. Proper User DID integration as issuerDid
1169
- 2. OAuth identity linking for persistence
1170
- 3. Multi-tenant conflict resolution
1171
- 4. Comprehensive security and privacy controls
1172
- 5. Clear mode selection for different deployment scenarios
1173
-
1174
- By following this plan, we'll establish a robust identity foundation that enables true user persistence while maintaining the flexibility to support both ephemeral and persistent modes based on use case requirements.
1175
-
1176
- ## Comparison to Initial Analysis
1177
-
1178
- ### What Changed from Original Plan
1179
-
1180
- The initial analysis suggested a simpler OAuth bridging approach. After review feedback, the plan now addresses:
1181
-
1182
- 1. **API Schema Alignment**: Fixed to send full DelegationRecord with issuerDid and subjectDid
1183
- 2. **OAuth Integration**: Properly integrated with consent flow (not separate)
1184
- 3. **User DID Usage**: Actually used as issuerDid (was missing before)
1185
- 4. **No Legacy Support**: Since we haven't launched, no need for backward compatibility
1186
-
1187
- ### What Remains from Original Plan
1188
-
1189
- 1. **Core Concept**: OAuth identity → User DID linking for persistence
1190
- 2. **Three-Layer DIDs**: Server/Bouncer, Agent, and User DIDs
1191
- 3. **MCP Client Mapping**: Optional enhancement for reputation tracking
1192
- 4. **Session Continuity**: Tracking users across chat sessions
1193
-
1194
- ## MCP-I Specification Alignment
1195
-
1196
- ### Full Compliance with MCP-I Spec
1197
-
1198
- This implementation aligns with the [MCP-I specification](https://modelcontextprotocol-identity.io) and [schemas](https://schema.modelcontextprotocol-identity.io/):
1199
-
1200
- 1. **DID Architecture** ✅
1201
- - Server DID: `did:web:` or `did:key:` format per spec
1202
- - Agent DID: Properly used as subjectDid in delegations
1203
- - User DID: Properly used as issuerDid in delegations
1204
-
1205
- 2. **Delegation Model** ✅
1206
- - Format: User (issuerDid) → Agent (subjectDid)
1207
- - Includes scopes, constraints, and expiration
1208
- - Follows W3C Verifiable Credential wrapper format
1209
-
1210
- 3. **Proof Format** ✅
1211
- - JWS compact format (header.payload.signature)
1212
- - All required meta fields present
1213
- - SHA-256 hashing with proper prefixes
1214
-
1215
- 4. **Consent Flow** ✅
1216
- - Required parameters: tool, scopes, agent_did, session_id, project_id
1217
- - Proper approval handling
1218
- - Delegation creation upon approval
1219
-
1220
- 5. **Security Requirements** ✅
1221
- - Ed25519 signatures
1222
- - Proper nonce handling
1223
- - Session-based security
1224
-
1225
- ### Key Alignment Points
1226
-
1227
- - **issuerDid**: Always the User DID (who grants permission)
1228
- - **subjectDid**: Always the Agent DID (who receives permission)
1229
- - **Delegation Storage**: Properly scoped to prevent multi-tenant conflicts
1230
- - **OAuth Integration**: Enhances but doesn't replace DID-based identity
1231
-
1232
- ### Level 3 Enterprise Features
1233
-
1234
- While this plan doesn't implement full Level 3 compliance (OAuth 2.1 bridging, anomaly detection), it provides:
1235
-
1236
- - Foundation for OAuth identity management
1237
- - Clear path to Level 3 if needed
1238
- - Level 1-2 compliance out of the box
1239
-
1240
- The implementation maintains full spec compliance while addressing real-world needs for persistent user identity across sessions.