@kya-os/mcp-i-core 1.2.3-canary.7 → 1.3.1

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 (225) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/.turbo/turbo-build.log +4 -0
  3. package/.turbo/turbo-test.log +2979 -0
  4. package/COMPLIANCE_IMPROVEMENT_REPORT.md +483 -0
  5. package/Composer 3.md +615 -0
  6. package/GPT-5.md +1169 -0
  7. package/OPUS-plan.md +352 -0
  8. package/PHASE_3_AND_4.1_SUMMARY.md +585 -0
  9. package/PHASE_3_SUMMARY.md +317 -0
  10. package/PHASE_4.1.3_SUMMARY.md +428 -0
  11. package/PHASE_4.1_COMPLETE.md +525 -0
  12. package/PHASE_4_USER_DID_IDENTITY_LINKING_PLAN.md +1240 -0
  13. package/SCHEMA_COMPLIANCE_REPORT.md +275 -0
  14. package/TEST_PLAN.md +571 -0
  15. package/coverage/coverage-final.json +57 -0
  16. package/dist/__tests__/utils/mock-providers.d.ts +1 -2
  17. package/dist/__tests__/utils/mock-providers.d.ts.map +1 -1
  18. package/dist/__tests__/utils/mock-providers.js.map +1 -1
  19. package/dist/cache/oauth-config-cache.d.ts +69 -0
  20. package/dist/cache/oauth-config-cache.d.ts.map +1 -0
  21. package/dist/cache/oauth-config-cache.js +76 -0
  22. package/dist/cache/oauth-config-cache.js.map +1 -0
  23. package/dist/identity/idp-token-resolver.d.ts +53 -0
  24. package/dist/identity/idp-token-resolver.d.ts.map +1 -0
  25. package/dist/identity/idp-token-resolver.js +108 -0
  26. package/dist/identity/idp-token-resolver.js.map +1 -0
  27. package/dist/identity/idp-token-storage.interface.d.ts +42 -0
  28. package/dist/identity/idp-token-storage.interface.d.ts.map +1 -0
  29. package/dist/identity/idp-token-storage.interface.js +12 -0
  30. package/dist/identity/idp-token-storage.interface.js.map +1 -0
  31. package/dist/identity/user-did-manager.d.ts +39 -1
  32. package/dist/identity/user-did-manager.d.ts.map +1 -1
  33. package/dist/identity/user-did-manager.js +69 -3
  34. package/dist/identity/user-did-manager.js.map +1 -1
  35. package/dist/index.d.ts +22 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +39 -1
  38. package/dist/index.js.map +1 -1
  39. package/dist/runtime/audit-logger.d.ts +37 -0
  40. package/dist/runtime/audit-logger.d.ts.map +1 -0
  41. package/dist/runtime/audit-logger.js +9 -0
  42. package/dist/runtime/audit-logger.js.map +1 -0
  43. package/dist/runtime/base.d.ts +58 -2
  44. package/dist/runtime/base.d.ts.map +1 -1
  45. package/dist/runtime/base.js +266 -11
  46. package/dist/runtime/base.js.map +1 -1
  47. package/dist/services/access-control.service.d.ts.map +1 -1
  48. package/dist/services/access-control.service.js +200 -35
  49. package/dist/services/access-control.service.js.map +1 -1
  50. package/dist/services/authorization/authorization-registry.d.ts +29 -0
  51. package/dist/services/authorization/authorization-registry.d.ts.map +1 -0
  52. package/dist/services/authorization/authorization-registry.js +57 -0
  53. package/dist/services/authorization/authorization-registry.js.map +1 -0
  54. package/dist/services/authorization/types.d.ts +53 -0
  55. package/dist/services/authorization/types.d.ts.map +1 -0
  56. package/dist/services/authorization/types.js +10 -0
  57. package/dist/services/authorization/types.js.map +1 -0
  58. package/dist/services/batch-delegation.service.d.ts +53 -0
  59. package/dist/services/batch-delegation.service.d.ts.map +1 -0
  60. package/dist/services/batch-delegation.service.js +95 -0
  61. package/dist/services/batch-delegation.service.js.map +1 -0
  62. package/dist/services/oauth-config.service.d.ts +53 -0
  63. package/dist/services/oauth-config.service.d.ts.map +1 -0
  64. package/dist/services/oauth-config.service.js +119 -0
  65. package/dist/services/oauth-config.service.js.map +1 -0
  66. package/dist/services/oauth-provider-registry.d.ts +88 -0
  67. package/dist/services/oauth-provider-registry.d.ts.map +1 -0
  68. package/dist/services/oauth-provider-registry.js +128 -0
  69. package/dist/services/oauth-provider-registry.js.map +1 -0
  70. package/dist/services/oauth-service.d.ts +77 -0
  71. package/dist/services/oauth-service.d.ts.map +1 -0
  72. package/dist/services/oauth-service.js +348 -0
  73. package/dist/services/oauth-service.js.map +1 -0
  74. package/dist/services/oauth-token-retrieval.service.d.ts +49 -0
  75. package/dist/services/oauth-token-retrieval.service.d.ts.map +1 -0
  76. package/dist/services/oauth-token-retrieval.service.js +150 -0
  77. package/dist/services/oauth-token-retrieval.service.js.map +1 -0
  78. package/dist/services/provider-resolver.d.ts +48 -0
  79. package/dist/services/provider-resolver.d.ts.map +1 -0
  80. package/dist/services/provider-resolver.js +121 -0
  81. package/dist/services/provider-resolver.js.map +1 -0
  82. package/dist/services/provider-validator.d.ts +55 -0
  83. package/dist/services/provider-validator.d.ts.map +1 -0
  84. package/dist/services/provider-validator.js +135 -0
  85. package/dist/services/provider-validator.js.map +1 -0
  86. package/dist/services/tool-context-builder.d.ts +57 -0
  87. package/dist/services/tool-context-builder.d.ts.map +1 -0
  88. package/dist/services/tool-context-builder.js +125 -0
  89. package/dist/services/tool-context-builder.js.map +1 -0
  90. package/dist/services/tool-protection.service.d.ts +87 -10
  91. package/dist/services/tool-protection.service.d.ts.map +1 -1
  92. package/dist/services/tool-protection.service.js +282 -112
  93. package/dist/services/tool-protection.service.js.map +1 -1
  94. package/dist/types/oauth-required-error.d.ts +40 -0
  95. package/dist/types/oauth-required-error.d.ts.map +1 -0
  96. package/dist/types/oauth-required-error.js +40 -0
  97. package/dist/types/oauth-required-error.js.map +1 -0
  98. package/dist/utils/did-helpers.d.ts +33 -0
  99. package/dist/utils/did-helpers.d.ts.map +1 -1
  100. package/dist/utils/did-helpers.js +40 -0
  101. package/dist/utils/did-helpers.js.map +1 -1
  102. package/dist/utils/index.d.ts +1 -0
  103. package/dist/utils/index.d.ts.map +1 -1
  104. package/dist/utils/index.js +1 -0
  105. package/dist/utils/index.js.map +1 -1
  106. package/docs/API_REFERENCE.md +1362 -0
  107. package/docs/COMPLIANCE_MATRIX.md +691 -0
  108. package/docs/STATUSLIST2021_GUIDE.md +696 -0
  109. package/docs/W3C_VC_DELEGATION_GUIDE.md +710 -0
  110. package/package.json +24 -50
  111. package/scripts/audit-compliance.ts +724 -0
  112. package/src/__tests__/cache/tool-protection-cache.test.ts +640 -0
  113. package/src/__tests__/config/provider-runtime-config.test.ts +309 -0
  114. package/src/__tests__/delegation-e2e.test.ts +690 -0
  115. package/src/__tests__/identity/user-did-manager.test.ts +213 -0
  116. package/src/__tests__/index.test.ts +56 -0
  117. package/src/__tests__/integration/full-flow.test.ts +776 -0
  118. package/src/__tests__/integration.test.ts +281 -0
  119. package/src/__tests__/providers/base.test.ts +173 -0
  120. package/src/__tests__/providers/memory.test.ts +319 -0
  121. package/src/__tests__/regression/phase2-regression.test.ts +429 -0
  122. package/src/__tests__/runtime/audit-logger.test.ts +154 -0
  123. package/src/__tests__/runtime/base-extensions.test.ts +593 -0
  124. package/src/__tests__/runtime/base.test.ts +869 -0
  125. package/src/__tests__/runtime/delegation-flow.test.ts +164 -0
  126. package/src/__tests__/runtime/proof-client-did.test.ts +375 -0
  127. package/src/__tests__/runtime/route-interception.test.ts +686 -0
  128. package/src/__tests__/runtime/tool-protection-enforcement.test.ts +908 -0
  129. package/src/__tests__/services/agentshield-integration.test.ts +784 -0
  130. package/src/__tests__/services/provider-resolver-edge-cases.test.ts +591 -0
  131. package/src/__tests__/services/tool-protection-oauth-provider.test.ts +480 -0
  132. package/src/__tests__/services/tool-protection.service.test.ts +1366 -0
  133. package/src/__tests__/utils/mock-providers.ts +340 -0
  134. package/src/cache/oauth-config-cache.d.ts +69 -0
  135. package/src/cache/oauth-config-cache.d.ts.map +1 -0
  136. package/src/cache/oauth-config-cache.js.map +1 -0
  137. package/src/cache/oauth-config-cache.ts +123 -0
  138. package/src/cache/tool-protection-cache.ts +171 -0
  139. package/src/compliance/EXAMPLE.md +412 -0
  140. package/src/compliance/__tests__/schema-verifier.test.ts +797 -0
  141. package/src/compliance/index.ts +8 -0
  142. package/src/compliance/schema-registry.ts +460 -0
  143. package/src/compliance/schema-verifier.ts +708 -0
  144. package/src/config/__tests__/remote-config.spec.ts +268 -0
  145. package/src/config/remote-config.ts +174 -0
  146. package/src/config.ts +309 -0
  147. package/src/delegation/__tests__/audience-validator.test.ts +112 -0
  148. package/src/delegation/__tests__/bitstring.test.ts +346 -0
  149. package/src/delegation/__tests__/cascading-revocation.test.ts +628 -0
  150. package/src/delegation/__tests__/delegation-graph.test.ts +584 -0
  151. package/src/delegation/__tests__/utils.test.ts +152 -0
  152. package/src/delegation/__tests__/vc-issuer.test.ts +442 -0
  153. package/src/delegation/__tests__/vc-verifier.test.ts +922 -0
  154. package/src/delegation/audience-validator.ts +52 -0
  155. package/src/delegation/bitstring.ts +278 -0
  156. package/src/delegation/cascading-revocation.ts +370 -0
  157. package/src/delegation/delegation-graph.ts +299 -0
  158. package/src/delegation/index.ts +14 -0
  159. package/src/delegation/statuslist-manager.ts +353 -0
  160. package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +366 -0
  161. package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +228 -0
  162. package/src/delegation/storage/index.ts +9 -0
  163. package/src/delegation/storage/memory-graph-storage.ts +178 -0
  164. package/src/delegation/storage/memory-statuslist-storage.ts +77 -0
  165. package/src/delegation/utils.ts +42 -0
  166. package/src/delegation/vc-issuer.ts +232 -0
  167. package/src/delegation/vc-verifier.ts +568 -0
  168. package/src/identity/idp-token-resolver.ts +147 -0
  169. package/src/identity/idp-token-storage.interface.ts +59 -0
  170. package/src/identity/user-did-manager.ts +370 -0
  171. package/src/index.ts +260 -0
  172. package/src/providers/base.d.ts +91 -0
  173. package/src/providers/base.d.ts.map +1 -0
  174. package/src/providers/base.js.map +1 -0
  175. package/src/providers/base.ts +96 -0
  176. package/src/providers/memory.ts +142 -0
  177. package/src/runtime/audit-logger.ts +39 -0
  178. package/src/runtime/base.ts +1329 -0
  179. package/src/services/__tests__/access-control.integration.test.ts +443 -0
  180. package/src/services/__tests__/access-control.proof-response-validation.test.ts +578 -0
  181. package/src/services/__tests__/access-control.service.test.ts +970 -0
  182. package/src/services/__tests__/batch-delegation.service.test.ts +351 -0
  183. package/src/services/__tests__/crypto.service.test.ts +531 -0
  184. package/src/services/__tests__/oauth-provider-registry.test.ts +142 -0
  185. package/src/services/__tests__/proof-verifier.integration.test.ts +485 -0
  186. package/src/services/__tests__/proof-verifier.test.ts +489 -0
  187. package/src/services/__tests__/provider-resolution.integration.test.ts +202 -0
  188. package/src/services/__tests__/provider-resolver.test.ts +213 -0
  189. package/src/services/__tests__/storage.service.test.ts +358 -0
  190. package/src/services/access-control.service.ts +990 -0
  191. package/src/services/authorization/authorization-registry.ts +66 -0
  192. package/src/services/authorization/types.ts +71 -0
  193. package/src/services/batch-delegation.service.ts +137 -0
  194. package/src/services/crypto.service.ts +302 -0
  195. package/src/services/errors.ts +76 -0
  196. package/src/services/index.ts +9 -0
  197. package/src/services/oauth-config.service.d.ts +53 -0
  198. package/src/services/oauth-config.service.d.ts.map +1 -0
  199. package/src/services/oauth-config.service.js.map +1 -0
  200. package/src/services/oauth-config.service.ts +169 -0
  201. package/src/services/oauth-provider-registry.d.ts +57 -0
  202. package/src/services/oauth-provider-registry.d.ts.map +1 -0
  203. package/src/services/oauth-provider-registry.js.map +1 -0
  204. package/src/services/oauth-provider-registry.ts +141 -0
  205. package/src/services/oauth-service.ts +510 -0
  206. package/src/services/oauth-token-retrieval.service.ts +245 -0
  207. package/src/services/proof-verifier.ts +478 -0
  208. package/src/services/provider-resolver.d.ts +48 -0
  209. package/src/services/provider-resolver.d.ts.map +1 -0
  210. package/src/services/provider-resolver.js.map +1 -0
  211. package/src/services/provider-resolver.ts +146 -0
  212. package/src/services/provider-validator.ts +170 -0
  213. package/src/services/storage.service.ts +566 -0
  214. package/src/services/tool-context-builder.ts +172 -0
  215. package/src/services/tool-protection.service.ts +958 -0
  216. package/src/types/oauth-required-error.ts +63 -0
  217. package/src/types/tool-protection.ts +155 -0
  218. package/src/utils/__tests__/did-helpers.test.ts +101 -0
  219. package/src/utils/base64.ts +148 -0
  220. package/src/utils/cors.ts +83 -0
  221. package/src/utils/did-helpers.ts +150 -0
  222. package/src/utils/index.ts +8 -0
  223. package/src/utils/storage-keys.ts +278 -0
  224. package/tsconfig.json +21 -0
  225. package/vitest.config.ts +56 -0
@@ -0,0 +1,348 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth Service
4
+ *
5
+ * Handles OAuth token exchange and refresh using PKCE (Proof Key for Code Exchange).
6
+ * Supports both direct PKCE exchange with OAuth providers and proxy mode via AgentShield.
7
+ *
8
+ * @package @kya-os/mcp-i-core
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.OAuthService = void 0;
12
+ /**
13
+ * Service for OAuth token exchange and refresh
14
+ */
15
+ class OAuthService {
16
+ config;
17
+ constructor(config) {
18
+ this.config = {
19
+ configService: config.configService,
20
+ fetchProvider: config.fetchProvider,
21
+ agentShieldApiUrl: config.agentShieldApiUrl,
22
+ agentShieldApiKey: config.agentShieldApiKey,
23
+ projectId: config.projectId,
24
+ logger: config.logger || (() => { }),
25
+ };
26
+ }
27
+ /**
28
+ * Exchange authorization code for IDP tokens using PKCE
29
+ *
30
+ * For PKCE providers: Exchanges code directly with OAuth provider (no client secret)
31
+ * For proxy mode: Exchanges code via AgentShield API
32
+ *
33
+ * @param provider - OAuth provider name (e.g., "github", "google")
34
+ * @param code - Authorization code from OAuth callback
35
+ * @param codeVerifier - PKCE code verifier (optional for non-PKCE providers in proxy mode)
36
+ * @param redirectUri - Redirect URI used in authorization request
37
+ * @returns IDP tokens (access_token, refresh_token, expires_at, etc.)
38
+ */
39
+ async exchangeToken(provider, code, codeVerifier, redirectUri) {
40
+ // Fetch provider config
41
+ const oauthConfig = await this.config.configService.getOAuthConfig(this.config.projectId);
42
+ const providerConfig = oauthConfig.providers[provider];
43
+ if (!providerConfig) {
44
+ throw new Error(`Provider "${provider}" not configured for project "${this.config.projectId}"`);
45
+ }
46
+ // For PKCE providers, require codeVerifier
47
+ if (providerConfig.supportsPKCE && !providerConfig.proxyMode) {
48
+ if (!codeVerifier) {
49
+ throw new Error(`Provider "${provider}" requires PKCE code_verifier for token exchange`);
50
+ }
51
+ return this.exchangeTokenPKCE(providerConfig, code, codeVerifier, redirectUri || "");
52
+ }
53
+ // For proxy mode, codeVerifier is optional (only included if PKCE is supported)
54
+ if (providerConfig.proxyMode) {
55
+ return this.exchangeTokenProxy(providerConfig, code, codeVerifier, redirectUri || "");
56
+ }
57
+ throw new Error(`Provider "${provider}" configuration is invalid: must support PKCE or use proxy mode`);
58
+ }
59
+ /**
60
+ * Exchange token directly with OAuth provider using PKCE
61
+ */
62
+ async exchangeTokenPKCE(providerConfig, code, codeVerifier, redirectUri) {
63
+ this.config.logger("[OAuthService] Exchanging token with PKCE", {
64
+ provider: providerConfig.authorizationUrl,
65
+ tokenUrl: providerConfig.tokenUrl,
66
+ });
67
+ const response = await this.config.fetchProvider.fetch(providerConfig.tokenUrl, {
68
+ method: "POST",
69
+ headers: {
70
+ "Content-Type": "application/x-www-form-urlencoded",
71
+ Accept: "application/json",
72
+ },
73
+ body: new URLSearchParams({
74
+ grant_type: "authorization_code",
75
+ code,
76
+ redirect_uri: redirectUri,
77
+ client_id: providerConfig.clientId,
78
+ code_verifier: codeVerifier,
79
+ }).toString(),
80
+ });
81
+ if (!response.ok) {
82
+ const errorText = await response.text().catch(() => "Unknown error");
83
+ let errorData;
84
+ try {
85
+ errorData = JSON.parse(errorText);
86
+ }
87
+ catch {
88
+ errorData = { error: errorText };
89
+ }
90
+ const errorMessage = errorData.error_description || errorData.error || errorText;
91
+ this.config.logger("[OAuthService] Token exchange failed", {
92
+ status: response.status,
93
+ error: errorMessage,
94
+ provider: providerConfig.tokenUrl,
95
+ });
96
+ throw new Error(`Token exchange failed: ${errorMessage} (${response.status})`);
97
+ }
98
+ const tokens = await response.json();
99
+ // Validate required fields
100
+ if (!tokens.access_token) {
101
+ throw new Error("Token response missing access_token");
102
+ }
103
+ // Calculate expiration timestamp
104
+ const expiresIn = tokens.expires_in || 3600; // Default 1 hour
105
+ const expiresAt = Date.now() + expiresIn * 1000;
106
+ const idpTokens = {
107
+ access_token: tokens.access_token,
108
+ refresh_token: tokens.refresh_token,
109
+ expires_in: expiresIn,
110
+ expires_at: expiresAt,
111
+ token_type: tokens.token_type || "Bearer",
112
+ scope: tokens.scope,
113
+ };
114
+ this.config.logger("[OAuthService] Token exchange successful", {
115
+ provider: providerConfig.tokenUrl,
116
+ expiresAt: new Date(expiresAt).toISOString(),
117
+ hasRefreshToken: !!idpTokens.refresh_token,
118
+ });
119
+ return idpTokens;
120
+ }
121
+ /**
122
+ * Exchange token via AgentShield proxy (for providers that require proxy mode)
123
+ *
124
+ * Note: For Phase 3 two-step flow, OAuth tokens are retrieved separately via
125
+ * OAuthTokenRetrievalService in the callback handler. This method maintains
126
+ * backward compatibility for direct proxy mode usage.
127
+ */
128
+ async exchangeTokenProxy(providerConfig, code, codeVerifier, redirectUri) {
129
+ // Exchange via AgentShield proxy endpoint
130
+ const proxyUrl = `${this.config.agentShieldApiUrl}/api/v1/oauth/token`;
131
+ this.config.logger("[OAuthService] Exchanging token via proxy", {
132
+ proxyUrl,
133
+ provider: providerConfig.authorizationUrl,
134
+ hasCodeVerifier: !!codeVerifier,
135
+ supportsPKCE: providerConfig.supportsPKCE,
136
+ });
137
+ // Build request body - only include code_verifier if PKCE is supported and provided
138
+ const requestBody = {
139
+ grant_type: "authorization_code",
140
+ code,
141
+ redirect_uri: redirectUri || "",
142
+ provider: providerConfig.authorizationUrl,
143
+ project_id: this.config.projectId,
144
+ };
145
+ // Include code_verifier only if provider supports PKCE and verifier is provided
146
+ if (providerConfig.supportsPKCE && codeVerifier) {
147
+ requestBody.code_verifier = codeVerifier;
148
+ }
149
+ const response = await this.config.fetchProvider.fetch(proxyUrl, {
150
+ method: "POST",
151
+ headers: {
152
+ "Content-Type": "application/json",
153
+ Authorization: `Bearer ${this.config.agentShieldApiKey}`,
154
+ },
155
+ body: JSON.stringify(requestBody),
156
+ });
157
+ if (!response.ok) {
158
+ const errorText = await response.text().catch(() => "Unknown error");
159
+ let errorData;
160
+ try {
161
+ errorData = JSON.parse(errorText);
162
+ }
163
+ catch {
164
+ errorData = { error: errorText };
165
+ }
166
+ const errorMessage = errorData.error_description || errorData.error || errorText;
167
+ this.config.logger("[OAuthService] Proxy token exchange failed", {
168
+ status: response.status,
169
+ error: errorMessage,
170
+ proxyUrl,
171
+ });
172
+ throw new Error(`Proxy token exchange failed: ${errorMessage} (${response.status})`);
173
+ }
174
+ const result = await response.json();
175
+ const tokens = result.data || result;
176
+ // Validate required fields
177
+ if (!tokens.access_token) {
178
+ throw new Error("Proxy token response missing access_token");
179
+ }
180
+ // Calculate expiration timestamp
181
+ const expiresIn = tokens.expires_in || 3600; // Default 1 hour
182
+ const expiresAt = Date.now() + expiresIn * 1000;
183
+ const idpTokens = {
184
+ access_token: tokens.access_token,
185
+ refresh_token: tokens.refresh_token,
186
+ expires_in: expiresIn,
187
+ expires_at: expiresAt,
188
+ token_type: tokens.token_type || "Bearer",
189
+ scope: tokens.scope,
190
+ };
191
+ this.config.logger("[OAuthService] Proxy token exchange successful", {
192
+ proxyUrl,
193
+ expiresAt: new Date(expiresAt).toISOString(),
194
+ hasRefreshToken: !!idpTokens.refresh_token,
195
+ });
196
+ return idpTokens;
197
+ }
198
+ /**
199
+ * Refresh IDP access token using refresh token
200
+ *
201
+ * For PKCE providers: Refreshes directly with OAuth provider
202
+ * For proxy mode: Refreshes via AgentShield API
203
+ *
204
+ * @param provider - OAuth provider name
205
+ * @param refreshToken - Refresh token from previous token exchange
206
+ * @returns New IDP tokens or null if refresh failed
207
+ */
208
+ async refreshToken(provider, refreshToken) {
209
+ // Fetch provider config
210
+ const oauthConfig = await this.config.configService.getOAuthConfig(this.config.projectId);
211
+ const providerConfig = oauthConfig.providers[provider];
212
+ if (!providerConfig) {
213
+ this.config.logger("[OAuthService] Provider not found for refresh", {
214
+ provider,
215
+ });
216
+ return null;
217
+ }
218
+ // For PKCE providers, refresh directly with OAuth provider
219
+ if (providerConfig.supportsPKCE && !providerConfig.proxyMode) {
220
+ return this.refreshTokenPKCE(providerConfig, refreshToken);
221
+ }
222
+ // For proxy mode, refresh via AgentShield
223
+ if (providerConfig.proxyMode) {
224
+ return this.refreshTokenProxy(providerConfig, refreshToken);
225
+ }
226
+ return null;
227
+ }
228
+ /**
229
+ * Refresh token directly with OAuth provider using PKCE
230
+ */
231
+ async refreshTokenPKCE(providerConfig, refreshToken) {
232
+ this.config.logger("[OAuthService] Refreshing token with PKCE", {
233
+ provider: providerConfig.tokenUrl,
234
+ });
235
+ try {
236
+ const response = await this.config.fetchProvider.fetch(providerConfig.tokenUrl, {
237
+ method: "POST",
238
+ headers: {
239
+ "Content-Type": "application/x-www-form-urlencoded",
240
+ Accept: "application/json",
241
+ },
242
+ body: new URLSearchParams({
243
+ grant_type: "refresh_token",
244
+ refresh_token: refreshToken,
245
+ client_id: providerConfig.clientId,
246
+ }).toString(),
247
+ });
248
+ if (!response.ok) {
249
+ this.config.logger("[OAuthService] Token refresh failed", {
250
+ status: response.status,
251
+ provider: providerConfig.tokenUrl,
252
+ });
253
+ return null;
254
+ }
255
+ const tokens = await response.json();
256
+ if (!tokens.access_token) {
257
+ this.config.logger("[OAuthService] Token refresh response missing access_token");
258
+ return null;
259
+ }
260
+ // Calculate expiration timestamp
261
+ const expiresIn = tokens.expires_in || 3600; // Default 1 hour
262
+ const expiresAt = Date.now() + expiresIn * 1000;
263
+ const idpTokens = {
264
+ access_token: tokens.access_token,
265
+ refresh_token: tokens.refresh_token || refreshToken, // Use new refresh token if provided, otherwise keep old one
266
+ expires_in: expiresIn,
267
+ expires_at: expiresAt,
268
+ token_type: tokens.token_type || "Bearer",
269
+ scope: tokens.scope,
270
+ };
271
+ this.config.logger("[OAuthService] Token refresh successful", {
272
+ provider: providerConfig.tokenUrl,
273
+ expiresAt: new Date(expiresAt).toISOString(),
274
+ });
275
+ return idpTokens;
276
+ }
277
+ catch (error) {
278
+ this.config.logger("[OAuthService] Token refresh error", {
279
+ error: error instanceof Error ? error.message : String(error),
280
+ provider: providerConfig.tokenUrl,
281
+ });
282
+ return null;
283
+ }
284
+ }
285
+ /**
286
+ * Refresh token via AgentShield proxy
287
+ */
288
+ async refreshTokenProxy(providerConfig, refreshToken) {
289
+ const proxyUrl = `${this.config.agentShieldApiUrl}/api/v1/oauth/token`;
290
+ this.config.logger("[OAuthService] Refreshing token via proxy", {
291
+ proxyUrl,
292
+ provider: providerConfig.authorizationUrl,
293
+ });
294
+ try {
295
+ const response = await this.config.fetchProvider.fetch(proxyUrl, {
296
+ method: "POST",
297
+ headers: {
298
+ "Content-Type": "application/json",
299
+ Authorization: `Bearer ${this.config.agentShieldApiKey}`,
300
+ },
301
+ body: JSON.stringify({
302
+ grant_type: "refresh_token",
303
+ refresh_token: refreshToken,
304
+ provider: providerConfig.authorizationUrl,
305
+ project_id: this.config.projectId,
306
+ }),
307
+ });
308
+ if (!response.ok) {
309
+ this.config.logger("[OAuthService] Proxy token refresh failed", {
310
+ status: response.status,
311
+ proxyUrl,
312
+ });
313
+ return null;
314
+ }
315
+ const result = await response.json();
316
+ const tokens = result.data || result;
317
+ if (!tokens.access_token) {
318
+ this.config.logger("[OAuthService] Proxy token refresh response missing access_token");
319
+ return null;
320
+ }
321
+ // Calculate expiration timestamp
322
+ const expiresIn = tokens.expires_in || 3600; // Default 1 hour
323
+ const expiresAt = Date.now() + expiresIn * 1000;
324
+ const idpTokens = {
325
+ access_token: tokens.access_token,
326
+ refresh_token: tokens.refresh_token || refreshToken,
327
+ expires_in: expiresIn,
328
+ expires_at: expiresAt,
329
+ token_type: tokens.token_type || "Bearer",
330
+ scope: tokens.scope,
331
+ };
332
+ this.config.logger("[OAuthService] Proxy token refresh successful", {
333
+ proxyUrl,
334
+ expiresAt: new Date(expiresAt).toISOString(),
335
+ });
336
+ return idpTokens;
337
+ }
338
+ catch (error) {
339
+ this.config.logger("[OAuthService] Proxy token refresh error", {
340
+ error: error instanceof Error ? error.message : String(error),
341
+ proxyUrl,
342
+ });
343
+ return null;
344
+ }
345
+ }
346
+ }
347
+ exports.OAuthService = OAuthService;
348
+ //# sourceMappingURL=oauth-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-service.js","sourceRoot":"","sources":["../../src/services/oauth-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * OAuth Token Retrieval Service
3
+ *
4
+ * Retrieves OAuth tokens from AgentShield after receiving delegation token.
5
+ * Implements the two-step token flow for Phase 3 custom IDP support.
6
+ *
7
+ * @package @kya-os/mcp-i-core
8
+ */
9
+ import type { IdpTokens } from "@kya-os/contracts/config";
10
+ /**
11
+ * Configuration for OAuthTokenRetrievalService
12
+ */
13
+ export interface OAuthTokenRetrievalServiceConfig {
14
+ /** AgentShield API base URL */
15
+ baseUrl: string;
16
+ /** Fetch implementation */
17
+ fetchProvider: typeof fetch;
18
+ /** Optional logger callback */
19
+ logger?: (message: string, data?: any) => void;
20
+ /** Optional retry configuration */
21
+ retryConfig?: {
22
+ maxRetries?: number;
23
+ retryDelay?: number;
24
+ retryBackoff?: number;
25
+ };
26
+ }
27
+ /**
28
+ * Service for retrieving OAuth tokens from AgentShield
29
+ */
30
+ export declare class OAuthTokenRetrievalService {
31
+ private config;
32
+ constructor(config: OAuthTokenRetrievalServiceConfig);
33
+ /**
34
+ * Retrieve OAuth tokens from AgentShield
35
+ *
36
+ * @param delegationId - Delegation ID from token exchange response
37
+ * @param delegationToken - Delegation token (JWT) for authorization
38
+ * @returns OAuth tokens mapped to IdpTokens format, or null if unavailable
39
+ */
40
+ retrieveTokens(delegationId: string, delegationToken: string): Promise<IdpTokens | null>;
41
+ /**
42
+ * Map AgentShield response to IdpTokens format
43
+ *
44
+ * @param data - Response data from AgentShield
45
+ * @returns IdpTokens object
46
+ */
47
+ private mapToIdpTokens;
48
+ }
49
+ //# sourceMappingURL=oauth-token-retrieval.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-retrieval.service.d.ts","sourceRoot":"","sources":["../../src/services/oauth-token-retrieval.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,aAAa,EAAE,OAAO,KAAK,CAAC;IAC5B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/C,mCAAmC;IACnC,WAAW,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAiCD;;GAEG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAEZ;gBAEU,MAAM,EAAE,gCAAgC;IAmBpD;;;;;;OAMG;IACG,cAAc,CAClB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAqH5B;;;;;OAKG;IACH,OAAO,CAAC,cAAc;CAuBvB"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth Token Retrieval Service
4
+ *
5
+ * Retrieves OAuth tokens from AgentShield after receiving delegation token.
6
+ * Implements the two-step token flow for Phase 3 custom IDP support.
7
+ *
8
+ * @package @kya-os/mcp-i-core
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.OAuthTokenRetrievalService = void 0;
12
+ /**
13
+ * Service for retrieving OAuth tokens from AgentShield
14
+ */
15
+ class OAuthTokenRetrievalService {
16
+ config;
17
+ constructor(config) {
18
+ const defaultRetryConfig = {
19
+ maxRetries: 3,
20
+ retryDelay: 1000,
21
+ retryBackoff: 2,
22
+ };
23
+ this.config = {
24
+ ...config,
25
+ logger: config.logger || (() => { }),
26
+ retryConfig: {
27
+ ...defaultRetryConfig,
28
+ ...config.retryConfig,
29
+ },
30
+ };
31
+ }
32
+ /**
33
+ * Retrieve OAuth tokens from AgentShield
34
+ *
35
+ * @param delegationId - Delegation ID from token exchange response
36
+ * @param delegationToken - Delegation token (JWT) for authorization
37
+ * @returns OAuth tokens mapped to IdpTokens format, or null if unavailable
38
+ */
39
+ async retrieveTokens(delegationId, delegationToken) {
40
+ const endpoint = `${this.config.baseUrl}/api/v1/bouncer/delegations/${delegationId}/tokens`;
41
+ this.config.logger("[OAuthTokenRetrievalService] Retrieving OAuth tokens", {
42
+ delegationId,
43
+ endpoint,
44
+ });
45
+ let lastError = null;
46
+ let attempt = 0;
47
+ // Retry logic for transient failures
48
+ while (attempt <= this.config.retryConfig.maxRetries) {
49
+ try {
50
+ const response = await this.config.fetchProvider(endpoint, {
51
+ method: "GET",
52
+ headers: {
53
+ Authorization: `Bearer ${delegationToken}`,
54
+ Accept: "application/json",
55
+ },
56
+ });
57
+ if (!response.ok) {
58
+ const errorData = await response.json().catch(() => ({}));
59
+ if (response.status === 404 || response.status === 401) {
60
+ // Token unavailable or unauthorized - don't retry
61
+ this.config.logger("[OAuthTokenRetrievalService] Tokens unavailable", {
62
+ status: response.status,
63
+ delegationId,
64
+ error: errorData,
65
+ });
66
+ return null;
67
+ }
68
+ // Transient error - retry
69
+ const errorMessage = errorData.error?.message ||
70
+ errorData.error ||
71
+ errorData.message ||
72
+ `HTTP ${response.status}`;
73
+ throw new Error(`Token retrieval failed: ${errorMessage}`);
74
+ }
75
+ const result = (await response.json());
76
+ if (!result.success) {
77
+ this.config.logger("[OAuthTokenRetrievalService] Token retrieval error response", {
78
+ delegationId,
79
+ error: result.error,
80
+ });
81
+ return null;
82
+ }
83
+ // Map response to IdpTokens format
84
+ const tokens = this.mapToIdpTokens(result.data);
85
+ this.config.logger("[OAuthTokenRetrievalService] OAuth tokens retrieved successfully", {
86
+ delegationId,
87
+ expiresAt: new Date(tokens.expires_at).toISOString(),
88
+ hasRefreshToken: !!tokens.refresh_token,
89
+ });
90
+ return tokens;
91
+ }
92
+ catch (error) {
93
+ lastError = error instanceof Error ? error : new Error(String(error));
94
+ if (attempt < this.config.retryConfig.maxRetries) {
95
+ const delay = this.config.retryConfig.retryDelay *
96
+ Math.pow(this.config.retryConfig.retryBackoff, attempt);
97
+ this.config.logger("[OAuthTokenRetrievalService] Retry attempt failed, retrying", {
98
+ attempt: attempt + 1,
99
+ maxRetries: this.config.retryConfig.maxRetries,
100
+ delay,
101
+ error: lastError.message,
102
+ });
103
+ await new Promise((resolve) => setTimeout(resolve, delay));
104
+ attempt++;
105
+ }
106
+ else {
107
+ // Max retries exceeded
108
+ this.config.logger("[OAuthTokenRetrievalService] Max retries exceeded", {
109
+ delegationId,
110
+ error: lastError.message,
111
+ attempts: attempt + 1,
112
+ });
113
+ // Return null instead of throwing - delegation token still valid
114
+ return null;
115
+ }
116
+ }
117
+ }
118
+ return null;
119
+ }
120
+ /**
121
+ * Map AgentShield response to IdpTokens format
122
+ *
123
+ * @param data - Response data from AgentShield
124
+ * @returns IdpTokens object
125
+ */
126
+ mapToIdpTokens(data) {
127
+ // Convert ISO 8601 string to milliseconds timestamp
128
+ let expiresAt;
129
+ if (data.oauth_expires_at) {
130
+ expiresAt = new Date(data.oauth_expires_at).getTime();
131
+ }
132
+ else if (data.oauth_expires_in) {
133
+ expiresAt = Date.now() + data.oauth_expires_in * 1000;
134
+ }
135
+ else {
136
+ // Default to 1 hour if neither provided
137
+ expiresAt = Date.now() + 3600 * 1000;
138
+ }
139
+ return {
140
+ access_token: data.oauth_access_token,
141
+ refresh_token: data.oauth_refresh_token || undefined,
142
+ expires_in: data.oauth_expires_in || undefined,
143
+ expires_at: expiresAt,
144
+ token_type: data.oauth_token_type || "Bearer",
145
+ scope: data.oauth_scope || undefined,
146
+ };
147
+ }
148
+ }
149
+ exports.OAuthTokenRetrievalService = OAuthTokenRetrievalService;
150
+ //# sourceMappingURL=oauth-token-retrieval.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-retrieval.service.js","sourceRoot":"","sources":["../../src/services/oauth-token-retrieval.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Provider Resolver
3
+ *
4
+ * Resolves OAuth provider for tools using priority-based resolution strategy.
5
+ * Supports Phase 2+ tool-specific providers with backward compatibility for Phase 1.
6
+ *
7
+ * @package @kya-os/mcp-i-core
8
+ */
9
+ import type { ToolProtection } from "@kya-os/contracts/tool-protection";
10
+ import type { OAuthProviderRegistry } from "./oauth-provider-registry.js";
11
+ import type { OAuthConfigService } from "./oauth-config.service.js";
12
+ /**
13
+ * Resolves OAuth provider for tools with priority-based fallback strategy
14
+ *
15
+ * Priority order:
16
+ * 1. Tool-specific oauthProvider field (Phase 2+ preferred)
17
+ * 2. Scope prefix inference (fallback)
18
+ * 3. Project-configured provider from AgentShield dashboard
19
+ * 4. Error if no provider can be resolved
20
+ */
21
+ export declare class ProviderResolver {
22
+ private registry;
23
+ private configService;
24
+ constructor(registry: OAuthProviderRegistry, configService: OAuthConfigService);
25
+ /**
26
+ * Resolve OAuth provider for a tool
27
+ *
28
+ * @param toolProtection - Tool protection configuration
29
+ * @param projectId - Project ID for fetching provider config
30
+ * @returns Provider name (never null - throws if cannot resolve)
31
+ * @throws Error if provider cannot be resolved
32
+ */
33
+ resolveProvider(toolProtection: ToolProtection, projectId: string): Promise<string>;
34
+ /**
35
+ * Infer provider from scope prefixes
36
+ *
37
+ * Used as Priority 2 fallback when oauthProvider is not specified.
38
+ * Examples:
39
+ * - github:repo:read → github
40
+ * - gmail:read → google
41
+ * - microsoft:calendar:read → microsoft
42
+ *
43
+ * @param scopes - Required scopes for the tool
44
+ * @returns Provider name if uniquely inferred, null otherwise
45
+ */
46
+ private inferProviderFromScopes;
47
+ }
48
+ //# sourceMappingURL=provider-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-resolver.d.ts","sourceRoot":"","sources":["../../src/services/provider-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;;;;;;GAQG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,aAAa;gBADb,QAAQ,EAAE,qBAAqB,EAC/B,aAAa,EAAE,kBAAkB;IAG3C;;;;;;;OAOG;IACG,eAAe,CACnB,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC;IAyDlB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,uBAAuB;CAoChC"}