@elizaos/plugin-elizacloud 2.0.0-alpha.7 → 2.0.0-beta.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 (378) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +220 -0
  3. package/auto-enable.ts +17 -0
  4. package/dist/browser/index.browser.js +2 -21
  5. package/dist/browser/index.browser.js.map +5 -37
  6. package/dist/cjs/index.d.ts +2 -2
  7. package/dist/cjs/index.node.cjs +12173 -2271
  8. package/dist/cjs/index.node.js.map +135 -27
  9. package/dist/cloud/auth.d.ts +19 -0
  10. package/dist/cloud/auth.d.ts.map +1 -0
  11. package/dist/cloud/auth.js +330 -0
  12. package/dist/cloud/auth.js.map +12 -0
  13. package/dist/cloud/backup.d.ts +18 -0
  14. package/dist/cloud/backup.d.ts.map +1 -0
  15. package/dist/cloud/backup.js +63 -0
  16. package/dist/cloud/backup.js.map +10 -0
  17. package/dist/cloud/base-url.d.ts +3 -0
  18. package/dist/cloud/base-url.d.ts.map +1 -0
  19. package/dist/cloud/base-url.js +77 -0
  20. package/dist/cloud/base-url.js.map +10 -0
  21. package/dist/cloud/bridge-client.d.ts +126 -0
  22. package/dist/cloud/bridge-client.d.ts.map +1 -0
  23. package/dist/cloud/bridge-client.js +432 -0
  24. package/dist/cloud/bridge-client.js.map +11 -0
  25. package/dist/cloud/cloud-api-key.d.ts +26 -0
  26. package/dist/cloud/cloud-api-key.d.ts.map +1 -0
  27. package/dist/cloud/cloud-api-key.js +60 -0
  28. package/dist/cloud/cloud-api-key.js.map +10 -0
  29. package/dist/cloud/cloud-manager.d.ts +33 -0
  30. package/dist/cloud/cloud-manager.d.ts.map +1 -0
  31. package/dist/cloud/cloud-manager.js +853 -0
  32. package/dist/cloud/cloud-manager.js.map +16 -0
  33. package/dist/cloud/cloud-proxy.d.ts +20 -0
  34. package/dist/cloud/cloud-proxy.d.ts.map +1 -0
  35. package/dist/cloud/cloud-proxy.js +54 -0
  36. package/dist/cloud/cloud-proxy.js.map +10 -0
  37. package/dist/cloud/cloud-wallet.d.ts +94 -0
  38. package/dist/cloud/cloud-wallet.d.ts.map +1 -0
  39. package/dist/cloud/cloud-wallet.js +5195 -0
  40. package/dist/cloud/cloud-wallet.js.map +92 -0
  41. package/dist/cloud/index.d.ts +9 -0
  42. package/dist/cloud/index.d.ts.map +1 -0
  43. package/dist/cloud/index.js +30 -0
  44. package/dist/cloud/index.js.map +9 -0
  45. package/dist/cloud/reconnect.d.ts +26 -0
  46. package/dist/cloud/reconnect.d.ts.map +1 -0
  47. package/dist/cloud/reconnect.js +104 -0
  48. package/dist/cloud/reconnect.js.map +10 -0
  49. package/dist/cloud/validate-url.d.ts +2 -0
  50. package/dist/cloud/validate-url.d.ts.map +1 -0
  51. package/dist/cloud/validate-url.js +174 -0
  52. package/dist/cloud/validate-url.js.map +10 -0
  53. package/dist/cloud-providers/cloud-status.d.ts.map +1 -1
  54. package/dist/cloud-providers/cloud-status.js +78 -0
  55. package/dist/cloud-providers/cloud-status.js.map +10 -0
  56. package/dist/cloud-providers/container-health.d.ts.map +1 -1
  57. package/dist/cloud-providers/container-health.js +74 -0
  58. package/dist/cloud-providers/container-health.js.map +10 -0
  59. package/dist/cloud-providers/credit-balance.d.ts.map +1 -1
  60. package/dist/cloud-providers/credit-balance.js +85 -0
  61. package/dist/cloud-providers/credit-balance.js.map +10 -0
  62. package/dist/cloud-providers/index.d.ts.map +1 -1
  63. package/dist/cloud-providers/index.js +24 -0
  64. package/dist/cloud-providers/index.js.map +9 -0
  65. package/dist/cloud-providers/model-registry.d.ts.map +1 -1
  66. package/dist/cloud-providers/model-registry.js +71 -0
  67. package/dist/cloud-providers/model-registry.js.map +10 -0
  68. package/dist/index.browser.d.ts +4 -2
  69. package/dist/index.browser.d.ts.map +1 -1
  70. package/dist/index.d.ts +18 -0
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +12851 -0
  73. package/dist/index.js.map +145 -0
  74. package/dist/index.node.d.ts +15 -2
  75. package/dist/index.node.d.ts.map +1 -1
  76. package/dist/init.d.ts.map +1 -1
  77. package/dist/init.js +169 -0
  78. package/dist/init.js.map +12 -0
  79. package/dist/lib/cloud-connection.d.ts +78 -0
  80. package/dist/lib/cloud-connection.d.ts.map +1 -0
  81. package/dist/lib/cloud-connection.js +731 -0
  82. package/dist/lib/cloud-connection.js.map +14 -0
  83. package/dist/lib/cloud-secrets.d.ts +23 -0
  84. package/dist/lib/cloud-secrets.d.ts.map +1 -0
  85. package/dist/lib/cloud-secrets.js +64 -0
  86. package/dist/lib/cloud-secrets.js.map +10 -0
  87. package/dist/lib/config-env.d.ts +5 -0
  88. package/dist/lib/config-env.d.ts.map +1 -0
  89. package/dist/lib/config-env.js +191 -0
  90. package/dist/lib/config-env.js.map +11 -0
  91. package/dist/lib/config-like.d.ts +40 -0
  92. package/dist/lib/config-like.d.ts.map +1 -0
  93. package/dist/lib/config-like.js +103 -0
  94. package/dist/lib/config-like.js.map +10 -0
  95. package/dist/lib/credential-type-map.d.ts +53 -0
  96. package/dist/lib/credential-type-map.d.ts.map +1 -0
  97. package/dist/lib/credential-type-map.js +88 -0
  98. package/dist/lib/credential-type-map.js.map +10 -0
  99. package/dist/lib/feature-flags.d.ts +2 -0
  100. package/dist/lib/feature-flags.d.ts.map +1 -0
  101. package/dist/lib/feature-flags.js +40 -0
  102. package/dist/lib/feature-flags.js.map +10 -0
  103. package/dist/lib/http.d.ts +22 -0
  104. package/dist/lib/http.d.ts.map +1 -0
  105. package/dist/lib/http.js +107 -0
  106. package/dist/lib/http.js.map +10 -0
  107. package/dist/lib/server-cloud-tts.d.ts +34 -0
  108. package/dist/lib/server-cloud-tts.d.ts.map +1 -0
  109. package/dist/lib/server-cloud-tts.js +549 -0
  110. package/dist/lib/server-cloud-tts.js.map +13 -0
  111. package/dist/lib/state-paths.d.ts +4 -0
  112. package/dist/lib/state-paths.d.ts.map +1 -0
  113. package/dist/lib/state-paths.js +52 -0
  114. package/dist/lib/state-paths.js.map +10 -0
  115. package/dist/lib/tts-debug.d.ts +4 -0
  116. package/dist/lib/tts-debug.d.ts.map +1 -0
  117. package/dist/lib/tts-debug.js +57 -0
  118. package/dist/lib/tts-debug.js.map +10 -0
  119. package/dist/models/embeddings.d.ts.map +1 -1
  120. package/dist/models/embeddings.js +319 -0
  121. package/dist/models/embeddings.js.map +13 -0
  122. package/dist/models/image.d.ts.map +1 -1
  123. package/dist/models/image.js +374 -0
  124. package/dist/models/image.js.map +14 -0
  125. package/dist/models/index.d.ts +1 -2
  126. package/dist/models/index.d.ts.map +1 -1
  127. package/dist/models/index.js +1386 -0
  128. package/dist/models/index.js.map +20 -0
  129. package/dist/models/research.d.ts.map +1 -1
  130. package/dist/models/research.js +324 -0
  131. package/dist/models/research.js.map +13 -0
  132. package/dist/models/speech.d.ts.map +1 -1
  133. package/dist/models/speech.js +273 -0
  134. package/dist/models/speech.js.map +13 -0
  135. package/dist/models/text.d.ts +5 -2
  136. package/dist/models/text.d.ts.map +1 -1
  137. package/dist/models/text.js +803 -0
  138. package/dist/models/text.js.map +15 -0
  139. package/dist/models/tokenization.d.ts.map +1 -1
  140. package/dist/models/tokenization.js +65 -0
  141. package/dist/models/tokenization.js.map +10 -0
  142. package/dist/models/transcription.d.ts.map +1 -1
  143. package/dist/models/transcription.js +283 -0
  144. package/dist/models/transcription.js.map +13 -0
  145. package/dist/node/index.d.ts +2 -2
  146. package/dist/node/index.node.js +12171 -2266
  147. package/dist/node/index.node.js.map +135 -27
  148. package/dist/onboarding.d.ts +35 -0
  149. package/dist/onboarding.d.ts.map +1 -0
  150. package/dist/onboarding.js +883 -0
  151. package/dist/onboarding.js.map +14 -0
  152. package/dist/plugin.d.ts +20 -0
  153. package/dist/plugin.d.ts.map +1 -0
  154. package/dist/plugin.js +7611 -0
  155. package/dist/plugin.js.map +104 -0
  156. package/dist/providers/openai.d.ts.map +1 -1
  157. package/dist/providers/openai.js +127 -0
  158. package/dist/providers/openai.js.map +11 -0
  159. package/dist/register-routes.d.ts +2 -0
  160. package/dist/register-routes.d.ts.map +1 -0
  161. package/dist/register-routes.js +7612 -0
  162. package/dist/register-routes.js.map +105 -0
  163. package/dist/routes/cloud-billing-routes.d.ts +9 -0
  164. package/dist/routes/cloud-billing-routes.d.ts.map +1 -0
  165. package/dist/routes/cloud-billing-routes.js +807 -0
  166. package/dist/routes/cloud-billing-routes.js.map +14 -0
  167. package/dist/routes/cloud-compat-routes.d.ts +10 -0
  168. package/dist/routes/cloud-compat-routes.d.ts.map +1 -0
  169. package/dist/routes/cloud-compat-routes.js +538 -0
  170. package/dist/routes/cloud-compat-routes.js.map +14 -0
  171. package/dist/routes/cloud-features-routes.d.ts +9 -0
  172. package/dist/routes/cloud-features-routes.d.ts.map +1 -0
  173. package/dist/routes/cloud-features-routes.js +124 -0
  174. package/dist/routes/cloud-features-routes.js.map +11 -0
  175. package/dist/routes/cloud-provisioning.d.ts +14 -0
  176. package/dist/routes/cloud-provisioning.d.ts.map +1 -0
  177. package/dist/routes/cloud-provisioning.js +37 -0
  178. package/dist/routes/cloud-provisioning.js.map +10 -0
  179. package/dist/routes/cloud-relay-routes.d.ts +22 -0
  180. package/dist/routes/cloud-relay-routes.d.ts.map +1 -0
  181. package/dist/routes/cloud-relay-routes.js +60 -0
  182. package/dist/routes/cloud-relay-routes.js.map +10 -0
  183. package/dist/routes/cloud-routes-autonomous.d.ts +83 -0
  184. package/dist/routes/cloud-routes-autonomous.d.ts.map +1 -0
  185. package/dist/routes/cloud-routes-autonomous.js +6134 -0
  186. package/dist/routes/cloud-routes-autonomous.js.map +97 -0
  187. package/dist/routes/cloud-routes.d.ts +35 -0
  188. package/dist/routes/cloud-routes.d.ts.map +1 -0
  189. package/dist/routes/cloud-routes.js +6888 -0
  190. package/dist/routes/cloud-routes.js.map +100 -0
  191. package/dist/routes/cloud-status-routes-autonomous.d.ts +15 -0
  192. package/dist/routes/cloud-status-routes-autonomous.d.ts.map +1 -0
  193. package/dist/routes/cloud-status-routes-autonomous.js +396 -0
  194. package/dist/routes/cloud-status-routes-autonomous.js.map +13 -0
  195. package/dist/routes/cloud-status-routes.d.ts +4 -0
  196. package/dist/routes/cloud-status-routes.d.ts.map +1 -0
  197. package/dist/routes/cloud-status-routes.js +771 -0
  198. package/dist/routes/cloud-status-routes.js.map +15 -0
  199. package/dist/services/cloud-auth.d.ts +140 -5
  200. package/dist/services/cloud-auth.d.ts.map +1 -1
  201. package/dist/services/cloud-auth.js +363 -0
  202. package/dist/services/cloud-auth.js.map +12 -0
  203. package/dist/services/cloud-backup.d.ts.map +1 -1
  204. package/dist/services/cloud-backup.js +176 -0
  205. package/dist/services/cloud-backup.js.map +11 -0
  206. package/dist/services/cloud-bootstrap.d.ts +38 -0
  207. package/dist/services/cloud-bootstrap.d.ts.map +1 -0
  208. package/dist/services/cloud-bootstrap.js +84 -0
  209. package/dist/services/cloud-bootstrap.js.map +10 -0
  210. package/dist/services/cloud-bridge.d.ts +1 -1
  211. package/dist/services/cloud-bridge.d.ts.map +1 -1
  212. package/dist/services/cloud-bridge.js +308 -0
  213. package/dist/services/cloud-bridge.js.map +11 -0
  214. package/dist/services/cloud-container.d.ts.map +1 -1
  215. package/dist/services/cloud-container.js +241 -0
  216. package/dist/services/cloud-container.js.map +11 -0
  217. package/dist/services/cloud-credential-provider.d.ts +55 -0
  218. package/dist/services/cloud-credential-provider.d.ts.map +1 -0
  219. package/dist/services/cloud-credential-provider.js +190 -0
  220. package/dist/services/cloud-credential-provider.js.map +11 -0
  221. package/dist/services/cloud-managed-gateway-relay.d.ts +38 -0
  222. package/dist/services/cloud-managed-gateway-relay.d.ts.map +1 -0
  223. package/dist/services/cloud-managed-gateway-relay.js +479 -0
  224. package/dist/services/cloud-managed-gateway-relay.js.map +10 -0
  225. package/dist/services/cloud-model-registry.d.ts.map +1 -1
  226. package/dist/services/cloud-model-registry.js +175 -0
  227. package/dist/services/cloud-model-registry.js.map +10 -0
  228. package/dist/services/index.d.ts +3 -1
  229. package/dist/services/index.d.ts.map +1 -1
  230. package/dist/services/index.js +29 -0
  231. package/dist/services/index.js.map +9 -0
  232. package/dist/types/cloud.d.ts +41 -19
  233. package/dist/types/cloud.d.ts.map +1 -1
  234. package/dist/types/cloud.js +52 -0
  235. package/dist/types/cloud.js.map +10 -0
  236. package/dist/types/index.d.ts +1 -1
  237. package/dist/types/index.d.ts.map +1 -1
  238. package/dist/types/index.js +24 -0
  239. package/dist/types/index.js.map +9 -0
  240. package/dist/utils/cloud-api.d.ts +2 -27
  241. package/dist/utils/cloud-api.d.ts.map +1 -1
  242. package/dist/utils/cloud-api.js +33 -0
  243. package/dist/utils/cloud-api.js.map +10 -0
  244. package/dist/utils/cloud-sdk/client.d.ts +133 -0
  245. package/dist/utils/cloud-sdk/client.d.ts.map +1 -0
  246. package/dist/utils/cloud-sdk/client.js +3561 -0
  247. package/dist/utils/cloud-sdk/client.js.map +13 -0
  248. package/dist/utils/cloud-sdk/http.d.ts +37 -0
  249. package/dist/utils/cloud-sdk/http.d.ts.map +1 -0
  250. package/dist/utils/cloud-sdk/http.js +237 -0
  251. package/dist/utils/cloud-sdk/http.js.map +11 -0
  252. package/dist/utils/cloud-sdk/index.d.ts +6 -0
  253. package/dist/utils/cloud-sdk/index.d.ts.map +1 -0
  254. package/dist/utils/cloud-sdk/index.js +29 -0
  255. package/dist/utils/cloud-sdk/index.js.map +9 -0
  256. package/dist/utils/cloud-sdk/public-routes.d.ts +5377 -0
  257. package/dist/utils/cloud-sdk/public-routes.d.ts.map +1 -0
  258. package/dist/utils/cloud-sdk/public-routes.js +2950 -0
  259. package/dist/utils/cloud-sdk/public-routes.js.map +10 -0
  260. package/dist/utils/cloud-sdk/types.cloud-api.d.ts +101 -0
  261. package/dist/utils/cloud-sdk/types.cloud-api.d.ts.map +1 -0
  262. package/dist/utils/cloud-sdk/types.cloud-api.js +2 -0
  263. package/dist/utils/cloud-sdk/types.cloud-api.js.map +9 -0
  264. package/dist/utils/cloud-sdk/types.d.ts +655 -0
  265. package/dist/utils/cloud-sdk/types.d.ts.map +1 -0
  266. package/dist/utils/cloud-sdk/types.js +29 -0
  267. package/dist/utils/cloud-sdk/types.js.map +10 -0
  268. package/dist/utils/config.d.ts +7 -3
  269. package/dist/utils/config.d.ts.map +1 -1
  270. package/dist/utils/config.js +137 -0
  271. package/dist/utils/config.js.map +10 -0
  272. package/dist/utils/events.d.ts.map +1 -1
  273. package/dist/utils/events.js +43 -0
  274. package/dist/utils/events.js.map +10 -0
  275. package/dist/utils/helpers.d.ts.map +1 -1
  276. package/dist/utils/helpers.js +103 -0
  277. package/dist/utils/helpers.js.map +10 -0
  278. package/dist/utils/responses-output.d.ts +13 -0
  279. package/dist/utils/responses-output.d.ts.map +1 -0
  280. package/dist/utils/responses-output.js +102 -0
  281. package/dist/utils/responses-output.js.map +10 -0
  282. package/dist/utils/sdk-client.d.ts +5 -0
  283. package/dist/utils/sdk-client.d.ts.map +1 -0
  284. package/dist/utils/sdk-client.js +144 -0
  285. package/dist/utils/sdk-client.js.map +11 -0
  286. package/package.json +108 -19
  287. package/src/cloud/auth.ts +175 -0
  288. package/src/cloud/backup.ts +46 -0
  289. package/src/cloud/base-url.ts +62 -0
  290. package/src/cloud/bridge-client.ts +602 -0
  291. package/src/cloud/cloud-api-key.ts +80 -0
  292. package/src/cloud/cloud-manager.ts +163 -0
  293. package/src/cloud/cloud-proxy.ts +52 -0
  294. package/src/cloud/cloud-wallet.ts +341 -0
  295. package/src/cloud/index.ts +28 -0
  296. package/src/cloud/reconnect.ts +111 -0
  297. package/src/cloud/validate-url.ts +181 -0
  298. package/src/cloud-providers/cloud-status.ts +75 -0
  299. package/src/cloud-providers/container-health.ts +68 -0
  300. package/src/cloud-providers/credit-balance.ts +70 -0
  301. package/src/cloud-providers/index.ts +3 -0
  302. package/src/cloud-providers/model-registry.ts +74 -0
  303. package/src/index.browser.ts +10 -0
  304. package/src/index.node.ts +39 -0
  305. package/src/index.ts +347 -0
  306. package/src/init.ts +39 -0
  307. package/src/lib/cloud-connection.ts +663 -0
  308. package/src/lib/cloud-secrets.ts +58 -0
  309. package/src/lib/config-env.ts +168 -0
  310. package/src/lib/config-like.ts +149 -0
  311. package/src/lib/credential-type-map.ts +130 -0
  312. package/src/lib/feature-flags.ts +26 -0
  313. package/src/lib/http.ts +139 -0
  314. package/src/lib/server-cloud-tts.ts +609 -0
  315. package/src/lib/state-paths.ts +28 -0
  316. package/src/lib/tts-debug.ts +34 -0
  317. package/src/models/embeddings.ts +234 -0
  318. package/src/models/image.ts +219 -0
  319. package/src/models/index.ts +16 -0
  320. package/src/models/research.ts +265 -0
  321. package/src/models/speech.ts +78 -0
  322. package/src/models/text.ts +899 -0
  323. package/src/models/tokenization.ts +67 -0
  324. package/src/models/transcription.ts +97 -0
  325. package/src/onboarding.ts +396 -0
  326. package/src/plugin.ts +243 -0
  327. package/src/providers/openai.ts +16 -0
  328. package/src/register-routes.ts +6 -0
  329. package/src/routes/cloud-billing-routes.ts +754 -0
  330. package/src/routes/cloud-compat-routes.ts +314 -0
  331. package/src/routes/cloud-features-routes.ts +57 -0
  332. package/src/routes/cloud-provisioning.ts +37 -0
  333. package/src/routes/cloud-relay-routes.ts +89 -0
  334. package/src/routes/cloud-routes-autonomous.ts +996 -0
  335. package/src/routes/cloud-routes.ts +576 -0
  336. package/src/routes/cloud-status-routes-autonomous.ts +234 -0
  337. package/src/routes/cloud-status-routes.ts +73 -0
  338. package/src/services/cloud-auth.ts +567 -0
  339. package/src/services/cloud-backup.ts +208 -0
  340. package/src/services/cloud-bootstrap.ts +108 -0
  341. package/src/services/cloud-bridge.ts +386 -0
  342. package/src/services/cloud-container.ts +297 -0
  343. package/src/services/cloud-credential-provider.ts +210 -0
  344. package/src/services/cloud-managed-gateway-relay.ts +663 -0
  345. package/src/services/cloud-model-registry.ts +202 -0
  346. package/src/services/index.ts +17 -0
  347. package/{types → src/types}/cloud.ts +52 -29
  348. package/{types → src/types}/index.ts +6 -0
  349. package/src/utils/cloud-api.ts +10 -0
  350. package/src/utils/cloud-sdk/client.ts +735 -0
  351. package/src/utils/cloud-sdk/http.ts +291 -0
  352. package/src/utils/cloud-sdk/index.ts +23 -0
  353. package/src/utils/cloud-sdk/public-routes.ts +5070 -0
  354. package/src/utils/cloud-sdk/types.cloud-api.ts +120 -0
  355. package/src/utils/cloud-sdk/types.ts +762 -0
  356. package/src/utils/config.ts +174 -0
  357. package/src/utils/events.ts +37 -0
  358. package/src/utils/helpers.ts +107 -0
  359. package/src/utils/responses-output.ts +115 -0
  360. package/src/utils/sdk-client.ts +37 -0
  361. package/dist/actions/check-credits.d.ts +0 -6
  362. package/dist/actions/check-credits.d.ts.map +0 -1
  363. package/dist/actions/freeze-agent.d.ts +0 -9
  364. package/dist/actions/freeze-agent.d.ts.map +0 -1
  365. package/dist/actions/index.d.ts +0 -5
  366. package/dist/actions/index.d.ts.map +0 -1
  367. package/dist/actions/provision-agent.d.ts +0 -8
  368. package/dist/actions/provision-agent.d.ts.map +0 -1
  369. package/dist/actions/resume-agent.d.ts +0 -9
  370. package/dist/actions/resume-agent.d.ts.map +0 -1
  371. package/dist/build.d.ts +0 -3
  372. package/dist/build.d.ts.map +0 -1
  373. package/dist/generated/specs/specs.d.ts +0 -55
  374. package/dist/generated/specs/specs.d.ts.map +0 -1
  375. package/dist/models/object.d.ts +0 -4
  376. package/dist/models/object.d.ts.map +0 -1
  377. package/dist/utils/forwarded-settings.d.ts +0 -8
  378. package/dist/utils/forwarded-settings.d.ts.map +0 -1
@@ -0,0 +1,567 @@
1
+ /**
2
+ * CloudAuthService — Eliza Cloud authentication entry points.
3
+ *
4
+ * Two distinct auth flows live here:
5
+ *
6
+ * 1. **Device auto-signup** (`authenticateWithDevice`) — convenience-only.
7
+ * Derives a hardware fingerprint and exchanges it for a free-tier API key
8
+ * against the cloud signup endpoint. The result is treated as opaque and
9
+ * is **never** trusted as inbound auth for the local Eliza dashboard.
10
+ * See `docs/security/remote-auth-hardening-plan.md` §7 for the explicit
11
+ * demotion rationale.
12
+ *
13
+ * 2. **Eliza Cloud SSO** (`getSsoRedirectUrl` / `exchangeCodeForSession`) —
14
+ * OAuth-style authorization-code flow against the cloud issuer. The
15
+ * callback handler in `app-core` (`api/auth/cloud-sso.ts`) consumes these
16
+ * methods to bind a verified cloud user to a local Identity. All error
17
+ * paths fail closed: the methods throw and the caller MUST refuse the
18
+ * request. There is no partial-claims fallback.
19
+ */
20
+
21
+ import {
22
+ type RuntimeEnvRecord,
23
+ type IAgentRuntime,
24
+ logger,
25
+ Service,
26
+ resolveApiSecurityConfig,
27
+ resolveDesktopApiPort,
28
+ } from "@elizaos/core";
29
+ import { createRemoteJWKSet, jwtVerify } from "jose";
30
+ import type { CloudCredentials, DeviceAuthResponse, DevicePlatform } from "../types/cloud";
31
+ import { DEFAULT_CLOUD_CONFIG } from "../types/cloud";
32
+ import { CloudApiClient } from "../utils/cloud-api";
33
+ import type { CloudBootstrapService } from "./cloud-bootstrap";
34
+
35
+ /** SHA-256 hash of hostname + platform + arch + cpu + memory. */
36
+ async function deriveDeviceId(): Promise<string> {
37
+ const os = await import("node:os");
38
+ const crypto = await import("node:crypto");
39
+ const cpus = os.cpus();
40
+ const raw = [
41
+ os.hostname(),
42
+ os.platform(),
43
+ os.arch(),
44
+ cpus[0]?.model ?? "?",
45
+ cpus.length,
46
+ os.totalmem(),
47
+ ].join(":");
48
+ return crypto.createHash("sha256").update(raw).digest("hex");
49
+ }
50
+
51
+ function detectPlatform(): DevicePlatform {
52
+ if (typeof process === "undefined") return "web";
53
+ const map: Record<string, DevicePlatform> = {
54
+ darwin: "macos",
55
+ win32: "windows",
56
+ linux: "linux",
57
+ };
58
+ return map[process.platform] ?? "linux";
59
+ }
60
+
61
+ // ─── Eliza Cloud SSO ───────────────────────────────────────────────────────
62
+
63
+ /**
64
+ * Required ID-token claims for an Eliza Cloud SSO exchange.
65
+ *
66
+ * `sub` is the cloud user id (canonical identity key). `email` and `name`
67
+ * are surfaced for UI display and identity provisioning. Anything else the
68
+ * cloud issuer adds is preserved on `extra` for callers that need it but
69
+ * is never required for auth decisions.
70
+ */
71
+ export interface CloudSsoIdTokenClaims {
72
+ iss: string;
73
+ sub: string;
74
+ aud: string | string[];
75
+ exp: number;
76
+ iat: number;
77
+ email: string;
78
+ email_verified?: boolean;
79
+ name: string;
80
+ picture?: string;
81
+ extra: Record<string, unknown>;
82
+ }
83
+
84
+ export interface CloudSsoSession {
85
+ cloudUserId: string;
86
+ email: string;
87
+ displayName: string;
88
+ claims: CloudSsoIdTokenClaims;
89
+ }
90
+
91
+ export interface SsoRedirectArgs {
92
+ /**
93
+ * Local URL the user should land on after the SSO round-trip
94
+ * (e.g. `/onboarding/setup`). The dashboard's callback route forwards
95
+ * to this once the session cookie is set; it is NOT sent to the cloud
96
+ * issuer.
97
+ */
98
+ returnTo?: string;
99
+ /**
100
+ * State nonce. The caller is responsible for generating this with
101
+ * `crypto.randomBytes(32)` and storing it server-side keyed by the
102
+ * issued cookie / pending exchange.
103
+ */
104
+ state: string;
105
+ /**
106
+ * Override for `ELIZA_CLOUD_CLIENT_ID`. Falls through to the env when
107
+ * unset; explicitly throws when neither is provided.
108
+ */
109
+ clientId?: string;
110
+ /** Allows tests to inject a synthetic env record. */
111
+ env?: RuntimeEnvRecord;
112
+ }
113
+
114
+ export interface ExchangeCodeArgs {
115
+ /** Authorization code returned on the SSO callback. */
116
+ code: string;
117
+ /** State value the cloud issuer echoed back on the callback. */
118
+ state: string;
119
+ /**
120
+ * State value the caller originally issued. Compared with `state` and
121
+ * mismatch causes a fail-closed throw before any network call is made.
122
+ */
123
+ expectedState: string;
124
+ /**
125
+ * Source for `getJwksUrl()`. The caller resolves this from the runtime
126
+ * service registry (`runtime.getService("CLOUD_BOOTSTRAP")`) so this
127
+ * file does not import from `app-core` directly.
128
+ */
129
+ bootstrap: CloudBootstrapService;
130
+ /** Allows tests to inject a fake fetch for the token endpoint. */
131
+ fetchImpl?: typeof fetch;
132
+ /** Allows tests to inject a synthetic env record. */
133
+ env?: RuntimeEnvRecord;
134
+ /** Optional override for the redirect URI; defaults to the local callback. */
135
+ redirectUri?: string;
136
+ }
137
+
138
+ interface RawTokenResponse {
139
+ id_token?: unknown;
140
+ access_token?: unknown;
141
+ token_type?: unknown;
142
+ expires_in?: unknown;
143
+ scope?: unknown;
144
+ }
145
+
146
+ interface ApiKeyAuthInput {
147
+ apiKey: string;
148
+ organizationId?: string;
149
+ userId?: string;
150
+ }
151
+
152
+ interface RawIdTokenPayload {
153
+ iss?: unknown;
154
+ sub?: unknown;
155
+ aud?: unknown;
156
+ exp?: unknown;
157
+ iat?: unknown;
158
+ email?: unknown;
159
+ email_verified?: unknown;
160
+ name?: unknown;
161
+ picture?: unknown;
162
+ [otherProperty: string]: unknown;
163
+ }
164
+
165
+ function readEnvKey(env: RuntimeEnvRecord, key: string): string | null {
166
+ const value = env[key];
167
+ if (typeof value !== "string") return null;
168
+ const trimmed = value.trim();
169
+ return trimmed.length > 0 ? trimmed : null;
170
+ }
171
+
172
+ function processEnv(): RuntimeEnvRecord {
173
+ if (typeof process === "undefined") return {};
174
+ return process.env as RuntimeEnvRecord;
175
+ }
176
+
177
+ /**
178
+ * Build the local SSO callback URL the cloud issuer will redirect back to.
179
+ *
180
+ * Reads `ELIZA_API_BIND` and the desktop API port from `@elizaos/core`'s
181
+ * runtime-env helper so the redirect_uri matches whatever the dashboard
182
+ * is actually serving on. Loopback binds default to `http://127.0.0.1:<port>`;
183
+ * non-loopback binds (cloud-provisioned containers) use `https://`.
184
+ */
185
+ function defaultRedirectUri(env: RuntimeEnvRecord): string {
186
+ const security = resolveApiSecurityConfig(env);
187
+ const port = resolveDesktopApiPort(env);
188
+ const scheme = security.isLoopbackBind ? "http" : "https";
189
+ // Strip any IPv6 brackets the bind host might already include.
190
+ const host = security.bindHost.startsWith("[")
191
+ ? security.bindHost
192
+ : security.bindHost.includes(":") && !security.bindHost.startsWith("[")
193
+ ? `[${security.bindHost}]`
194
+ : security.bindHost;
195
+ return `${scheme}://${host}:${port}/api/auth/login/sso/callback`;
196
+ }
197
+
198
+ /**
199
+ * Returns the absolute URL the dashboard should redirect the user to in
200
+ * order to start an Eliza Cloud SSO authorization-code flow.
201
+ *
202
+ * Throws when `ELIZA_CLOUD_CLIENT_ID` is unset and no `clientId` override
203
+ * is provided — there is no built-in default. `ELIZA_CLOUD_ISSUER` is read
204
+ * via the `CloudBootstrapService`'s service-port and must already be set;
205
+ * if not, this method throws via the bootstrap's existing fail-closed
206
+ * behaviour.
207
+ *
208
+ * The `state` argument MUST be generated by the caller with a cryptographic
209
+ * RNG and stored server-side bound to the issued cookie. This method does
210
+ * NOT generate or persist state.
211
+ *
212
+ * @param bootstrap - Service-port that exposes `getExpectedIssuer()`.
213
+ * @param args - Required `state`, optional `clientId` / `returnTo` / `env`.
214
+ */
215
+ export function getSsoRedirectUrl(bootstrap: CloudBootstrapService, args: SsoRedirectArgs): string {
216
+ const env = args.env ?? processEnv();
217
+ const clientId = args.clientId ?? readEnvKey(env, "ELIZA_CLOUD_CLIENT_ID");
218
+ if (!clientId) {
219
+ throw new Error("ELIZA_CLOUD_CLIENT_ID is not configured — cannot start Eliza Cloud SSO");
220
+ }
221
+ if (args.state.length === 0) {
222
+ throw new Error("getSsoRedirectUrl requires a non-empty state nonce");
223
+ }
224
+ const issuer = bootstrap.getExpectedIssuer();
225
+ const redirectUri = defaultRedirectUri(env);
226
+ const params = new URLSearchParams();
227
+ params.set("response_type", "code");
228
+ params.set("client_id", clientId);
229
+ params.set("redirect_uri", redirectUri);
230
+ params.set("scope", "openid profile");
231
+ params.set("state", args.state);
232
+ if (args.returnTo) {
233
+ // Forwarded through state on the cloud side is not safe (issuer-controlled);
234
+ // we surface it as a separate hint that the local callback honours.
235
+ params.set("eliza_return_to", args.returnTo);
236
+ }
237
+ return `${issuer}/oauth/authorize?${params.toString()}`;
238
+ }
239
+
240
+ function shapeIdTokenClaims(payload: RawIdTokenPayload): CloudSsoIdTokenClaims {
241
+ if (typeof payload.iss !== "string" || payload.iss.length === 0) {
242
+ throw new Error("id_token missing issuer claim");
243
+ }
244
+ if (typeof payload.sub !== "string" || payload.sub.length === 0) {
245
+ throw new Error("id_token missing sub claim");
246
+ }
247
+ if (
248
+ typeof payload.aud !== "string" &&
249
+ !(Array.isArray(payload.aud) && payload.aud.every((value) => typeof value === "string"))
250
+ ) {
251
+ throw new Error("id_token missing or malformed aud claim");
252
+ }
253
+ if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
254
+ throw new Error("id_token missing exp claim");
255
+ }
256
+ if (typeof payload.iat !== "number" || !Number.isFinite(payload.iat)) {
257
+ throw new Error("id_token missing iat claim");
258
+ }
259
+ if (typeof payload.email !== "string" || payload.email.length === 0) {
260
+ throw new Error("id_token missing email claim — Eliza Cloud SSO requires it");
261
+ }
262
+ if (typeof payload.name !== "string" || payload.name.length === 0) {
263
+ throw new Error("id_token missing name claim — Eliza Cloud SSO requires it");
264
+ }
265
+ const extra: Record<string, unknown> = {};
266
+ for (const [key, value] of Object.entries(payload)) {
267
+ if (
268
+ key !== "iss" &&
269
+ key !== "sub" &&
270
+ key !== "aud" &&
271
+ key !== "exp" &&
272
+ key !== "iat" &&
273
+ key !== "email" &&
274
+ key !== "email_verified" &&
275
+ key !== "name" &&
276
+ key !== "picture"
277
+ ) {
278
+ extra[key] = value;
279
+ }
280
+ }
281
+ return {
282
+ iss: payload.iss,
283
+ sub: payload.sub,
284
+ aud: payload.aud as string | string[],
285
+ exp: payload.exp,
286
+ iat: payload.iat,
287
+ email: payload.email,
288
+ email_verified:
289
+ typeof payload.email_verified === "boolean" ? payload.email_verified : undefined,
290
+ name: payload.name,
291
+ picture: typeof payload.picture === "string" ? payload.picture : undefined,
292
+ extra,
293
+ };
294
+ }
295
+
296
+ function shapeTokenResponse(payload: unknown): { idToken: string } {
297
+ if (!payload || typeof payload !== "object") {
298
+ throw new Error("Eliza Cloud token endpoint returned a non-object body");
299
+ }
300
+ const raw = payload as RawTokenResponse;
301
+ if (typeof raw.id_token !== "string" || raw.id_token.length === 0) {
302
+ throw new Error("Eliza Cloud token endpoint did not return an id_token");
303
+ }
304
+ return { idToken: raw.id_token };
305
+ }
306
+
307
+ /**
308
+ * Exchange an authorization code for a verified Eliza Cloud session.
309
+ *
310
+ * Steps:
311
+ * 1. Compare `state === expectedState`. Mismatch throws.
312
+ * 2. POST to `${ELIZA_CLOUD_ISSUER}/oauth/token` with the code,
313
+ * `client_id`, and `client_secret` (the latter from
314
+ * `ELIZA_CLOUD_CLIENT_SECRET`).
315
+ * 3. Verify the returned `id_token` against the JWKS exposed by
316
+ * `CloudBootstrapService.getJwksUrl()`. RS256 only.
317
+ * 4. Project the claims onto a `CloudSsoSession`.
318
+ *
319
+ * Any error in fetch / signature verify / claim shape throws — this method
320
+ * NEVER returns a partial or fallback session.
321
+ */
322
+ export async function exchangeCodeForSession(args: ExchangeCodeArgs): Promise<CloudSsoSession> {
323
+ if (args.code.length === 0) {
324
+ throw new Error("exchangeCodeForSession requires a non-empty code");
325
+ }
326
+ if (!args.state || !args.expectedState || args.state !== args.expectedState) {
327
+ throw new Error("Eliza Cloud SSO state mismatch — refusing to exchange code (possible CSRF)");
328
+ }
329
+
330
+ const env = args.env ?? processEnv();
331
+ const clientId = readEnvKey(env, "ELIZA_CLOUD_CLIENT_ID");
332
+ if (!clientId) {
333
+ throw new Error("ELIZA_CLOUD_CLIENT_ID is not configured — cannot complete Eliza Cloud SSO");
334
+ }
335
+ const clientSecret = readEnvKey(env, "ELIZA_CLOUD_CLIENT_SECRET");
336
+ if (!clientSecret) {
337
+ throw new Error(
338
+ "ELIZA_CLOUD_CLIENT_SECRET is not configured — cannot complete Eliza Cloud SSO"
339
+ );
340
+ }
341
+
342
+ const issuer = args.bootstrap.getExpectedIssuer();
343
+ const redirectUri = args.redirectUri ?? defaultRedirectUri(env);
344
+ const tokenUrl = `${issuer}/oauth/token`;
345
+
346
+ const fetchImpl = args.fetchImpl ?? fetch;
347
+ const body = new URLSearchParams();
348
+ body.set("grant_type", "authorization_code");
349
+ body.set("code", args.code);
350
+ body.set("redirect_uri", redirectUri);
351
+ body.set("client_id", clientId);
352
+ body.set("client_secret", clientSecret);
353
+
354
+ const response = await fetchImpl(tokenUrl, {
355
+ method: "POST",
356
+ headers: {
357
+ "content-type": "application/x-www-form-urlencoded",
358
+ accept: "application/json",
359
+ },
360
+ body: body.toString(),
361
+ });
362
+ if (!response.ok) {
363
+ throw new Error(
364
+ `Eliza Cloud token endpoint returned HTTP ${response.status} for code exchange`
365
+ );
366
+ }
367
+ const payload: unknown = await response.json();
368
+ const { idToken } = shapeTokenResponse(payload);
369
+
370
+ const jwksUrl = args.bootstrap.getJwksUrl();
371
+ const remoteJwks = createRemoteJWKSet(new URL(jwksUrl));
372
+
373
+ const verified = await jwtVerify(idToken, remoteJwks, {
374
+ algorithms: ["RS256"],
375
+ issuer,
376
+ audience: clientId,
377
+ });
378
+
379
+ const claims = shapeIdTokenClaims(verified.payload as RawIdTokenPayload);
380
+
381
+ return {
382
+ cloudUserId: claims.sub,
383
+ email: claims.email,
384
+ displayName: claims.name,
385
+ claims,
386
+ };
387
+ }
388
+
389
+ // ─── Service ───────────────────────────────────────────────────────────────
390
+
391
+ export class CloudAuthService extends Service {
392
+ static serviceType = "CLOUD_AUTH";
393
+ capabilityDescription = "Eliza Cloud device authentication and SSO session helpers";
394
+
395
+ private client: CloudApiClient;
396
+ private credentials: CloudCredentials | null = null;
397
+
398
+ constructor(runtime?: IAgentRuntime) {
399
+ super(runtime);
400
+ this.client = new CloudApiClient(DEFAULT_CLOUD_CONFIG.baseUrl);
401
+ }
402
+
403
+ static async start(runtime: IAgentRuntime): Promise<Service> {
404
+ const service = new CloudAuthService(runtime);
405
+ await service.initialize();
406
+ return service;
407
+ }
408
+
409
+ async stop(): Promise<void> {
410
+ this.credentials = null;
411
+ }
412
+
413
+ private async initialize(): Promise<void> {
414
+ const baseUrl = String(
415
+ this.runtime.getSetting("ELIZAOS_CLOUD_BASE_URL") ?? DEFAULT_CLOUD_CONFIG.baseUrl
416
+ );
417
+ this.client.setBaseUrl(baseUrl);
418
+
419
+ // Try existing API key first. If the key is present in settings
420
+ // (persisted via config file or character secrets in the DB), trust it
421
+ // immediately so the agent is functional even when the cloud API is
422
+ // temporarily unreachable. A background validation fires to confirm
423
+ // the key — if it turns out to be revoked the next model call will
424
+ // surface the error, but the agent won't stall on startup.
425
+ const existingKey = this.runtime.getSetting("ELIZAOS_CLOUD_API_KEY");
426
+ if (existingKey) {
427
+ const key = String(existingKey);
428
+ this.client.setApiKey(key);
429
+
430
+ // Accept the key optimistically — no blocking network call.
431
+ this.credentials = {
432
+ apiKey: key,
433
+ userId: String(this.runtime.getSetting("ELIZAOS_CLOUD_USER_ID") ?? ""),
434
+ organizationId: String(
435
+ this.runtime.getSetting("ELIZAOS_CLOUD_ORG_ID") ??
436
+ this.runtime.getSetting("ELIZA_CLOUD_ORGANIZATION_ID") ??
437
+ ""
438
+ ),
439
+ authenticatedAt: Date.now(),
440
+ };
441
+ logger.info("[CloudAuth] Authenticated with saved API key");
442
+
443
+ // Non-blocking validation — if the key is invalid the next model
444
+ // call will surface the error; we just log a warning here.
445
+ this.validateApiKey(key)
446
+ .then((valid) => {
447
+ if (!valid) {
448
+ logger.warn(
449
+ "[CloudAuth] Saved API key could not be validated (cloud may be unreachable or key revoked) — model calls will use the key anyway"
450
+ );
451
+ }
452
+ })
453
+ .catch(() => {
454
+ // Swallow — already logged inside validateApiKey
455
+ });
456
+ return;
457
+ }
458
+
459
+ // Device-based auto-signup when explicitly enabled
460
+ const enabled = this.runtime.getSetting("ELIZAOS_CLOUD_ENABLED");
461
+ if (enabled === "true" || enabled === "1") {
462
+ try {
463
+ await this.authenticateWithDevice();
464
+ } catch (err) {
465
+ const msg = err instanceof Error ? err.message : String(err);
466
+ logger.warn(`[CloudAuth] Device auth failed (cloud may be unreachable): ${msg}`);
467
+ logger.info(
468
+ "[CloudAuth] Service will start unauthenticated — cloud features disabled until connectivity is restored"
469
+ );
470
+ }
471
+ } else {
472
+ logger.info("[CloudAuth] Cloud not enabled (set ELIZAOS_CLOUD_ENABLED=true)");
473
+ }
474
+ }
475
+
476
+ private async validateApiKey(key: string): Promise<boolean> {
477
+ try {
478
+ const validationClient = new CloudApiClient(this.client.getBaseUrl(), key);
479
+ await validationClient.get("/models", { timeoutMs: 10_000 });
480
+ return true;
481
+ } catch (err) {
482
+ const msg = err instanceof Error ? err.message : String(err);
483
+ logger.warn(`[CloudAuth] Could not reach cloud API to validate key: ${msg}`);
484
+ return false;
485
+ }
486
+ }
487
+
488
+ /**
489
+ * Free-tier device auto-signup. **Convenience only — not a security
490
+ * primitive.** The hardware fingerprint is treated as opaque material the
491
+ * cloud signup endpoint can use to mint a fresh API key + $5 free credit
492
+ * for new installs. The result is usable for outbound LLM calls; it never
493
+ * authorizes inbound dashboard access.
494
+ *
495
+ * See `docs/security/remote-auth-hardening-plan.md` §7.
496
+ */
497
+ async authenticateWithDevice(): Promise<CloudCredentials> {
498
+ const deviceId = await deriveDeviceId();
499
+ const platform = detectPlatform();
500
+ const appVersion = process.env.ELIZAOS_CLOUD_APP_VERSION ?? "2.0.0-beta.0";
501
+ const os = await import("node:os");
502
+
503
+ logger.info(`[CloudAuth] Authenticating device (platform=${platform})`);
504
+
505
+ const response = await this.client.postUnauthenticated<DeviceAuthResponse>("/device-auth", {
506
+ deviceId,
507
+ platform,
508
+ appVersion,
509
+ deviceName: os.hostname(),
510
+ });
511
+
512
+ this.credentials = {
513
+ apiKey: response.data.apiKey,
514
+ userId: response.data.userId,
515
+ organizationId: response.data.organizationId,
516
+ authenticatedAt: Date.now(),
517
+ };
518
+ this.client.setApiKey(response.data.apiKey);
519
+
520
+ const action = response.data.isNew ? "New account created" : "Authenticated";
521
+ logger.info(`[CloudAuth] ${action} (credits: $${response.data.credits.toFixed(2)})`);
522
+
523
+ return this.credentials;
524
+ }
525
+
526
+ authenticateWithApiKey(input: ApiKeyAuthInput): CloudCredentials {
527
+ const apiKey = input.apiKey.trim();
528
+ if (!apiKey) {
529
+ throw new Error("Eliza Cloud API key is required");
530
+ }
531
+
532
+ this.client.setApiKey(apiKey);
533
+ this.credentials = {
534
+ apiKey,
535
+ userId: input.userId ?? "",
536
+ organizationId: input.organizationId ?? "",
537
+ authenticatedAt: Date.now(),
538
+ };
539
+
540
+ logger.info("[CloudAuth] Authenticated with API key");
541
+ return this.credentials;
542
+ }
543
+
544
+ clearAuth(): void {
545
+ this.credentials = null;
546
+ this.client.setApiKey(undefined);
547
+ }
548
+
549
+ isAuthenticated(): boolean {
550
+ return this.credentials !== null;
551
+ }
552
+ getCredentials(): CloudCredentials | null {
553
+ return this.credentials;
554
+ }
555
+ getApiKey(): string | undefined {
556
+ return this.credentials?.apiKey ?? this.client.getApiKey();
557
+ }
558
+ getClient(): CloudApiClient {
559
+ return this.client;
560
+ }
561
+ getUserId(): string | undefined {
562
+ return this.credentials?.userId;
563
+ }
564
+ getOrganizationId(): string | undefined {
565
+ return this.credentials?.organizationId;
566
+ }
567
+ }