@undefineds.co/xpod 0.4.14 → 0.4.15

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 (202) hide show
  1. package/config/cloud.json +0 -3
  2. package/config/local.json +0 -3
  3. package/config/xpod.base.json +0 -24
  4. package/dist/api/ai-config/AiConfigStore.d.ts +2 -2
  5. package/dist/api/ai-config/AiConfigStore.js +4 -1
  6. package/dist/api/ai-gateway/auth/CallerPodAccess.d.ts +2 -5
  7. package/dist/api/ai-gateway/auth/CallerPodAccess.js +3 -42
  8. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.d.ts +2 -1
  9. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js +1 -1
  10. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.d.ts +3 -8
  11. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js +9 -32
  12. package/dist/api/ai-gateway/connect/index.d.ts +3 -3
  13. package/dist/api/ai-gateway/connect/index.js +9 -38
  14. package/dist/api/ai-gateway/errors.js +2 -1
  15. package/dist/api/ai-gateway/models/PodModelSelectionRepository.d.ts +3 -3
  16. package/dist/api/ai-gateway/models/PodModelSelectionRepository.js +7 -11
  17. package/dist/api/ai-gateway/pod/HostedPodRoute.d.ts +27 -0
  18. package/dist/api/ai-gateway/pod/HostedPodRoute.js +47 -0
  19. package/dist/api/ai-gateway/pod/OwnerPodAccess.d.ts +79 -0
  20. package/dist/api/ai-gateway/pod/OwnerPodAccess.js +192 -0
  21. package/dist/api/ai-gateway/pod/PodInterfaceKeyStore.d.ts +52 -0
  22. package/dist/api/ai-gateway/pod/PodInterfaceKeyStore.js +61 -0
  23. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.d.ts +3 -3
  24. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js +7 -32
  25. package/dist/api/auth/ClientCredentialsAuthenticator.js +5 -28
  26. package/dist/api/auth/TokenEndpointRoute.d.ts +18 -0
  27. package/dist/api/auth/TokenEndpointRoute.js +36 -0
  28. package/dist/api/chatkit/pod-store.d.ts +4 -4
  29. package/dist/api/chatkit/pod-store.js +24 -95
  30. package/dist/api/container/common.js +36 -23
  31. package/dist/api/container/local.js +62 -29
  32. package/dist/api/container/routes.js +39 -7
  33. package/dist/api/container/types.d.ts +2 -2
  34. package/dist/api/handlers/AiGatewayManagementHandler.d.ts +6 -0
  35. package/dist/api/handlers/AiGatewayManagementHandler.js +17 -4
  36. package/dist/api/handlers/NetworkSettingsHandler.d.ts +7 -0
  37. package/dist/api/handlers/NetworkSettingsHandler.js +7 -0
  38. package/dist/api/handlers/PodSettingsHandler.d.ts +3 -3
  39. package/dist/api/handlers/PodSettingsHandler.js +3 -3
  40. package/dist/api/handlers/ProvisionHandler.d.ts +29 -0
  41. package/dist/api/handlers/ProvisionHandler.js +46 -0
  42. package/dist/api/handlers/ReachabilityHandler.js +3 -1
  43. package/dist/api/runtime.d.ts +9 -0
  44. package/dist/api/runtime.js +16 -3
  45. package/dist/cli/commands/start.d.ts +9 -2
  46. package/dist/cli/commands/start.js +15 -17
  47. package/dist/components/components.jsonld +1 -1
  48. package/dist/components/context.jsonld +5 -42
  49. package/dist/edge/EdgeNodeAgent.d.ts +10 -0
  50. package/dist/edge/EdgeNodeAgent.js +55 -0
  51. package/dist/edge/EdgeNodeAgent.jsonld +8 -0
  52. package/dist/edge/reachability/ReachabilitySessionService.js +4 -1
  53. package/dist/edge/reachability/RouteSetBuilder.d.ts +18 -1
  54. package/dist/edge/reachability/RouteSetBuilder.js +47 -0
  55. package/dist/edge/reachability/RouteSetBuilder.jsonld +29 -0
  56. package/dist/edge/reachability/types.d.ts +8 -2
  57. package/dist/http/SubgraphSparqlHttpHandler.d.ts +1 -25
  58. package/dist/http/SubgraphSparqlHttpHandler.js +0 -100
  59. package/dist/http/SubgraphSparqlHttpHandler.jsonld +0 -8
  60. package/dist/identity/drizzle/PodInterfaceKeyRepository.d.ts +33 -0
  61. package/dist/identity/drizzle/PodInterfaceKeyRepository.js +78 -0
  62. package/dist/identity/drizzle/db.d.ts +7 -0
  63. package/dist/identity/drizzle/db.js +30 -0
  64. package/dist/identity/drizzle/schema.pg.d.ts +9 -0
  65. package/dist/identity/drizzle/schema.pg.js +16 -1
  66. package/dist/identity/drizzle/schema.sqlite.d.ts +106 -0
  67. package/dist/identity/drizzle/schema.sqlite.js +16 -1
  68. package/dist/index.d.ts +1 -2
  69. package/dist/index.js +3 -5
  70. package/dist/runtime/GatewayAdminProxyAuth.d.ts +1 -16
  71. package/dist/runtime/GatewayAdminProxyAuth.js +2 -71
  72. package/dist/runtime/Proxy.d.ts +10 -1
  73. package/dist/runtime/Proxy.js +95 -28
  74. package/dist/runtime/bootstrap.d.ts +10 -0
  75. package/dist/runtime/bootstrap.js +24 -0
  76. package/dist/runtime/host/node/NodeRuntimeHost.js +5 -3
  77. package/dist/runtime/index.d.ts +1 -1
  78. package/dist/runtime/index.js +2 -3
  79. package/dist/runtime/js-runtime.js +10 -3
  80. package/dist/runtime/lifecycle.js +5 -4
  81. package/dist/runtime/port-finder.d.ts +9 -13
  82. package/dist/runtime/port-finder.js +18 -37
  83. package/dist/tunnel/AutoTunnelProvider.d.ts +56 -0
  84. package/dist/tunnel/AutoTunnelProvider.js +181 -0
  85. package/dist/tunnel/index.d.ts +1 -0
  86. package/dist/tunnel/index.js +3 -1
  87. package/node_modules/@undefineds.co/ai-connections/dist/error-wording.js +7 -2
  88. package/node_modules/@undefineds.co/solid-sdk/dist/access-route.cjs +230 -0
  89. package/node_modules/@undefineds.co/solid-sdk/dist/access-route.d.ts +76 -0
  90. package/node_modules/@undefineds.co/solid-sdk/dist/access-route.js +115 -0
  91. package/node_modules/@undefineds.co/solid-sdk/dist/index.cjs +89 -0
  92. package/node_modules/@undefineds.co/solid-sdk/dist/index.d.ts +1 -0
  93. package/node_modules/@undefineds.co/solid-sdk/dist/index.js +1 -0
  94. package/node_modules/@undefineds.co/solid-sdk/package.json +6 -1
  95. package/package.json +2 -2
  96. package/static/app/assets/inrupt-smoke.js +23 -23
  97. package/static/auth-callback/assets/{AiConfigContext-DCXpjzpj.js → AiConfigContext-Bx0HCAW5.js} +1 -1
  98. package/static/auth-callback/assets/{AiConfigPage-fe-xMIXa.js → AiConfigPage-ChQImMbm.js} +1 -1
  99. package/static/auth-callback/assets/{DocumentProcessingPanel-BGnkfMuU.js → DocumentProcessingPanel-D830H4SH.js} +1 -1
  100. package/static/auth-callback/assets/{IndexLifecyclePanel-42Jups0j.js → IndexLifecyclePanel-CnlkjMF8.js} +1 -1
  101. package/static/auth-callback/assets/{IndexSubjectPanel-CYyLOlQU.js → IndexSubjectPanel-CdEfg_CO.js} +1 -1
  102. package/static/auth-callback/assets/{ModelAssignmentsPanel-BOvUH4yr.js → ModelAssignmentsPanel-D-8A8dZx.js} +1 -1
  103. package/static/auth-callback/assets/{ModelsPage-DwyITxt7.js → ModelsPage-Cim7cubp.js} +3 -3
  104. package/static/auth-callback/assets/{NetworkPage-CG9RelJA.js → NetworkPage-CfK3x-pb.js} +2 -2
  105. package/static/auth-callback/assets/{PaneListHeader-yvd5ohs6.js → PaneListHeader-Bf_kEd4U.js} +1 -1
  106. package/static/auth-callback/assets/{SearchIndexingPanel-2_a6ezzj.js → SearchIndexingPanel-4kD4RBEQ.js} +1 -1
  107. package/static/auth-callback/assets/{StatusSubjectPanel-8qtVxnzC.js → StatusSubjectPanel-Bw9AiTSf.js} +1 -1
  108. package/static/auth-callback/assets/{StatusWorkspace-CBdRahCF.js → StatusWorkspace-C-301H-0.js} +1 -1
  109. package/static/auth-callback/assets/{SystemSettingsPage-BZJ6vWkg.js → SystemSettingsPage-BbWn-eG6.js} +1 -1
  110. package/static/auth-callback/assets/{SystemSettingsSubjectPanel-xm08UhXP.js → SystemSettingsSubjectPanel-DA4wvNSm.js} +1 -1
  111. package/static/auth-callback/assets/{XpodAiConnectionsPodStore-V6vgGfuw.js → XpodAiConnectionsPodStore-CohdyLoX.js} +1 -1
  112. package/static/auth-callback/assets/{activity-CeM7xly8.js → activity-CCsb9Oam.js} +1 -1
  113. package/static/auth-callback/assets/ai-connections-DexTPyfC.js +1 -0
  114. package/static/auth-callback/assets/{auth-callback-DTG8cSj7.js → auth-callback-Ds-c62W3.js} +5 -5
  115. package/static/auth-callback/assets/{badge-qJo2Zr4d.js → badge-CQm5OyzR.js} +1 -1
  116. package/static/auth-callback/assets/{collection-runtime-Bztsz31a.js → collection-runtime-DlAuU5TW.js} +1 -1
  117. package/static/auth-callback/assets/{dialog-D-h6x5x0.js → dialog-CnGzg5Ff.js} +1 -1
  118. package/static/auth-callback/assets/{download-C2ir4lmR.js → download-DwMONJvm.js} +1 -1
  119. package/static/auth-callback/assets/{external-link-THLDL4On.js → external-link-Bu5AGqCO.js} +1 -1
  120. package/static/auth-callback/assets/{index-BlVZb9A7.js → index-B0T-1YO8.js} +1 -1
  121. package/static/auth-callback/assets/{index-BRpv4yO3.js → index-C8QZf_4W.js} +1 -1
  122. package/static/auth-callback/assets/{index-D983R1FV.js → index-DwIlrIDG.js} +1 -1
  123. package/static/auth-callback/assets/{index-browser-3FvR0aaf.js → index-browser-lRsMcP_7.js} +1 -1
  124. package/static/auth-callback/assets/{key-round-C9U5j1Ly.js → key-round-BDMtU57P.js} +1 -1
  125. package/static/auth-callback/assets/{rotate-ccw-DP45cD4o.js → rotate-ccw-CoKIGCsQ.js} +1 -1
  126. package/static/auth-callback/assets/{skeleton-Dn4EiSCS.js → skeleton-CPoSWHDr.js} +1 -1
  127. package/static/auth-callback/assets/{waypoints-uqFQ3uEG.js → waypoints-BeYHxqHv.js} +1 -1
  128. package/static/auth-callback/assets/{workspace-layout-DLYK0Wwu.js → workspace-layout-xA5YxiK3.js} +1 -1
  129. package/static/auth-callback/auth-callback.html +1 -1
  130. package/static/dashboard/assets/{AiConfigContext-DJcMECNw.js → AiConfigContext-rWx4TyiH.js} +1 -1
  131. package/static/dashboard/assets/{AiConfigPage-BvE7dOTy.js → AiConfigPage-StVJpDFT.js} +1 -1
  132. package/static/dashboard/assets/{DocumentProcessingPanel-D9780krf.js → DocumentProcessingPanel-DJ5yul2O.js} +1 -1
  133. package/static/dashboard/assets/{IndexLifecyclePanel-SjsUcnbM.js → IndexLifecyclePanel-CpjtgezK.js} +1 -1
  134. package/static/dashboard/assets/{IndexSubjectPanel-C-ym2Tqi.js → IndexSubjectPanel-BVKcot1_.js} +1 -1
  135. package/static/dashboard/assets/{ModelAssignmentsPanel-BRjZ-arB.js → ModelAssignmentsPanel-BxVgWZPc.js} +1 -1
  136. package/static/dashboard/assets/{ModelsPage-BtTU6du3.js → ModelsPage-CECBwmeO.js} +3 -3
  137. package/static/dashboard/assets/{NetworkPage-CV9qpkDg.js → NetworkPage-zQgFscEW.js} +2 -2
  138. package/static/dashboard/assets/{PaneListHeader-KyPTTBsv.js → PaneListHeader-DIPe8pS6.js} +1 -1
  139. package/static/dashboard/assets/{SearchIndexingPanel-DolHGawg.js → SearchIndexingPanel-lalFJ3c8.js} +1 -1
  140. package/static/dashboard/assets/{StatusSubjectPanel-_YZvKiYi.js → StatusSubjectPanel-CpY_KU-G.js} +1 -1
  141. package/static/dashboard/assets/{StatusWorkspace-Dlbh_G40.js → StatusWorkspace-BwWCii3A.js} +1 -1
  142. package/static/dashboard/assets/{SystemSettingsPage-Be7QSIoz.js → SystemSettingsPage-BKZxX-_n.js} +1 -1
  143. package/static/dashboard/assets/{SystemSettingsSubjectPanel-DBp0gja7.js → SystemSettingsSubjectPanel-BZrqb2C5.js} +1 -1
  144. package/static/dashboard/assets/{XpodAiConnectionsPodStore-ClpSjzpP.js → XpodAiConnectionsPodStore-Bbpx9dTN.js} +1 -1
  145. package/static/dashboard/assets/{activity-lsNbTXJu.js → activity-BJ15TLVP.js} +1 -1
  146. package/static/dashboard/assets/ai-connections-GG6qkTJt.js +1 -0
  147. package/static/dashboard/assets/{badge-CVatKjaG.js → badge-BBX5FlaB.js} +1 -1
  148. package/static/dashboard/assets/{collection-runtime-Ec4UnY28.js → collection-runtime-UBbHBzdf.js} +1 -1
  149. package/static/dashboard/assets/{dashboard-BEzsRsvF.js → dashboard-7Y6BHyV9.js} +62 -62
  150. package/static/dashboard/assets/{dialog-BuyelQ4V.js → dialog-QrOJ-hB0.js} +1 -1
  151. package/static/dashboard/assets/{download-B4Nf678F.js → download-DK9x-VOP.js} +1 -1
  152. package/static/dashboard/assets/{external-link-PYv9CvKL.js → external-link-Cnkn87mJ.js} +1 -1
  153. package/static/dashboard/assets/{index-C9XPE-mI.js → index-B1z84it5.js} +1 -1
  154. package/static/dashboard/assets/{index-awr7ulur.js → index-DzjauX3N.js} +1 -1
  155. package/static/dashboard/assets/{index-Cx69bTNh.js → index-cIa8_efI.js} +1 -1
  156. package/static/dashboard/assets/{key-round-VsY80U1Z.js → key-round-BoS6UqKz.js} +1 -1
  157. package/static/dashboard/assets/{rotate-ccw-Cz1K4vE9.js → rotate-ccw-BeWV76i0.js} +1 -1
  158. package/static/dashboard/assets/{skeleton-BhNv_8tO.js → skeleton-CypcJL07.js} +1 -1
  159. package/static/dashboard/assets/{waypoints-DYS9XFYV.js → waypoints-zHOOqfhi.js} +1 -1
  160. package/static/dashboard/assets/{workspace-layout-OZJAFx5V.js → workspace-layout-DZ9JuxnM.js} +1 -1
  161. package/static/dashboard/dashboard.html +1 -1
  162. package/static/settings/assets/{AiConfigContext-B8JS3MXF.js → AiConfigContext-D3b1l_Kw.js} +1 -1
  163. package/static/settings/assets/{AiConfigPage-C3Zl8LUl.js → AiConfigPage-DYKw-atP.js} +1 -1
  164. package/static/settings/assets/{DocumentProcessingPanel-DpDZAQvf.js → DocumentProcessingPanel-DguRfsIV.js} +1 -1
  165. package/static/settings/assets/{IndexLifecyclePanel-Ec1XF88t.js → IndexLifecyclePanel-B85qJJA4.js} +1 -1
  166. package/static/settings/assets/{IndexSubjectPanel-BulT9BmO.js → IndexSubjectPanel-CsN7IxaV.js} +1 -1
  167. package/static/settings/assets/{ModelAssignmentsPanel-BcGSmYjb.js → ModelAssignmentsPanel-DEp9byI6.js} +1 -1
  168. package/static/settings/assets/{ModelsPage-CvTCKy1T.js → ModelsPage-CzTnPs_G.js} +3 -3
  169. package/static/settings/assets/{NetworkPage-DQF5u9Bn.js → NetworkPage-BDVnmUU0.js} +2 -2
  170. package/static/settings/assets/{PaneListHeader-D40hqcVl.js → PaneListHeader-Cpe39N76.js} +1 -1
  171. package/static/settings/assets/{SearchIndexingPanel-iCUPOx_0.js → SearchIndexingPanel-DA9w8lLL.js} +1 -1
  172. package/static/settings/assets/{StatusSubjectPanel-E--ZHSql.js → StatusSubjectPanel-BU0Aq0CS.js} +1 -1
  173. package/static/settings/assets/{StatusWorkspace-YjDAx1II.js → StatusWorkspace-D1AC1i5N.js} +1 -1
  174. package/static/settings/assets/{SystemSettingsPage-CDdV3mC9.js → SystemSettingsPage-ChKvOioO.js} +1 -1
  175. package/static/settings/assets/{SystemSettingsSubjectPanel-Br8WazDq.js → SystemSettingsSubjectPanel-DyTpOnD2.js} +1 -1
  176. package/static/settings/assets/{XpodAiConnectionsPodStore-CLr38P_Z.js → XpodAiConnectionsPodStore-VU5Bsz1a.js} +1 -1
  177. package/static/settings/assets/{activity-C5DAHHTE.js → activity-DGpLfsQB.js} +1 -1
  178. package/static/settings/assets/ai-connections-DexTPyfC.js +1 -0
  179. package/static/settings/assets/{badge-D8eIyxKt.js → badge-_hCrrWRP.js} +1 -1
  180. package/static/settings/assets/{collection-runtime-DLc9zil8.js → collection-runtime-E40TZ8Cl.js} +1 -1
  181. package/static/settings/assets/{dialog-CyuR7Va4.js → dialog-DTr2JkHn.js} +1 -1
  182. package/static/settings/assets/{download-c0oxZrCz.js → download-B_D21DDX.js} +1 -1
  183. package/static/settings/assets/{external-link-D3Z34fP_.js → external-link-BATYaM13.js} +1 -1
  184. package/static/settings/assets/{index-CSr3-2Cj.js → index-BAlAVi-J.js} +1 -1
  185. package/static/settings/assets/{index-ComidxAm.js → index-Ckh4h9jj.js} +1 -1
  186. package/static/settings/assets/{index-CKGbRFlc.js → index-DOiwLF4B.js} +1 -1
  187. package/static/settings/assets/{index-browser-CAscEbae.js → index-browser-DFFWN3Kr.js} +1 -1
  188. package/static/settings/assets/{key-round-DyjLmXuB.js → key-round-ZTVU_1O1.js} +1 -1
  189. package/static/settings/assets/{rotate-ccw-679HF_ec.js → rotate-ccw-DDdw8PTU.js} +1 -1
  190. package/static/settings/assets/{settings-DKknqu4C.js → settings-CyLnISOv.js} +62 -62
  191. package/static/settings/assets/{skeleton-CkopNkPB.js → skeleton-DEzA3hc2.js} +1 -1
  192. package/static/settings/assets/{waypoints-CrqfAftE.js → waypoints-BSdfNvEb.js} +1 -1
  193. package/static/settings/assets/{workspace-layout-UN6c4qTG.js → workspace-layout-BOQnl_3d.js} +1 -1
  194. package/static/settings/settings.html +1 -1
  195. package/dist/api/ai-gateway/pod/HostedPodDataAccess.d.ts +0 -31
  196. package/dist/api/ai-gateway/pod/HostedPodDataAccess.js +0 -330
  197. package/dist/http/InternalPodDataHttpHandler.d.ts +0 -57
  198. package/dist/http/InternalPodDataHttpHandler.js +0 -551
  199. package/dist/http/InternalPodDataHttpHandler.jsonld +0 -243
  200. package/static/auth-callback/assets/ai-connections-C6yaE6WQ.js +0 -1
  201. package/static/dashboard/assets/ai-connections-CXp5gd1J.js +0 -1
  202. package/static/settings/assets/ai-connections-C6yaE6WQ.js +0 -1
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OwnerPodAccess = exports.POD_INTERFACE_KEY_REJECTED = exports.POD_INTERFACE_KEY_MISSING = void 0;
4
+ exports.podAccessError = podAccessError;
5
+ exports.isPodAccessFailure = isPodAccessFailure;
6
+ const solid_client_authn_core_1 = require("@inrupt/solid-client-authn-core");
7
+ const global_logger_factory_1 = require("global-logger-factory");
8
+ const AuthContext_1 = require("../../auth/AuthContext");
9
+ const CallerPodAccess_1 = require("../auth/CallerPodAccess");
10
+ const TokenEndpointRoute_1 = require("../../auth/TokenEndpointRoute");
11
+ const HostedPodRoute_1 = require("./HostedPodRoute");
12
+ /** No usable Pod credential is on file for this owner; the user has to grant one. */
13
+ exports.POD_INTERFACE_KEY_MISSING = 'pod_interface_key_missing';
14
+ /** The owner's stored credential was refused by the Pod; it has to be granted again. */
15
+ exports.POD_INTERFACE_KEY_REJECTED = 'pod_interface_key_rejected';
16
+ const TOKEN_EXPIRY_SKEW_MS = 30_000;
17
+ const DEFAULT_TOKEN_LIFETIME_SECONDS = 300;
18
+ const MAX_CACHED_TOKENS = 128;
19
+ /**
20
+ * Reaches a Pod as its owner over the standard Solid interface.
21
+ *
22
+ * Three credentials can prove the owner, and all three are the owner's own interface key:
23
+ * the caller's key, when the caller presented one; the caller's reusable token, when it holds
24
+ * one; and the key the owner granted this deployment for work no caller is attached to.
25
+ *
26
+ * What never happens is asking the Solid server to trust the caller's network position. Every
27
+ * request carries a credential for the owner and addresses the Pod's own URLs, so the Pod's own
28
+ * authorization decides - exactly as it does for the browser.
29
+ */
30
+ class OwnerPodAccess {
31
+ constructor(options) {
32
+ this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
33
+ this.podFetches = new Map();
34
+ this.keys = options.keys;
35
+ this.fetchImpl = options.fetch ?? fetch;
36
+ this.now = options.now ?? Date.now;
37
+ this.tokenRoute = (0, TokenEndpointRoute_1.resolveTokenEndpointRoute)(options.tokenEndpoint, options.publicBaseUrl);
38
+ this.route = options.route;
39
+ }
40
+ /** Grant, or rotate, the owner's Pod interface key. */
41
+ async saveKey(owner, credential) {
42
+ await this.keys.saveKey(owner, credential);
43
+ this.podFetches.clear();
44
+ }
45
+ async forgetKey(owner) {
46
+ await this.keys.forgetKey(owner);
47
+ this.podFetches.clear();
48
+ }
49
+ async hasKey(owner) {
50
+ return await this.keys.hasKey(owner);
51
+ }
52
+ async getPodFetch(owner, context = {}) {
53
+ const auth = context.auth;
54
+ if (auth?.type === 'solid' && auth.webId !== owner) {
55
+ // A caller authenticated as somebody else never borrows this owner's credential.
56
+ return undefined;
57
+ }
58
+ if ((0, AuthContext_1.hasSolidClientCredentialsAuthority)(auth)) {
59
+ // The caller's own interface key. Its exchanged token may be DPoP-bound to a proof that
60
+ // was never kept, so the key is exchanged again with a key this process controls.
61
+ return await this.credentialFetch(owner, { clientId: auth.clientId, clientSecret: auth.clientSecret });
62
+ }
63
+ const callerFetch = (0, CallerPodAccess_1.createCallerAuthenticatedPodFetch)(owner, auth, this.fetchImpl, this.route);
64
+ if (callerFetch) {
65
+ return callerFetch;
66
+ }
67
+ return await this.storedKeyFetch(owner);
68
+ }
69
+ async storedKeyFetch(owner) {
70
+ const credential = await this.keys.read(owner);
71
+ return credential ? await this.credentialFetch(owner, credential) : undefined;
72
+ }
73
+ async credentialFetch(owner, credential) {
74
+ const cacheKey = `${owner}\u0000${credential.clientId}`;
75
+ const cached = this.podFetches.get(cacheKey);
76
+ if (cached && cached.expiresAt > this.now() + TOKEN_EXPIRY_SKEW_MS) {
77
+ return cached.fetch;
78
+ }
79
+ this.podFetches.delete(cacheKey);
80
+ const exchanged = await this.exchange(owner, credential);
81
+ this.podFetches.set(cacheKey, exchanged);
82
+ pruneOldest(this.podFetches, MAX_CACHED_TOKENS);
83
+ return exchanged.fetch;
84
+ }
85
+ async exchange(owner, credential) {
86
+ const dpopKey = await (0, solid_client_authn_core_1.generateDpopKeyPair)();
87
+ const response = await this.fetchImpl(this.tokenRoute.url, {
88
+ method: 'POST',
89
+ headers: {
90
+ accept: 'application/json',
91
+ 'content-type': 'application/x-www-form-urlencoded',
92
+ authorization: `Basic ${Buffer.from(`${credential.clientId}:${credential.clientSecret}`, 'utf8').toString('base64')}`,
93
+ DPoP: await (0, solid_client_authn_core_1.createDpopHeader)(this.tokenRoute.proofUrl, 'POST', dpopKey),
94
+ ...this.tokenRoute.headers,
95
+ },
96
+ body: new URLSearchParams({ grant_type: 'client_credentials', scope: 'webid' }),
97
+ });
98
+ const body = await response.text().catch(() => '');
99
+ if (!response.ok) {
100
+ this.logger.warn(`Pod interface key refused for ${owner}: ${response.status} ${body.slice(0, 200)}`);
101
+ throw new Error(`${exports.POD_INTERFACE_KEY_REJECTED}:${response.status}`);
102
+ }
103
+ const token = parseTokenResponse(body);
104
+ if (!token) {
105
+ this.logger.warn(`Pod interface key exchange returned no access token for ${owner}`);
106
+ throw new Error(`${exports.POD_INTERFACE_KEY_REJECTED}:invalid_response`);
107
+ }
108
+ const transport = await (0, HostedPodRoute_1.createHostedPodRouteTransport)(this.fetchImpl, this.route);
109
+ const authenticated = (0, solid_client_authn_core_1.buildAuthenticatedFetch)(token.accessToken, {
110
+ ...(token.dpopBound ? { dpopKey } : {}),
111
+ fetch: transport,
112
+ });
113
+ return {
114
+ fetch: this.invalidateOnUnauthorized(`${owner}\u0000${credential.clientId}`, authenticated),
115
+ expiresAt: this.now() + token.expiresInSeconds * 1000,
116
+ };
117
+ }
118
+ invalidateOnUnauthorized(cacheKey, podFetch) {
119
+ return async (input, init) => {
120
+ const response = await podFetch(input, init);
121
+ if (response.status === 401) {
122
+ // The token stopped being accepted; the next request exchanges the key again.
123
+ this.podFetches.delete(cacheKey);
124
+ }
125
+ return response;
126
+ };
127
+ }
128
+ }
129
+ exports.OwnerPodAccess = OwnerPodAccess;
130
+ /**
131
+ * Reason an owner's Pod is out of reach, as a stable code the caller and the UI can act on.
132
+ *
133
+ * A same-owner caller is the ordinary case: Xpod knows who the user is, but holds nothing it can
134
+ * present to the Pod on the user's behalf. A browser session explains why its own credential was
135
+ * not enough - its proof is bound to the URL it was made for - while a bearer session simply has
136
+ * no Pod credential at all. Either way the fix is the same: grant the interface key.
137
+ */
138
+ function podAccessError(owner, auth) {
139
+ if (!auth || auth.type !== 'solid') {
140
+ return CallerPodAccess_1.CALLER_POD_ACCESS_UNAVAILABLE;
141
+ }
142
+ if (auth.webId !== owner) {
143
+ return CallerPodAccess_1.CALLER_OWNER_MISMATCH;
144
+ }
145
+ if (auth.tokenType === 'DPoP' || typeof auth.dpopProof === 'string') {
146
+ return CallerPodAccess_1.CALLER_DPOP_REPLAY_UNSUPPORTED;
147
+ }
148
+ return exports.POD_INTERFACE_KEY_MISSING;
149
+ }
150
+ /**
151
+ * Whether a failure means Xpod had no usable way into the owner's Pod.
152
+ *
153
+ * The stable wire code for this is `service_access_missing`, which callers already report; the
154
+ * codes below are the reason behind it, kept distinct so the UI can ask for the right fix.
155
+ */
156
+ function isPodAccessFailure(message) {
157
+ return message === 'service_access_missing'
158
+ || message.startsWith(exports.POD_INTERFACE_KEY_MISSING)
159
+ || message.startsWith(exports.POD_INTERFACE_KEY_REJECTED)
160
+ || message.startsWith(CallerPodAccess_1.CALLER_DPOP_REPLAY_UNSUPPORTED)
161
+ || message.startsWith(CallerPodAccess_1.CALLER_OWNER_MISMATCH)
162
+ || message.startsWith(CallerPodAccess_1.CALLER_POD_ACCESS_UNAVAILABLE);
163
+ }
164
+ function pruneOldest(cache, limit) {
165
+ while (cache.size > limit) {
166
+ const oldest = cache.keys().next();
167
+ if (oldest.done)
168
+ return;
169
+ cache.delete(oldest.value);
170
+ }
171
+ }
172
+ function parseTokenResponse(body) {
173
+ let parsed;
174
+ try {
175
+ parsed = JSON.parse(body);
176
+ }
177
+ catch {
178
+ return undefined;
179
+ }
180
+ if (typeof parsed.access_token !== 'string' || !parsed.access_token) {
181
+ return undefined;
182
+ }
183
+ const expiresIn = typeof parsed.expires_in === 'number' && parsed.expires_in > 0
184
+ ? parsed.expires_in
185
+ : DEFAULT_TOKEN_LIFETIME_SECONDS;
186
+ return {
187
+ accessToken: parsed.access_token,
188
+ dpopBound: String(parsed.token_type ?? 'DPoP').toUpperCase() !== 'BEARER',
189
+ expiresInSeconds: expiresIn,
190
+ };
191
+ }
192
+ //# sourceMappingURL=OwnerPodAccess.js.map
@@ -0,0 +1,52 @@
1
+ import type { CredentialVault } from '../credentials/CredentialVault';
2
+ import type { PodInterfaceKeyRepositoryPort } from '../../../identity/drizzle/PodInterfaceKeyRepository';
3
+ /** The owner's own Pod interface credential: the same kind of key a browser holds. */
4
+ export interface PodInterfaceCredential {
5
+ clientId: string;
6
+ clientSecret: string;
7
+ }
8
+ /**
9
+ * Grants, or withdraws, the interface key server-side components use for an owner.
10
+ *
11
+ * The browser is where a Pod credential is created, so it is also where the decision to let
12
+ * Xpod use it is made; this is the API that decision arrives through.
13
+ */
14
+ export interface PodInterfaceKeyGrant {
15
+ saveKey(owner: string, credential: PodInterfaceCredential): Promise<void>;
16
+ forgetKey(owner: string): Promise<void>;
17
+ hasKey(owner: string): Promise<boolean>;
18
+ }
19
+ /** Reads back the interface key an owner granted. */
20
+ export interface PodInterfaceKeySource {
21
+ read(owner: string): Promise<PodInterfaceCredential | undefined>;
22
+ }
23
+ /** Everything a component needs to hold and use an owner's interface key. */
24
+ export interface PodInterfaceKeyAccess extends PodInterfaceKeySource, PodInterfaceKeyGrant {
25
+ }
26
+ export declare const POD_INTERFACE_KEY_CORRUPT_PREFIX = "pod_interface_key_corrupt";
27
+ export interface PodInterfaceKeyStoreOptions {
28
+ repository: PodInterfaceKeyRepositoryPort;
29
+ vault: CredentialVault;
30
+ /** Vault identity the secret is sealed under. */
31
+ credentialIri?: string;
32
+ }
33
+ /**
34
+ * Keeps the owner's Pod interface key for server-side use.
35
+ *
36
+ * The key is what opens the Pod, so it is sealed with the credential vault rather than kept in
37
+ * the Pod. Storing it here is what lets a background component reach the Pod through the
38
+ * standard interface as the owner, instead of asking the Solid server to trust its position.
39
+ */
40
+ export declare class PodInterfaceKeyStore implements PodInterfaceKeyAccess {
41
+ private readonly logger;
42
+ private readonly repository;
43
+ private readonly vault;
44
+ private readonly credentialIri;
45
+ constructor(options: PodInterfaceKeyStoreOptions);
46
+ /** Store, or rotate, the owner's interface key. */
47
+ saveKey(ownerWebId: string, credential: PodInterfaceCredential): Promise<void>;
48
+ forgetKey(ownerWebId: string): Promise<void>;
49
+ hasKey(ownerWebId: string): Promise<boolean>;
50
+ read(ownerWebId: string): Promise<PodInterfaceCredential | undefined>;
51
+ private open;
52
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PodInterfaceKeyStore = exports.POD_INTERFACE_KEY_CORRUPT_PREFIX = void 0;
4
+ const global_logger_factory_1 = require("global-logger-factory");
5
+ exports.POD_INTERFACE_KEY_CORRUPT_PREFIX = 'pod_interface_key_corrupt';
6
+ const CREDENTIAL_IRI = 'urn:xpod:pod-interface-key';
7
+ const CREDENTIAL_PROVIDER = 'solid';
8
+ /**
9
+ * Keeps the owner's Pod interface key for server-side use.
10
+ *
11
+ * The key is what opens the Pod, so it is sealed with the credential vault rather than kept in
12
+ * the Pod. Storing it here is what lets a background component reach the Pod through the
13
+ * standard interface as the owner, instead of asking the Solid server to trust its position.
14
+ */
15
+ class PodInterfaceKeyStore {
16
+ constructor(options) {
17
+ this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
18
+ this.repository = options.repository;
19
+ this.vault = options.vault;
20
+ this.credentialIri = options.credentialIri ?? CREDENTIAL_IRI;
21
+ }
22
+ /** Store, or rotate, the owner's interface key. */
23
+ async saveKey(ownerWebId, credential) {
24
+ const sealed = await this.vault.seal({ webId: ownerWebId }, this.credentialIri, CREDENTIAL_PROVIDER, { clientSecret: credential.clientSecret });
25
+ await this.repository.write({
26
+ ownerWebId,
27
+ clientId: credential.clientId,
28
+ sealedSecret: JSON.stringify(sealed),
29
+ });
30
+ this.logger.debug(`Stored Pod interface key for ${ownerWebId}`);
31
+ }
32
+ async forgetKey(ownerWebId) {
33
+ await this.repository.remove(ownerWebId);
34
+ }
35
+ async hasKey(ownerWebId) {
36
+ return await this.repository.read(ownerWebId) !== undefined;
37
+ }
38
+ async read(ownerWebId) {
39
+ const record = await this.repository.read(ownerWebId);
40
+ return record ? await this.open(record) : undefined;
41
+ }
42
+ async open(record) {
43
+ const sealed = parseSealedSecret(record.sealedSecret, record.ownerWebId);
44
+ const opened = await this.vault.open({ webId: record.ownerWebId }, this.credentialIri, CREDENTIAL_PROVIDER, sealed);
45
+ const clientSecret = opened.clientSecret;
46
+ if (typeof clientSecret !== 'string' || !clientSecret) {
47
+ throw new Error(`${exports.POD_INTERFACE_KEY_CORRUPT_PREFIX}:${record.ownerWebId}`);
48
+ }
49
+ return { clientId: record.clientId, clientSecret };
50
+ }
51
+ }
52
+ exports.PodInterfaceKeyStore = PodInterfaceKeyStore;
53
+ function parseSealedSecret(value, ownerWebId) {
54
+ try {
55
+ return JSON.parse(value);
56
+ }
57
+ catch {
58
+ throw new Error(`${exports.POD_INTERFACE_KEY_CORRUPT_PREFIX}:${ownerWebId}`);
59
+ }
60
+ }
61
+ //# sourceMappingURL=PodInterfaceKeyStore.js.map
@@ -1,7 +1,7 @@
1
1
  import { quotaSnapshotResource, type QuotaSnapshotRow } from '@undefineds.co/models';
2
2
  import type { AuthContext } from '../../auth/AuthContext';
3
+ import { type PodAccessFetchProvider } from '../pod/OwnerPodAccess';
3
4
  import type { GatewayDeployment } from '../auth/InvocationTokenCodec';
4
- import type { InternalPodAccessTokenProvider } from '../pod/HostedPodDataAccess';
5
5
  import { type PodBaseUrlResolver } from '../pod/PodBaseUrlResolver';
6
6
  import type { ConnectCredentialRecord, PodCredentialRepository } from '../connect';
7
7
  import type { CredentialVault, ProviderSecret } from '../credentials/CredentialVault';
@@ -180,7 +180,7 @@ type QuotaSnapshotDb = {
180
180
  };
181
181
  };
182
182
  export interface PodQuotaSnapshotRepositoryOptions {
183
- internalPodAccess?: InternalPodAccessTokenProvider;
183
+ podAccess?: PodAccessFetchProvider;
184
184
  podBaseUrlResolver?: PodBaseUrlResolver;
185
185
  dbFactory?: (input: {
186
186
  owner: string;
@@ -191,7 +191,7 @@ export interface PodQuotaSnapshotRepositoryOptions {
191
191
  }
192
192
  export declare class PodQuotaSnapshotRepository implements QuotaSnapshotRepository {
193
193
  private readonly dbFactory;
194
- private readonly internalPodAccess?;
194
+ private readonly podAccess?;
195
195
  private readonly podBaseUrlResolver?;
196
196
  constructor(options?: PodQuotaSnapshotRepositoryOptions);
197
197
  findFresh(input: {
@@ -10,7 +10,7 @@ exports.decimalAmount = decimalAmount;
10
10
  exports.normalizeProvider = normalizeProvider;
11
11
  const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
12
12
  const models_1 = require("@undefineds.co/models");
13
- const CallerPodAccess_1 = require("../auth/CallerPodAccess");
13
+ const OwnerPodAccess_1 = require("../pod/OwnerPodAccess");
14
14
  const PodBaseUrlResolver_1 = require("../pod/PodBaseUrlResolver");
15
15
  const QuotaCapabilityRegistry_1 = require("./QuotaCapabilityRegistry");
16
16
  class ProviderQuotaService {
@@ -337,7 +337,7 @@ function quotaOfferingMatches(candidateOfferingId, inputOfferingId) {
337
337
  }
338
338
  class PodQuotaSnapshotRepository {
339
339
  constructor(options = {}) {
340
- this.internalPodAccess = options.internalPodAccess;
340
+ this.podAccess = options.podAccess;
341
341
  this.podBaseUrlResolver = options.podBaseUrlResolver;
342
342
  this.dbFactory = options.dbFactory ?? createDefaultQuotaSnapshotDb;
343
343
  }
@@ -405,37 +405,12 @@ class PodQuotaSnapshotRepository {
405
405
  return db;
406
406
  }
407
407
  async resolveTrustedFetch(owner, auth, podBaseUrl) {
408
- if (auth?.type === 'solid' && auth.webId !== owner) {
409
- throw new Error((0, CallerPodAccess_1.callerPodAccessError)(owner, auth));
410
- }
411
- if (auth?.type === 'solid'
412
- && auth.webId === owner
413
- && auth.viaApiKey === true
414
- && typeof auth.clientId === 'string'
415
- && typeof auth.clientSecret === 'string') {
416
- const hostedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth, { podBaseUrl });
417
- if (hostedFetch) {
418
- return this.wrapPodFetch(hostedFetch);
419
- }
420
- }
421
- const callerFetch = (0, CallerPodAccess_1.createCallerAuthenticatedPodFetch)(owner, auth);
422
- if (callerFetch) {
423
- return this.wrapPodFetch(callerFetch);
424
- }
425
- if (auth?.type === 'solid'
426
- && auth.webId === owner
427
- && (auth.tokenType === 'DPoP' || typeof auth.dpopProof === 'string')) {
428
- const hostedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth, { podBaseUrl });
429
- if (hostedFetch) {
430
- return this.wrapPodFetch(hostedFetch);
431
- }
432
- }
433
- if (!(0, CallerPodAccess_1.isInternalPodAccessAllowed)(auth)) {
434
- throw new Error((0, CallerPodAccess_1.callerPodAccessError)(owner, auth));
435
- }
436
- const trustedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth, { podBaseUrl });
408
+ const trustedFetch = await this.podAccess?.getPodFetch(owner, {
409
+ ...(auth ? { auth } : {}),
410
+ podBaseUrl,
411
+ });
437
412
  if (!trustedFetch) {
438
- throw new Error('AI Connection service identity is not configured');
413
+ throw new Error((0, OwnerPodAccess_1.podAccessError)(owner, auth));
439
414
  }
440
415
  return this.wrapPodFetch(trustedFetch);
441
416
  }
@@ -4,6 +4,7 @@ exports.ClientCredentialsAuthenticator = void 0;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const solid_client_authn_core_1 = require("@inrupt/solid-client-authn-core");
6
6
  const global_logger_factory_1 = require("global-logger-factory");
7
+ const TokenEndpointRoute_1 = require("./TokenEndpointRoute");
7
8
  const TokenIdentity_1 = require("./TokenIdentity");
8
9
  /**
9
10
  * Authenticator for CSS client credentials wrapped in sk-xxx transport format.
@@ -20,9 +21,10 @@ class ClientCredentialsAuthenticator {
20
21
  constructor(options) {
21
22
  this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
22
23
  this.tokenCache = options.tokenCache;
23
- this.tokenEndpoint = options.tokenEndpoint;
24
- this.tokenEndpointHeaders = tokenEndpointRoutingHeaders(options.tokenEndpoint, options.publicBaseUrl);
25
- this.tokenEndpointProofUrl = tokenEndpointProofUrl(options.tokenEndpoint, options.publicBaseUrl, this.tokenEndpointHeaders);
24
+ const route = (0, TokenEndpointRoute_1.resolveTokenEndpointRoute)(options.tokenEndpoint, options.publicBaseUrl);
25
+ this.tokenEndpoint = route.url;
26
+ this.tokenEndpointHeaders = route.headers;
27
+ this.tokenEndpointProofUrl = route.proofUrl;
26
28
  }
27
29
  canAuthenticate(request) {
28
30
  const auth = request.headers.authorization;
@@ -175,29 +177,4 @@ class ClientCredentialsAuthenticator {
175
177
  }
176
178
  }
177
179
  exports.ClientCredentialsAuthenticator = ClientCredentialsAuthenticator;
178
- function tokenEndpointRoutingHeaders(tokenEndpoint, publicBaseUrl) {
179
- if (!publicBaseUrl)
180
- return {};
181
- try {
182
- const internal = new URL(tokenEndpoint);
183
- const canonical = new URL(publicBaseUrl);
184
- if (internal.origin === canonical.origin || !isLoopbackHostname(internal.hostname))
185
- return {};
186
- return {
187
- 'X-Forwarded-Host': canonical.host,
188
- 'X-Forwarded-Proto': canonical.protocol.slice(0, -1),
189
- };
190
- }
191
- catch {
192
- return {};
193
- }
194
- }
195
- function tokenEndpointProofUrl(tokenEndpoint, publicBaseUrl, routingHeaders) {
196
- if (!publicBaseUrl || Object.keys(routingHeaders).length === 0)
197
- return tokenEndpoint;
198
- return new URL('/.oidc/token', publicBaseUrl).toString();
199
- }
200
- function isLoopbackHostname(hostname) {
201
- return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]';
202
- }
203
180
  //# sourceMappingURL=ClientCredentialsAuthenticator.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Where an OIDC token request is sent, versus the URL its DPoP proof must be made for.
3
+ *
4
+ * Xpod reaches the Solid interface over a loopback alias while the canonical URL never changes
5
+ * (`docs/multi-channel-access.md`). An internal loopback token endpoint therefore needs two
6
+ * things at once: the request goes to the alias, and the receiver is told which canonical origin
7
+ * it is really serving, so the proof verifies against the canonical URL.
8
+ */
9
+ export interface TokenEndpointRoute {
10
+ /** Request target: where the token request is actually sent. */
11
+ url: string;
12
+ /** URL the DPoP proof is bound to (`htu`). */
13
+ proofUrl: string;
14
+ /** Headers that make the receiver serve the canonical origin for this request. */
15
+ headers: Record<string, string>;
16
+ }
17
+ export declare function resolveTokenEndpointRoute(tokenEndpoint: string, publicBaseUrl?: string): TokenEndpointRoute;
18
+ export declare function isLoopbackHostname(hostname: string): boolean;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveTokenEndpointRoute = resolveTokenEndpointRoute;
4
+ exports.isLoopbackHostname = isLoopbackHostname;
5
+ function resolveTokenEndpointRoute(tokenEndpoint, publicBaseUrl) {
6
+ const headers = canonicalRoutingHeaders(tokenEndpoint, publicBaseUrl);
7
+ if (!publicBaseUrl || Object.keys(headers).length === 0) {
8
+ return { url: tokenEndpoint, proofUrl: tokenEndpoint, headers };
9
+ }
10
+ return {
11
+ url: tokenEndpoint,
12
+ proofUrl: new URL('/.oidc/token', publicBaseUrl).toString(),
13
+ headers,
14
+ };
15
+ }
16
+ function isLoopbackHostname(hostname) {
17
+ return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]';
18
+ }
19
+ function canonicalRoutingHeaders(tokenEndpoint, publicBaseUrl) {
20
+ if (!publicBaseUrl)
21
+ return {};
22
+ try {
23
+ const internal = new URL(tokenEndpoint);
24
+ const canonical = new URL(publicBaseUrl);
25
+ if (internal.origin === canonical.origin || !isLoopbackHostname(internal.hostname))
26
+ return {};
27
+ return {
28
+ 'X-Forwarded-Host': canonical.host,
29
+ 'X-Forwarded-Proto': canonical.protocol.slice(0, -1),
30
+ };
31
+ }
32
+ catch {
33
+ return {};
34
+ }
35
+ }
36
+ //# sourceMappingURL=TokenEndpointRoute.js.map
@@ -3,12 +3,14 @@ import type { ThreadMetadata, ThreadRef, ThreadItem, Attachment, Page, StoreItem
3
3
  import { type RunListOptions, type RunRecordData, type RunStepRecordData, type RunStore } from '../runs/store';
4
4
  import { type TaskListOptions, type TaskRecordData, type TaskStore } from '../tasks/store';
5
5
  import { type TaskAuthBindingRepository } from '../tasks/TaskAuthBinding';
6
+ import { type PodAccessFetchProvider } from '../ai-gateway/pod/OwnerPodAccess';
6
7
  import { type AiCredentialSecretDecoder } from '../../ai/service/AiCredentialSecret';
7
8
  import { CredentialStatus } from '../../credential/schema/types';
8
9
  import { type ServerGroupReconcilerService } from '../reconciler';
9
10
  import { type ReaderAiConfig } from '../../document/ReaderAiConfig';
10
11
  export interface PodChatKitStoreOptions {
11
- tokenEndpoint: string;
12
+ /** Reaches a Pod as its owner over the Pod's standard interface. */
13
+ podAccess?: PodAccessFetchProvider;
12
14
  serverGroupReconcilerService?: ServerGroupReconcilerService;
13
15
  /**
14
16
  * Reads a Pod credential secret (AI Connections envelope, `plaintext-v1`
@@ -30,7 +32,7 @@ export interface PodChatKitStoreOptions {
30
32
  */
31
33
  export declare class PodChatKitStore implements ChatKitStore<StoreContext>, RunStore<StoreContext>, TaskStore<StoreContext>, TaskAuthBindingRepository<StoreContext> {
32
34
  private readonly logger;
33
- private readonly tokenEndpoint;
35
+ private readonly podAccess?;
34
36
  private readonly serverGroupReconcilerService?;
35
37
  private readonly credentialSecretDecoder;
36
38
  private readonly deployment?;
@@ -47,8 +49,6 @@ export declare class PodChatKitStore implements ChatKitStore<StoreContext>, RunS
47
49
  * 获取认证后的 drizzle 实例 (缓存到 context 中)
48
50
  */
49
51
  private getDb;
50
- private getClientCredentialsAccessToken;
51
- private createAccessTokenFetch;
52
52
  /**
53
53
  * 从 context 获取 webId
54
54
  */