@undefineds.co/xpod 0.3.70 → 0.3.71-rc.2

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 (172) hide show
  1. package/config/cloud.json +3 -0
  2. package/config/local.json +3 -0
  3. package/config/resolver.json +7 -0
  4. package/config/xpod.base.json +20 -0
  5. package/dist/agents/ClaudeExecutor.js +1 -1
  6. package/dist/agents/ClaudeExecutor.js.map +1 -1
  7. package/dist/agents/types.d.ts +5 -5
  8. package/dist/agents/types.js.map +1 -1
  9. package/dist/api/ai-gateway/AiGatewayService.d.ts +5 -16
  10. package/dist/api/ai-gateway/AiGatewayService.js +13 -35
  11. package/dist/api/ai-gateway/AiGatewayService.js.map +1 -1
  12. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.d.ts +3 -2
  13. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.js +37 -12
  14. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.js.map +1 -1
  15. package/dist/api/ai-gateway/auth/GatewayPrincipal.d.ts +2 -16
  16. package/dist/api/ai-gateway/auth/GatewayPrincipal.js +3 -33
  17. package/dist/api/ai-gateway/auth/GatewayPrincipal.js.map +1 -1
  18. package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.d.ts +23 -0
  19. package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.js +81 -0
  20. package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.js.map +1 -0
  21. package/dist/api/ai-gateway/auth/InvocationTokenCodec.d.ts +7 -4
  22. package/dist/api/ai-gateway/auth/InvocationTokenCodec.js.map +1 -1
  23. package/dist/api/ai-gateway/connect/index.d.ts +7 -26
  24. package/dist/api/ai-gateway/connect/index.js +40 -67
  25. package/dist/api/ai-gateway/connect/index.js.map +1 -1
  26. package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.d.ts +17 -0
  27. package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.js +65 -0
  28. package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.js.map +1 -0
  29. package/dist/api/ai-gateway/pod/HostedPodDataAccess.d.ts +24 -0
  30. package/dist/api/ai-gateway/pod/HostedPodDataAccess.js +149 -0
  31. package/dist/api/ai-gateway/pod/HostedPodDataAccess.js.map +1 -0
  32. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.d.ts +13 -5
  33. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js +16 -19
  34. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js.map +1 -1
  35. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.d.ts +1 -1
  36. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.js +0 -2
  37. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.js.map +1 -1
  38. package/dist/api/auth/AuthContext.d.ts +1 -12
  39. package/dist/api/auth/AuthContext.js +0 -11
  40. package/dist/api/auth/AuthContext.js.map +1 -1
  41. package/dist/api/auth/ClientCredentialsAuthenticator.js +4 -11
  42. package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
  43. package/dist/api/chatkit/default-agent.d.ts +2 -2
  44. package/dist/api/chatkit/default-agent.js +4 -4
  45. package/dist/api/chatkit/default-agent.js.map +1 -1
  46. package/dist/api/chatkit/runtime/AcpAgentRuntime.js +1 -1
  47. package/dist/api/chatkit/runtime/AcpAgentRuntime.js.map +1 -1
  48. package/dist/api/container/common.js +28 -69
  49. package/dist/api/container/common.js.map +1 -1
  50. package/dist/api/container/index.js +5 -6
  51. package/dist/api/container/index.js.map +1 -1
  52. package/dist/api/container/routes.js +2 -5
  53. package/dist/api/container/routes.js.map +1 -1
  54. package/dist/api/container/types.d.ts +8 -10
  55. package/dist/api/container/types.js.map +1 -1
  56. package/dist/api/handlers/AiClientConfigurationHandler.js +3 -3
  57. package/dist/api/handlers/AiClientConfigurationHandler.js.map +1 -1
  58. package/dist/api/handlers/AiGatewayHandler.js +2 -2
  59. package/dist/api/handlers/AiGatewayHandler.js.map +1 -1
  60. package/dist/api/handlers/AiGatewayManagementHandler.d.ts +2 -10
  61. package/dist/api/handlers/AiGatewayManagementHandler.js +4 -154
  62. package/dist/api/handlers/AiGatewayManagementHandler.js.map +1 -1
  63. package/dist/api/handlers/NetworkSettingsHandler.js +0 -3
  64. package/dist/api/handlers/NetworkSettingsHandler.js.map +1 -1
  65. package/dist/api/handlers/PodSettingsHandler.d.ts +5 -2
  66. package/dist/api/handlers/PodSettingsHandler.js +3 -3
  67. package/dist/api/handlers/PodSettingsHandler.js.map +1 -1
  68. package/dist/api/runs/AgentRuntimeTypes.d.ts +3 -3
  69. package/dist/api/runs/AgentRuntimeTypes.js +10 -10
  70. package/dist/api/runs/AgentRuntimeTypes.js.map +1 -1
  71. package/dist/api/runs/InngestRunExecutionBackend.d.ts +15 -9
  72. package/dist/api/runs/InngestRunExecutionBackend.js +25 -10
  73. package/dist/api/runs/InngestRunExecutionBackend.js.map +1 -1
  74. package/dist/api/runs/PiAgentRuntimeDriver.js +2 -2
  75. package/dist/api/runs/PiAgentRuntimeDriver.js.map +1 -1
  76. package/dist/api/runs/RunStateCenter.js +1 -1
  77. package/dist/api/runs/RunStateCenter.js.map +1 -1
  78. package/dist/api/service/AiClientConfigurationService.d.ts +2 -2
  79. package/dist/api/service/AiClientConfigurationService.js +11 -11
  80. package/dist/api/service/AiClientConfigurationService.js.map +1 -1
  81. package/dist/api/tasks/InngestTaskScheduler.d.ts +16 -10
  82. package/dist/api/tasks/InngestTaskScheduler.js +24 -12
  83. package/dist/api/tasks/InngestTaskScheduler.js.map +1 -1
  84. package/dist/cli/commands/start.js +7 -7
  85. package/dist/cli/commands/start.js.map +1 -1
  86. package/dist/components/components.jsonld +1 -0
  87. package/dist/components/context.jsonld +36 -0
  88. package/dist/http/InternalPodDataHttpHandler.d.ts +32 -0
  89. package/dist/http/InternalPodDataHttpHandler.js +258 -0
  90. package/dist/http/InternalPodDataHttpHandler.js.map +1 -0
  91. package/dist/http/InternalPodDataHttpHandler.jsonld +201 -0
  92. package/dist/index.d.ts +2 -1
  93. package/dist/index.js +4 -2
  94. package/dist/index.js.map +1 -1
  95. package/dist/main.js +13 -13
  96. package/dist/main.js.map +1 -1
  97. package/dist/runtime/GatewayAdminProxyAuth.d.ts +15 -1
  98. package/dist/runtime/GatewayAdminProxyAuth.js +57 -2
  99. package/dist/runtime/GatewayAdminProxyAuth.js.map +1 -1
  100. package/dist/runtime/bootstrap.js +3 -0
  101. package/dist/runtime/bootstrap.js.map +1 -1
  102. package/dist/runtime/css-process.d.ts +1 -1
  103. package/dist/runtime/css-process.js +4 -1
  104. package/dist/runtime/css-process.js.map +1 -1
  105. package/dist/runtime/runner/node/CommunitySolidServerCssRunner.d.ts +2 -0
  106. package/dist/runtime/runner/node/CommunitySolidServerCssRunner.js +50 -0
  107. package/dist/runtime/runner/node/CommunitySolidServerCssRunner.js.map +1 -1
  108. package/node_modules/@undefineds.co/ai-connection/dist/AiClientConfigurationSection.d.ts +5 -5
  109. package/node_modules/@undefineds.co/ai-connection/dist/AiClientConfigurationSection.js +7 -7
  110. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionMain.js +1 -1
  111. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionPanel.d.ts +3 -1
  112. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionPanel.js +74 -60
  113. package/node_modules/@undefineds.co/ai-connection/dist/ai-connection-client.d.ts +0 -21
  114. package/node_modules/@undefineds.co/ai-connection/dist/ai-connection-client.js +0 -41
  115. package/node_modules/@undefineds.co/ai-connection/dist/client-config/base-adapter.d.ts +1 -0
  116. package/node_modules/@undefineds.co/ai-connection/dist/client-config/base-adapter.js +7 -2
  117. package/node_modules/@undefineds.co/ai-connection/dist/client-config/codex.js +3 -3
  118. package/node_modules/@undefineds.co/ai-connection/dist/client-config/index.cjs +15 -9
  119. package/node_modules/@undefineds.co/ai-connection/dist/client-config/json-env-adapter.js +4 -4
  120. package/node_modules/@undefineds.co/ai-connection/dist/client-config/pi.js +3 -3
  121. package/node_modules/@undefineds.co/ai-connection/dist/client-config/types.d.ts +1 -1
  122. package/node_modules/@undefineds.co/ai-connection/dist/controller.d.ts +2 -1
  123. package/node_modules/@undefineds.co/ai-connection/dist/controller.js +1 -0
  124. package/node_modules/@undefineds.co/ai-connection/dist/service-access.js +0 -1
  125. package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +22 -1
  126. package/package.json +3 -3
  127. package/static/app/assets/main.js +7 -7
  128. package/static/dashboard/assets/NetworkPage-CXjiUMR1.js +2 -0
  129. package/static/dashboard/assets/{PaneListHeader-57nvMwH6.js → PaneListHeader-BSipfl0W.js} +1 -1
  130. package/static/dashboard/assets/PodPage-Bd3Xhmp-.js +2 -0
  131. package/static/dashboard/assets/ServicesPage-CI3jWZGe.js +1 -0
  132. package/static/dashboard/assets/{card-B9Zjf_2p.js → card-z5BV5hTo.js} +1 -1
  133. package/static/dashboard/assets/{dashboard-8C6o666W.js → dashboard-CSrqAv2L.js} +2 -2
  134. package/static/dashboard/assets/{database-DPh9wDY9.js → database-Ct5ZPe6L.js} +1 -1
  135. package/static/dashboard/assets/{external-link-VbMQvVMz.js → external-link-B7wD1hkm.js} +1 -1
  136. package/static/dashboard/assets/index-tOBaUnM1.js +44 -0
  137. package/static/dashboard/assets/{refresh-cw-BxVxNxNr.js → refresh-cw-CFDZPaE8.js} +1 -1
  138. package/static/dashboard/assets/{services-status-context-DKmJ7ISr.js → services-status-context-DN1Icg4A.js} +1 -1
  139. package/static/dashboard/dashboard.html +1 -1
  140. package/static/settings/assets/ModelsPage-D87RrLB0.js +1 -0
  141. package/static/settings/assets/{PaneListHeader-Bgaze006.js → PaneListHeader-BtON8Z5Q.js} +1 -1
  142. package/static/settings/assets/PodPage-9LGuOloQ.js +2 -0
  143. package/static/settings/assets/ServicesPage-ZoT9-B_0.js +1 -0
  144. package/static/settings/assets/SettingsPage-Bj4lB3mq.js +41 -0
  145. package/static/settings/assets/{card-B_bXSIn-.js → card-CCGngjas.js} +1 -1
  146. package/static/settings/assets/{services-status-context-DiX-AbrP.js → services-status-context-CBfImxL_.js} +1 -1
  147. package/static/settings/assets/{settings-B30oMfZq.js → settings-yUyFIJxi.js} +2 -2
  148. package/static/settings/assets/{workspace-layout-Dv1Yn9Ci.js → workspace-layout-B0wJpPze.js} +1 -1
  149. package/static/settings/settings.html +1 -1
  150. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.d.ts +0 -25
  151. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.js +0 -91
  152. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.js.map +0 -1
  153. package/dist/api/ai-gateway/auth/GatewayApiKey.d.ts +0 -28
  154. package/dist/api/ai-gateway/auth/GatewayApiKey.js +0 -162
  155. package/dist/api/ai-gateway/auth/GatewayApiKey.js.map +0 -1
  156. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.d.ts +0 -56
  157. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js +0 -143
  158. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js.map +0 -1
  159. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.d.ts +0 -26
  160. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.js +0 -97
  161. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.js.map +0 -1
  162. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.d.ts +0 -54
  163. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js +0 -152
  164. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js.map +0 -1
  165. package/static/dashboard/assets/NetworkPage-Brt79fuQ.js +0 -2
  166. package/static/dashboard/assets/PodPage-CM6do1vB.js +0 -2
  167. package/static/dashboard/assets/ServicesPage-BUNxGJRz.js +0 -1
  168. package/static/dashboard/assets/index-RfiFckzb.js +0 -51
  169. package/static/settings/assets/ModelsPage-D_IH7AH3.js +0 -1
  170. package/static/settings/assets/PodPage-Cy1VNObw.js +0 -2
  171. package/static/settings/assets/ServicesPage-BsFaxVWC.js +0 -1
  172. package/static/settings/assets/SettingsPage-UafNWE_p.js +0 -48
@@ -1 +1 @@
1
- {"version":3,"file":"InvocationTokenCodec.js","sourceRoot":"","sources":["../../../../src/api/ai-gateway/auth/InvocationTokenCodec.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'node:crypto';\nimport type { GatewayDeployment } from './GatewayApiKey';\nimport type { GatewayKeyLocatorSecret } from './GatewayKeyLocatorCodec';\n\nconst PREFIX = 'xpod_inv_v1';\nconst AAD_CONTEXT = 'xpod:gateway:internal-invocation:v1';\nconst NONCE_BYTES = 12;\nconst KEY_BYTES = 32;\nconst MAX_TOKEN_LENGTH = 8_192;\nconst MAX_CIPHERTEXT_BYTES = 4_096;\nconst MAX_TTL_MS = 15 * 60_000;\nconst MAX_SCOPES = 8;\n\nexport interface InvocationTokenClaims {\n version: 1;\n kid: string;\n deployment: GatewayDeployment;\n audience: string;\n issuer: string;\n webId: string;\n scopes: string[];\n issuedAt: Date;\n expiresAt: Date;\n jti: string;\n}\n\nexport interface InvocationTokenInput {\n deployment: GatewayDeployment;\n audience: string;\n issuer: string;\n webId: string;\n scopes: string[];\n issuedAt: Date;\n expiresAt: Date;\n jti?: string;\n}\n\nexport interface InvocationTokenCodec {\n encode(input: InvocationTokenInput): string;\n decode(token: string): InvocationTokenClaims | undefined;\n}\n\nexport interface AesInvocationTokenCodecOptions {\n active: GatewayKeyLocatorSecret;\n previous?: GatewayKeyLocatorSecret[];\n}\n\nexport class AesInvocationTokenCodec implements InvocationTokenCodec {\n private readonly active: { kid: string; key: Buffer };\n private readonly ring = new Map<string, Buffer>();\n\n public constructor(options: AesInvocationTokenCodecOptions) {\n this.active = normalizeSecret(options.active);\n this.ring.set(this.active.kid, this.active.key);\n for (const previous of options.previous ?? []) {\n const normalized = normalizeSecret(previous);\n if (this.ring.has(normalized.kid)) {\n throw new Error(`Duplicate invocation token key id: ${normalized.kid}`);\n }\n this.ring.set(normalized.kid, normalized.key);\n }\n }\n\n public encode(input: InvocationTokenInput): string {\n const webId = requireCanonicalWebId(input.webId);\n const audience = requireCanonicalOrigin(input.audience, 'audience');\n const issuer = requireCanonicalOrigin(input.issuer, 'issuer');\n const scopes = requireScopes(input.scopes);\n const issuedAt = requireTimestamp(input.issuedAt, 'issuedAt');\n const expiresAt = requireTimestamp(input.expiresAt, 'expiresAt');\n if (expiresAt <= issuedAt || expiresAt - issuedAt > MAX_TTL_MS) {\n throw new Error(`Invocation token TTL must be between 1 and ${MAX_TTL_MS} milliseconds`);\n }\n const payload = {\n v: 1,\n kid: this.active.kid,\n deployment: input.deployment,\n aud: audience,\n iss: issuer,\n webId,\n scopes,\n iat: issuedAt,\n exp: expiresAt,\n jti: input.jti ?? randomBytes(18).toString('base64url'),\n };\n const nonce = randomBytes(NONCE_BYTES);\n const aad = Buffer.from(`${AAD_CONTEXT}.${this.active.kid}`);\n const cipher = createCipheriv('aes-256-gcm', this.active.key, nonce);\n cipher.setAAD(aad);\n const ciphertext = Buffer.concat([\n cipher.update(JSON.stringify(payload), 'utf8'),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n return [\n PREFIX,\n this.active.kid,\n nonce.toString('base64url'),\n ciphertext.toString('base64url'),\n tag.toString('base64url'),\n ].join('.');\n }\n\n public decode(token: string): InvocationTokenClaims | undefined {\n if (token.length > MAX_TOKEN_LENGTH) {\n return undefined;\n }\n const parts = token.split('.');\n if (parts.length !== 5 || parts[0] !== PREFIX) {\n return undefined;\n }\n const kid = parts[1];\n const key = this.ring.get(kid);\n if (\n !key\n || !parts.slice(1).every((part) => /^[A-Za-z0-9_-]+$/u.test(part))\n ) {\n return undefined;\n }\n try {\n const nonce = decodeCanonicalBase64Url(parts[2]);\n const ciphertext = decodeCanonicalBase64Url(parts[3]);\n const tag = decodeCanonicalBase64Url(parts[4]);\n if (!nonce || !ciphertext || !tag) {\n return undefined;\n }\n if (\n nonce.length !== NONCE_BYTES\n || ciphertext.length === 0\n || ciphertext.length > MAX_CIPHERTEXT_BYTES\n || tag.length !== 16\n ) {\n return undefined;\n }\n const decipher = createDecipheriv('aes-256-gcm', key, nonce);\n decipher.setAAD(Buffer.from(`${AAD_CONTEXT}.${kid}`));\n decipher.setAuthTag(tag);\n const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n const parsed = JSON.parse(plaintext.toString('utf8')) as Record<string, unknown>;\n const keys = Object.keys(parsed).sort();\n if (\n keys.join(',') !== 'aud,deployment,exp,iat,iss,jti,kid,scopes,v,webId'\n ||\n parsed.v !== 1\n || parsed.kid !== kid\n || (parsed.deployment !== 'local' && parsed.deployment !== 'cloud')\n || typeof parsed.aud !== 'string'\n || typeof parsed.iss !== 'string'\n || typeof parsed.webId !== 'string'\n || !Array.isArray(parsed.scopes)\n || typeof parsed.iat !== 'number'\n || typeof parsed.exp !== 'number'\n || typeof parsed.jti !== 'string'\n || !/^[A-Za-z0-9_-]{16,128}$/u.test(parsed.jti)\n ) {\n return undefined;\n }\n const audience = requireCanonicalOrigin(parsed.aud, 'audience');\n const issuer = requireCanonicalOrigin(parsed.iss, 'issuer');\n const webId = requireCanonicalWebId(parsed.webId);\n const scopes = requireScopes(parsed.scopes);\n const issuedAt = requireEpoch(parsed.iat);\n const expiresAt = requireEpoch(parsed.exp);\n if (expiresAt <= issuedAt || expiresAt - issuedAt > MAX_TTL_MS) {\n return undefined;\n }\n return {\n version: 1,\n kid,\n deployment: parsed.deployment,\n audience,\n issuer,\n webId,\n scopes,\n issuedAt: new Date(issuedAt),\n expiresAt: new Date(expiresAt),\n jti: parsed.jti,\n };\n } catch {\n return undefined;\n }\n }\n}\n\nexport function requireCanonicalOrigin(value: string, name = 'origin'): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error(`Invocation token ${name} must be a canonical HTTP(S) origin`);\n }\n if (\n (url.protocol !== 'https:' && url.protocol !== 'http:')\n || url.username\n || url.password\n || url.pathname !== '/'\n || url.search\n || url.hash\n || url.origin !== value\n ) {\n throw new Error(`Invocation token ${name} must be a canonical HTTP(S) origin`);\n }\n return url.origin;\n}\n\nfunction decodeCanonicalBase64Url(value: string): Buffer | undefined {\n const decoded = Buffer.from(value, 'base64url');\n return decoded.toString('base64url') === value ? decoded : undefined;\n}\n\nfunction normalizeSecret(input: GatewayKeyLocatorSecret): { kid: string; key: Buffer } {\n const kid = input.kid.trim();\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u.test(kid)) {\n throw new Error('Invocation token key id is invalid');\n }\n if (!input.secret.trim()) {\n throw new Error('Invocation token secret is required');\n }\n return {\n kid,\n key: createHash('sha256')\n .update(`${AAD_CONTEXT}\\0`, 'utf8')\n .update(input.secret, 'utf8')\n .digest()\n .subarray(0, KEY_BYTES),\n };\n}\n\nexport function requireCanonicalWebId(value: string): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error('Invocation token WebID must be a canonical HTTP(S) URL');\n }\n if (\n (url.protocol !== 'https:' && url.protocol !== 'http:')\n || url.username\n || url.password\n || url.href !== value\n ) {\n throw new Error('Invocation token WebID must be a canonical HTTP(S) URL');\n }\n return url.href;\n}\n\nfunction requireScopes(value: unknown[]): string[] {\n if (\n value.length === 0\n || value.length > MAX_SCOPES\n || value.some((scope) => typeof scope !== 'string' || !/^[a-z][a-z0-9-]*:[a-z][a-z0-9-]*$/u.test(scope))\n || new Set(value).size !== value.length\n ) {\n throw new Error('Invocation token scopes are invalid');\n }\n return [...value] as string[];\n}\n\nfunction requireTimestamp(value: Date, name: string): number {\n const timestamp = value.getTime();\n if (!Number.isSafeInteger(timestamp) || timestamp < 0) {\n throw new Error(`Invocation token ${name} is invalid`);\n }\n return timestamp;\n}\n\nfunction requireEpoch(value: number): number {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new Error('Invocation token timestamp is invalid');\n }\n return value;\n}\n"]}
1
+ {"version":3,"file":"InvocationTokenCodec.js","sourceRoot":"","sources":["../../../../src/api/ai-gateway/auth/InvocationTokenCodec.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'node:crypto';\n\nconst PREFIX = 'xpod_inv_v1';\nconst AAD_CONTEXT = 'xpod:gateway:internal-invocation:v1';\nconst NONCE_BYTES = 12;\nconst KEY_BYTES = 32;\nconst MAX_TOKEN_LENGTH = 8_192;\nconst MAX_CIPHERTEXT_BYTES = 4_096;\nconst MAX_TTL_MS = 15 * 60_000;\nconst MAX_SCOPES = 8;\n\nexport interface InvocationTokenClaims {\n version: 1;\n kid: string;\n deployment: GatewayDeployment;\n audience: string;\n issuer: string;\n webId: string;\n scopes: string[];\n issuedAt: Date;\n expiresAt: Date;\n jti: string;\n}\n\nexport type GatewayDeployment = 'cloud' | 'local';\n\nexport interface InvocationTokenSecret {\n kid: string;\n secret: string;\n}\n\nexport interface InvocationTokenInput {\n deployment: GatewayDeployment;\n audience: string;\n issuer: string;\n webId: string;\n scopes: string[];\n issuedAt: Date;\n expiresAt: Date;\n jti?: string;\n}\n\nexport interface InvocationTokenCodec {\n encode(input: InvocationTokenInput): string;\n decode(token: string): InvocationTokenClaims | undefined;\n}\n\nexport interface AesInvocationTokenCodecOptions {\n active: InvocationTokenSecret;\n previous?: InvocationTokenSecret[];\n}\n\nexport class AesInvocationTokenCodec implements InvocationTokenCodec {\n private readonly active: { kid: string; key: Buffer };\n private readonly ring = new Map<string, Buffer>();\n\n public constructor(options: AesInvocationTokenCodecOptions) {\n this.active = normalizeSecret(options.active);\n this.ring.set(this.active.kid, this.active.key);\n for (const previous of options.previous ?? []) {\n const normalized = normalizeSecret(previous);\n if (this.ring.has(normalized.kid)) {\n throw new Error(`Duplicate invocation token key id: ${normalized.kid}`);\n }\n this.ring.set(normalized.kid, normalized.key);\n }\n }\n\n public encode(input: InvocationTokenInput): string {\n const webId = requireCanonicalWebId(input.webId);\n const audience = requireCanonicalOrigin(input.audience, 'audience');\n const issuer = requireCanonicalOrigin(input.issuer, 'issuer');\n const scopes = requireScopes(input.scopes);\n const issuedAt = requireTimestamp(input.issuedAt, 'issuedAt');\n const expiresAt = requireTimestamp(input.expiresAt, 'expiresAt');\n if (expiresAt <= issuedAt || expiresAt - issuedAt > MAX_TTL_MS) {\n throw new Error(`Invocation token TTL must be between 1 and ${MAX_TTL_MS} milliseconds`);\n }\n const payload = {\n v: 1,\n kid: this.active.kid,\n deployment: input.deployment,\n aud: audience,\n iss: issuer,\n webId,\n scopes,\n iat: issuedAt,\n exp: expiresAt,\n jti: input.jti ?? randomBytes(18).toString('base64url'),\n };\n const nonce = randomBytes(NONCE_BYTES);\n const aad = Buffer.from(`${AAD_CONTEXT}.${this.active.kid}`);\n const cipher = createCipheriv('aes-256-gcm', this.active.key, nonce);\n cipher.setAAD(aad);\n const ciphertext = Buffer.concat([\n cipher.update(JSON.stringify(payload), 'utf8'),\n cipher.final(),\n ]);\n const tag = cipher.getAuthTag();\n return [\n PREFIX,\n this.active.kid,\n nonce.toString('base64url'),\n ciphertext.toString('base64url'),\n tag.toString('base64url'),\n ].join('.');\n }\n\n public decode(token: string): InvocationTokenClaims | undefined {\n if (token.length > MAX_TOKEN_LENGTH) {\n return undefined;\n }\n const parts = token.split('.');\n if (parts.length !== 5 || parts[0] !== PREFIX) {\n return undefined;\n }\n const kid = parts[1];\n const key = this.ring.get(kid);\n if (\n !key\n || !parts.slice(1).every((part) => /^[A-Za-z0-9_-]+$/u.test(part))\n ) {\n return undefined;\n }\n try {\n const nonce = decodeCanonicalBase64Url(parts[2]);\n const ciphertext = decodeCanonicalBase64Url(parts[3]);\n const tag = decodeCanonicalBase64Url(parts[4]);\n if (!nonce || !ciphertext || !tag) {\n return undefined;\n }\n if (\n nonce.length !== NONCE_BYTES\n || ciphertext.length === 0\n || ciphertext.length > MAX_CIPHERTEXT_BYTES\n || tag.length !== 16\n ) {\n return undefined;\n }\n const decipher = createDecipheriv('aes-256-gcm', key, nonce);\n decipher.setAAD(Buffer.from(`${AAD_CONTEXT}.${kid}`));\n decipher.setAuthTag(tag);\n const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n const parsed = JSON.parse(plaintext.toString('utf8')) as Record<string, unknown>;\n const keys = Object.keys(parsed).sort();\n if (\n keys.join(',') !== 'aud,deployment,exp,iat,iss,jti,kid,scopes,v,webId'\n ||\n parsed.v !== 1\n || parsed.kid !== kid\n || (parsed.deployment !== 'local' && parsed.deployment !== 'cloud')\n || typeof parsed.aud !== 'string'\n || typeof parsed.iss !== 'string'\n || typeof parsed.webId !== 'string'\n || !Array.isArray(parsed.scopes)\n || typeof parsed.iat !== 'number'\n || typeof parsed.exp !== 'number'\n || typeof parsed.jti !== 'string'\n || !/^[A-Za-z0-9_-]{16,128}$/u.test(parsed.jti)\n ) {\n return undefined;\n }\n const audience = requireCanonicalOrigin(parsed.aud, 'audience');\n const issuer = requireCanonicalOrigin(parsed.iss, 'issuer');\n const webId = requireCanonicalWebId(parsed.webId);\n const scopes = requireScopes(parsed.scopes);\n const issuedAt = requireEpoch(parsed.iat);\n const expiresAt = requireEpoch(parsed.exp);\n if (expiresAt <= issuedAt || expiresAt - issuedAt > MAX_TTL_MS) {\n return undefined;\n }\n return {\n version: 1,\n kid,\n deployment: parsed.deployment,\n audience,\n issuer,\n webId,\n scopes,\n issuedAt: new Date(issuedAt),\n expiresAt: new Date(expiresAt),\n jti: parsed.jti,\n };\n } catch {\n return undefined;\n }\n }\n}\n\nexport function requireCanonicalOrigin(value: string, name = 'origin'): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error(`Invocation token ${name} must be a canonical HTTP(S) origin`);\n }\n if (\n (url.protocol !== 'https:' && url.protocol !== 'http:')\n || url.username\n || url.password\n || url.pathname !== '/'\n || url.search\n || url.hash\n || url.origin !== value\n ) {\n throw new Error(`Invocation token ${name} must be a canonical HTTP(S) origin`);\n }\n return url.origin;\n}\n\nfunction decodeCanonicalBase64Url(value: string): Buffer | undefined {\n const decoded = Buffer.from(value, 'base64url');\n return decoded.toString('base64url') === value ? decoded : undefined;\n}\n\nfunction normalizeSecret(input: InvocationTokenSecret): { kid: string; key: Buffer } {\n const kid = input.kid.trim();\n if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u.test(kid)) {\n throw new Error('Invocation token key id is invalid');\n }\n if (!input.secret.trim()) {\n throw new Error('Invocation token secret is required');\n }\n return {\n kid,\n key: createHash('sha256')\n .update(`${AAD_CONTEXT}\\0`, 'utf8')\n .update(input.secret, 'utf8')\n .digest()\n .subarray(0, KEY_BYTES),\n };\n}\n\nexport function requireCanonicalWebId(value: string): string {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error('Invocation token WebID must be a canonical HTTP(S) URL');\n }\n if (\n (url.protocol !== 'https:' && url.protocol !== 'http:')\n || url.username\n || url.password\n || url.href !== value\n ) {\n throw new Error('Invocation token WebID must be a canonical HTTP(S) URL');\n }\n return url.href;\n}\n\nfunction requireScopes(value: unknown[]): string[] {\n if (\n value.length === 0\n || value.length > MAX_SCOPES\n || value.some((scope) => typeof scope !== 'string' || !/^[a-z][a-z0-9-]*:[a-z][a-z0-9-]*$/u.test(scope))\n || new Set(value).size !== value.length\n ) {\n throw new Error('Invocation token scopes are invalid');\n }\n return [...value] as string[];\n}\n\nfunction requireTimestamp(value: Date, name: string): number {\n const timestamp = value.getTime();\n if (!Number.isSafeInteger(timestamp) || timestamp < 0) {\n throw new Error(`Invocation token ${name} is invalid`);\n }\n return timestamp;\n}\n\nfunction requireEpoch(value: number): number {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new Error('Invocation token timestamp is invalid');\n }\n return value;\n}\n"]}
@@ -1,10 +1,9 @@
1
1
  import { aiProviderResource, credentialResource } from '@undefineds.co/models';
2
- import type { EncryptedCredentialSecret } from '../credentials/KeyWrapper';
3
- import type { CredentialVault, ProviderSecret } from '../credentials/CredentialVault';
4
- import type { GatewayDeployment } from '../auth/GatewayApiKey';
2
+ import type { ProviderSecret } from '../credentials/CredentialVault';
3
+ import type { GatewayDeployment } from '../auth/InvocationTokenCodec';
5
4
  import type { ProviderRegistry } from '../providers/ProviderRegistry';
6
5
  import type { AuthContext } from '../../auth/AuthContext';
7
- import type { InternalPodAccessTokenProvider } from '../auth/PodGatewayAccessKeyRepository';
6
+ import type { InternalPodAccessTokenProvider } from '../pod/HostedPodDataAccess';
8
7
  export type ConnectMode = 'browserAssistedApiKey' | 'deviceCodeOAuth' | 'connectUnsupported';
9
8
  export type ConnectAttemptStatus = 'pending' | 'authorization_pending' | 'slow_down' | 'completed' | 'expired' | 'unsupported';
10
9
  export interface ConnectBeginInput {
@@ -74,7 +73,8 @@ export interface ConnectCredentialRecord {
74
73
  provider: string;
75
74
  deployment: GatewayDeployment;
76
75
  authMode: 'apiKey' | 'deviceCodeOAuth';
77
- encryptedSecret: EncryptedCredentialSecret;
76
+ storageMode: 'plaintext-v1';
77
+ secretPayload: string;
78
78
  status: 'active' | 'revoked';
79
79
  accountLabel?: string;
80
80
  expiresAt?: Date;
@@ -100,14 +100,6 @@ export interface PodCredentialRepository {
100
100
  upsertConnectedCredential(record: ConnectCredentialRecord, context?: {
101
101
  auth?: AuthContext;
102
102
  }): Promise<ConnectCredentialRecord>;
103
- rewrapCredential?(input: {
104
- webId: string;
105
- deployment: GatewayDeployment;
106
- credentialId: string;
107
- expectedVersion?: number;
108
- encryptedSecret: EncryptedCredentialSecret;
109
- auth?: AuthContext;
110
- }): Promise<boolean>;
111
103
  markReauthRequired(input: {
112
104
  webId: string;
113
105
  provider: string;
@@ -191,7 +183,8 @@ export declare class PodConnectedCredentialRepository implements PodCredentialRe
191
183
  quota?: {
192
184
  status: 'available' | 'unsupported' | 'exhausted' | 'error';
193
185
  };
194
- encryptedSecret: EncryptedCredentialSecret;
186
+ storageMode: 'plaintext-v1';
187
+ secretPayload: string;
195
188
  version?: number;
196
189
  runtimeCredential?: Record<string, unknown>;
197
190
  metadata?: Record<string, unknown>;
@@ -199,14 +192,6 @@ export declare class PodConnectedCredentialRepository implements PodCredentialRe
199
192
  upsertConnectedCredential(record: ConnectCredentialRecord, context?: {
200
193
  auth?: AuthContext;
201
194
  }): Promise<ConnectCredentialRecord>;
202
- rewrapCredential(input: {
203
- webId: string;
204
- deployment: GatewayDeployment;
205
- credentialId: string;
206
- expectedVersion?: number;
207
- encryptedSecret: EncryptedCredentialSecret;
208
- auth?: AuthContext;
209
- }): Promise<boolean>;
210
195
  markReauthRequired(input: {
211
196
  webId: string;
212
197
  provider: string;
@@ -272,7 +257,6 @@ export interface BrowserAssistedApiKeyConnectAdapterOptions {
272
257
  consoleUrl: string;
273
258
  attempts: InMemoryConnectAttemptStore;
274
259
  credentialRepository: PodCredentialRepository;
275
- vault: CredentialVault;
276
260
  deployment: GatewayDeployment;
277
261
  now?: () => Date;
278
262
  randomBytes?: (bytes: number) => Buffer;
@@ -283,7 +267,6 @@ export declare class BrowserAssistedApiKeyConnectAdapter implements ProviderConn
283
267
  private readonly consoleUrl;
284
268
  protected readonly attempts: InMemoryConnectAttemptStore;
285
269
  protected readonly credentialRepository: PodCredentialRepository;
286
- protected readonly vault: CredentialVault;
287
270
  protected readonly deployment: GatewayDeployment;
288
271
  protected readonly now: () => Date;
289
272
  protected readonly randomBytes: (bytes: number) => Buffer;
@@ -327,7 +310,6 @@ export interface ProviderConnectServiceOptions {
327
310
  registry: ProviderRegistry;
328
311
  adapters: ProviderConnectAdapter[];
329
312
  credentialRepository?: PodCredentialRepository;
330
- vault?: CredentialVault;
331
313
  }
332
314
  export interface ProviderConnectionSummary {
333
315
  provider: string;
@@ -347,7 +329,6 @@ export interface ProviderConnectionSummary {
347
329
  export declare class ProviderConnectService {
348
330
  private readonly registry;
349
331
  private readonly credentialRepository?;
350
- private readonly vault?;
351
332
  private readonly adapters;
352
333
  constructor(options: ProviderConnectServiceOptions);
353
334
  begin(input: ConnectBeginInput): Promise<ConnectBeginResult>;
@@ -4,6 +4,7 @@ exports.ProviderConnectService = exports.DeepSeekConnectAdapter = exports.KimiDe
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
6
6
  const models_1 = require("@undefineds.co/models");
7
+ const PlaintextCredentialPayload_1 = require("../credentials/PlaintextCredentialPayload");
7
8
  const ProviderRegistry_1 = require("../providers/ProviderRegistry");
8
9
  class PodConnectedCredentialRepository {
9
10
  constructor(options = {}) {
@@ -18,7 +19,7 @@ class PodConnectedCredentialRepository {
18
19
  const { db, credential } = await this.dbForOwner(input.webId, input.auth);
19
20
  const id = models_1.aiRuntimeRepository.credentialId(input);
20
21
  const row = await db.findById(credential, id);
21
- const record = row ? recordFromCredentialRow(row) : undefined;
22
+ const record = row ? recordFromCredentialRow(row, input.webId) : undefined;
22
23
  if (!record) {
23
24
  return undefined;
24
25
  }
@@ -42,7 +43,7 @@ class PodConnectedCredentialRepository {
42
43
  }
43
44
  }))).filter((row) => row !== null);
44
45
  return rows
45
- .map(recordFromCredentialRow)
46
+ .map((row) => recordFromCredentialRow(row, input.webId))
46
47
  .filter((record) => record.webId === input.webId)
47
48
  .filter((record) => record.deployment === input.deployment)
48
49
  .filter((record) => record.status === 'active')
@@ -57,7 +58,8 @@ class PodConnectedCredentialRepository {
57
58
  priority: priorityFromMetadata(record.metadata),
58
59
  health: record.reauthRequired ? 'reauthRequired' : 'healthy',
59
60
  quota: { status: 'available' },
60
- encryptedSecret: record.encryptedSecret,
61
+ storageMode: record.storageMode,
62
+ secretPayload: record.secretPayload,
61
63
  version: record.version,
62
64
  runtimeCredential: runtimeCredentialFromMetadata(record.metadata),
63
65
  metadata: record.metadata,
@@ -77,36 +79,10 @@ class PodConnectedCredentialRepository {
77
79
  });
78
80
  if (existing) {
79
81
  const updated = await db.updateById(credential, record.id, row);
80
- return recordFromCredentialRow(updated ?? row);
82
+ return recordFromCredentialRow(updated ?? row, record.webId);
81
83
  }
82
84
  await db.insert(credential).values(row).execute();
83
- return recordFromCredentialRow(row);
84
- }
85
- async rewrapCredential(input) {
86
- const { db, credential } = await this.dbForOwner(input.webId, input.auth);
87
- const existing = await db.findById(credential, input.credentialId);
88
- if (!existing) {
89
- return false;
90
- }
91
- const current = recordFromCredentialRow(existing);
92
- if (current.webId !== input.webId || current.deployment !== input.deployment) {
93
- return false;
94
- }
95
- const currentVersion = versionFromRow(existing);
96
- if (input.expectedVersion === undefined || currentVersion !== input.expectedVersion) {
97
- return false;
98
- }
99
- const updated = await db.update(credential)
100
- .set({
101
- encryptedSecret: JSON.stringify(input.encryptedSecret),
102
- wrappedDataKey: input.encryptedSecret.wrappedDek,
103
- encryptionAlgorithm: input.encryptedSecret.algorithm,
104
- keyVersion: String(currentVersion + 1),
105
- })
106
- .where((0, drizzle_solid_1.and)((0, drizzle_solid_1.eq)(credential.id, input.credentialId), (0, drizzle_solid_1.eq)(credential.keyVersion, String(input.expectedVersion))))
107
- .returning()
108
- .execute();
109
- return updated.length === 1;
85
+ return recordFromCredentialRow(row, record.webId);
110
86
  }
111
87
  async markReauthRequired(input) {
112
88
  const { db, credential } = await this.dbForOwner(input.webId, input.auth);
@@ -124,7 +100,7 @@ class PodConnectedCredentialRepository {
124
100
  status: 'active',
125
101
  keyVersion: String(existingVersion + 1),
126
102
  });
127
- return updated ? recordFromCredentialRow(updated) : undefined;
103
+ return updated ? recordFromCredentialRow(updated, input.webId) : undefined;
128
104
  }
129
105
  async disconnect(input) {
130
106
  const { db, credential } = await this.dbForOwner(input.webId, input.auth);
@@ -137,18 +113,18 @@ class PodConnectedCredentialRepository {
137
113
  status: 'revoked',
138
114
  keyVersion: String(versionFromRow(existing) + 1),
139
115
  });
140
- return updated ? recordFromCredentialRow(updated) : undefined;
116
+ return updated ? recordFromCredentialRow(updated, input.webId) : undefined;
141
117
  }
142
118
  async dbForOwner(owner, auth) {
143
- const trustedFetch = await this.resolveTrustedFetch(owner);
119
+ const trustedFetch = await this.resolveTrustedFetch(owner, auth);
144
120
  const credential = (0, drizzle_solid_1.alias)(this.credentialTemplate, 'credential');
145
121
  const aiProvider = (0, drizzle_solid_1.alias)(this.aiProviderTemplate, 'aiProvider');
146
122
  const db = await this.dbFactory({ owner, auth, fetch: trustedFetch, credential, aiProvider });
147
123
  await db.init?.(credential, aiProvider);
148
124
  return { db, credential };
149
125
  }
150
- async resolveTrustedFetch(owner) {
151
- const trustedFetch = await this.internalPodAccess?.getTrustedFetch(owner);
126
+ async resolveTrustedFetch(owner, auth) {
127
+ const trustedFetch = await this.internalPodAccess?.getTrustedFetch(owner, auth);
152
128
  if (!trustedFetch) {
153
129
  throw new Error('AI Connection service identity is not configured');
154
130
  }
@@ -261,7 +237,6 @@ class BrowserAssistedApiKeyConnectAdapter {
261
237
  this.consoleUrl = options.consoleUrl;
262
238
  this.attempts = options.attempts;
263
239
  this.credentialRepository = options.credentialRepository;
264
- this.vault = options.vault;
265
240
  this.deployment = options.deployment;
266
241
  this.now = options.now ?? (() => new Date());
267
242
  this.randomBytes = options.randomBytes ?? node_crypto_1.randomBytes;
@@ -297,7 +272,7 @@ class BrowserAssistedApiKeyConnectAdapter {
297
272
  deployment: input.deployment,
298
273
  provider: this.provider,
299
274
  });
300
- const encryptedSecret = await this.vault.seal(principal(input.webId), credentialIri, this.provider, { type: 'apiKey', apiKey: input.apiKey });
275
+ const secretPayload = (0, PlaintextCredentialPayload_1.encodePlaintextCredential)({ type: 'apiKey', apiKey: input.apiKey });
301
276
  const record = await this.credentialRepository.upsertConnectedCredential({
302
277
  id: models_1.aiRuntimeRepository.credentialId({ deployment: input.deployment, provider: this.provider }),
303
278
  credentialIri,
@@ -305,7 +280,8 @@ class BrowserAssistedApiKeyConnectAdapter {
305
280
  provider: this.provider,
306
281
  deployment: input.deployment,
307
282
  authMode: 'apiKey',
308
- encryptedSecret,
283
+ storageMode: PlaintextCredentialPayload_1.PLAINTEXT_CREDENTIAL_STORAGE_MODE,
284
+ secretPayload,
309
285
  status: 'active',
310
286
  accountLabel: input.accountLabel,
311
287
  expectedVersion: consumed.expectedCredentialVersion,
@@ -601,7 +577,6 @@ class KimiDeviceCodeConnectAdapter extends BrowserAssistedApiKeyConnectAdapter {
601
577
  scope: stringFrom(body.scope),
602
578
  idToken: stringFrom(body.id_token),
603
579
  };
604
- const encryptedSecret = await this.vault.seal(principal(input.webId), credentialIri, 'kimi', secret);
605
580
  return this.credentialRepository.upsertConnectedCredential({
606
581
  id: models_1.aiRuntimeRepository.credentialId({ deployment: input.deployment, provider: 'kimi' }),
607
582
  credentialIri,
@@ -609,7 +584,8 @@ class KimiDeviceCodeConnectAdapter extends BrowserAssistedApiKeyConnectAdapter {
609
584
  provider: 'kimi',
610
585
  deployment: input.deployment,
611
586
  authMode: 'deviceCodeOAuth',
612
- encryptedSecret,
587
+ storageMode: PlaintextCredentialPayload_1.PLAINTEXT_CREDENTIAL_STORAGE_MODE,
588
+ secretPayload: (0, PlaintextCredentialPayload_1.encodePlaintextCredential)(secret),
613
589
  status: 'active',
614
590
  expiresAt,
615
591
  expectedVersion,
@@ -644,7 +620,6 @@ class ProviderConnectService {
644
620
  this.adapters = new Map();
645
621
  this.registry = options.registry;
646
622
  this.credentialRepository = options.credentialRepository;
647
- this.vault = options.vault;
648
623
  for (const adapter of options.adapters) {
649
624
  this.adapters.set(normalizeProvider(adapter.provider), adapter);
650
625
  }
@@ -733,14 +708,14 @@ class ProviderConnectService {
733
708
  if (!adapter.refresh) {
734
709
  throw new Error('Provider does not support refresh');
735
710
  }
736
- if (!this.credentialRepository || !this.vault) {
737
- throw new Error('CredentialVault and PodCredentialRepository are required for provider refresh');
711
+ if (!this.credentialRepository) {
712
+ throw new Error('PodCredentialRepository is required for provider refresh');
738
713
  }
739
714
  const current = await this.credentialRepository.getActiveCredential(input);
740
715
  if (!current) {
741
716
  throw new Error('Active provider credential not found');
742
717
  }
743
- const secret = await this.vault.open({ webId: input.webId }, current.credentialIri, normalizeProvider(input.provider), current.encryptedSecret);
718
+ const secret = (0, PlaintextCredentialPayload_1.decodePlaintextCredential)(current);
744
719
  try {
745
720
  return await adapter.refresh(input, current, secret);
746
721
  }
@@ -794,9 +769,8 @@ function credentialRowFromRecord(record) {
794
769
  service: 'ai',
795
770
  authMode: record.authMode,
796
771
  status: record.status,
797
- encryptedSecret: JSON.stringify(record.encryptedSecret),
798
- wrappedDataKey: record.encryptedSecret.wrappedDek,
799
- encryptionAlgorithm: record.encryptedSecret.algorithm,
772
+ storageMode: record.storageMode,
773
+ secretPayload: record.secretPayload,
800
774
  keyVersion: String(record.version ?? 1),
801
775
  scopes: record.scopes ?? [],
802
776
  expiresAt: record.expiresAt,
@@ -806,21 +780,33 @@ function credentialRowFromRecord(record) {
806
780
  lastRefreshAt: new Date(),
807
781
  };
808
782
  }
809
- function recordFromCredentialRow(row) {
810
- const encrypted = parseEncryptedSecret(row.encryptedSecret);
783
+ function recordFromCredentialRow(row, owner) {
784
+ const storageMode = stringFrom(row.storageMode) === PlaintextCredentialPayload_1.PLAINTEXT_CREDENTIAL_STORAGE_MODE
785
+ ? PlaintextCredentialPayload_1.PLAINTEXT_CREDENTIAL_STORAGE_MODE
786
+ : stringFrom(row.storageMode);
787
+ const secretPayload = typeof row.secretPayload === 'string' ? row.secretPayload : '';
788
+ (0, PlaintextCredentialPayload_1.decodePlaintextCredential)({
789
+ storageMode,
790
+ secretPayload,
791
+ encryptedSecret: row.encryptedSecret,
792
+ wrappedDataKey: row.wrappedDataKey,
793
+ encryptionAlgorithm: row.encryptionAlgorithm,
794
+ });
811
795
  const id = stringFrom(row.id);
812
796
  const provider = providerFromRelation(stringFrom(row.provider))
813
797
  || providerFromCredentialId(id);
814
798
  const deployment = deploymentFromCredentialId(id);
815
- const webId = encrypted.webId;
799
+ const credentialIri = stringFrom(row.credentialIri)
800
+ || models_1.aiRuntimeRepository.credentialIri(owner, { deployment, provider });
816
801
  return {
817
802
  id,
818
- credentialIri: encrypted.credentialIri,
819
- webId,
803
+ credentialIri,
804
+ webId: owner,
820
805
  provider,
821
806
  deployment,
822
807
  authMode: stringFrom(row.authMode) === 'deviceCodeOAuth' ? 'deviceCodeOAuth' : 'apiKey',
823
- encryptedSecret: encrypted,
808
+ storageMode: PlaintextCredentialPayload_1.PLAINTEXT_CREDENTIAL_STORAGE_MODE,
809
+ secretPayload,
824
810
  status: stringFrom(row.status) === 'revoked' ? 'revoked' : 'active',
825
811
  accountLabel: stringFrom(row.accountLabel) || stringFrom(row.label) || undefined,
826
812
  expiresAt: dateFrom(row.expiresAt),
@@ -884,16 +870,6 @@ function runtimeCredentialFromMetadata(metadata) {
884
870
  ? value
885
871
  : undefined;
886
872
  }
887
- function parseEncryptedSecret(value) {
888
- if (typeof value !== 'string' || !value.trim()) {
889
- throw new Error('Credential row is missing encrypted secret payload');
890
- }
891
- const parsed = JSON.parse(value);
892
- if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
893
- throw new Error('Credential row encrypted secret payload is invalid');
894
- }
895
- return parsed;
896
- }
897
873
  function versionFromRow(row) {
898
874
  const value = row.keyVersion;
899
875
  if (typeof value === 'number' && Number.isFinite(value)) {
@@ -943,9 +919,6 @@ function signatureMatches(actual, expected) {
943
919
  function codeChallenge(verifier) {
944
920
  return (0, node_crypto_1.createHash)('sha256').update(verifier).digest('base64url');
945
921
  }
946
- function principal(webId) {
947
- return { webId };
948
- }
949
922
  function cloneAttempt(attempt) {
950
923
  return {
951
924
  ...attempt,