@segmentstream/ontology 0.0.0-stage → 0.92.0

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 (483) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +2 -0
  3. package/README.md +1655 -2
  4. package/dist/action.d.ts +193 -0
  5. package/dist/action.js +41 -0
  6. package/dist/agent-chat.d.ts +44 -0
  7. package/dist/agent-chat.js +91 -0
  8. package/dist/agent-task-contract.d.ts +64 -0
  9. package/dist/agent-task-contract.js +15 -0
  10. package/dist/agent-task.d.ts +39 -0
  11. package/dist/agent-task.js +112 -0
  12. package/dist/analyze.d.ts +215 -0
  13. package/dist/analyze.js +2438 -0
  14. package/dist/app-feedback.d.ts +167 -0
  15. package/dist/app-feedback.js +176 -0
  16. package/dist/authoring-input.d.ts +3 -0
  17. package/dist/authoring-input.js +107 -0
  18. package/dist/authoring-names.d.ts +4 -0
  19. package/dist/authoring-names.js +13 -0
  20. package/dist/authoring-records.d.ts +35 -0
  21. package/dist/authoring-records.js +264 -0
  22. package/dist/authoring.d.ts +15 -0
  23. package/dist/authoring.js +331 -0
  24. package/dist/bin/check.d.ts +30 -0
  25. package/dist/bin/check.js +99 -0
  26. package/dist/bin/load.d.ts +48 -0
  27. package/dist/bin/load.js +139 -0
  28. package/dist/bin/main.d.ts +31 -0
  29. package/dist/bin/main.js +121 -0
  30. package/dist/bin/migrate.d.ts +57 -0
  31. package/dist/bin/migrate.js +170 -0
  32. package/dist/bin/output.d.ts +31 -0
  33. package/dist/bin/output.js +84 -0
  34. package/dist/bin.d.ts +2 -0
  35. package/dist/bin.js +31 -0
  36. package/dist/blob.d.ts +52 -0
  37. package/dist/blob.js +87 -0
  38. package/dist/channel-session.d.ts +16 -0
  39. package/dist/channel-session.js +16 -0
  40. package/dist/chat.d.ts +43 -0
  41. package/dist/chat.js +34 -0
  42. package/dist/confirmation.d.ts +46 -0
  43. package/dist/confirmation.js +41 -0
  44. package/dist/connection.d.ts +213 -0
  45. package/dist/connection.js +289 -0
  46. package/dist/deployment.d.ts +35 -0
  47. package/dist/deployment.js +76 -0
  48. package/dist/diagnostics.d.ts +27 -0
  49. package/dist/diagnostics.js +106 -0
  50. package/dist/emails.d.ts +70 -0
  51. package/dist/emails.js +221 -0
  52. package/dist/entity.d.ts +331 -0
  53. package/dist/entity.js +153 -0
  54. package/dist/errors.d.ts +154 -0
  55. package/dist/errors.js +109 -0
  56. package/dist/feedback-config.d.ts +24 -0
  57. package/dist/feedback-config.js +126 -0
  58. package/dist/files.d.ts +39 -0
  59. package/dist/files.js +4 -0
  60. package/dist/groups.d.ts +95 -0
  61. package/dist/groups.js +280 -0
  62. package/dist/index.d.ts +109 -0
  63. package/dist/index.js +70 -0
  64. package/dist/internal/diagnostics.js +594 -0
  65. package/dist/legacy.d.ts +160 -0
  66. package/dist/legacy.js +270 -0
  67. package/dist/manifest-compatibility.d.ts +8 -0
  68. package/dist/manifest-compatibility.js +87 -0
  69. package/dist/manifest.d.ts +3329 -0
  70. package/dist/manifest.js +757 -0
  71. package/dist/me.d.ts +46 -0
  72. package/dist/me.js +109 -0
  73. package/dist/metric-filters.d.ts +48 -0
  74. package/dist/metric-filters.js +252 -0
  75. package/dist/metric-routes.d.ts +132 -0
  76. package/dist/metric-routes.js +498 -0
  77. package/dist/metric.d.ts +172 -0
  78. package/dist/metric.js +132 -0
  79. package/dist/migrate/apply.d.ts +94 -0
  80. package/dist/migrate/apply.js +526 -0
  81. package/dist/migrate/errors.d.ts +46 -0
  82. package/dist/migrate/errors.js +38 -0
  83. package/dist/migrate/index.d.ts +10 -0
  84. package/dist/migrate/index.js +7 -0
  85. package/dist/migrate/model.d.ts +2311 -0
  86. package/dist/migrate/model.js +148 -0
  87. package/dist/migrate/plan.d.ts +51 -0
  88. package/dist/migrate/plan.js +1856 -0
  89. package/dist/migrate/preview.d.ts +13 -0
  90. package/dist/migrate/preview.js +65 -0
  91. package/dist/migrate/storage.d.ts +226 -0
  92. package/dist/migrate/storage.js +774 -0
  93. package/dist/model-metrics.d.ts +22 -0
  94. package/dist/model-metrics.js +545 -0
  95. package/dist/names.d.ts +49 -0
  96. package/dist/names.js +110 -0
  97. package/dist/navigation-artifact.d.ts +13 -0
  98. package/dist/navigation-artifact.js +11 -0
  99. package/dist/navigation-catalog.d.ts +55 -0
  100. package/dist/navigation-catalog.js +297 -0
  101. package/dist/nitro-navigation.d.ts +3 -0
  102. package/dist/nitro-navigation.js +64 -0
  103. package/dist/nitro-workflows.d.ts +108 -0
  104. package/dist/nitro-workflows.js +286 -0
  105. package/dist/nitro.d.ts +40 -0
  106. package/dist/nitro.js +50 -0
  107. package/dist/ontology.d.ts +41 -0
  108. package/dist/ontology.js +46 -0
  109. package/dist/permissions.d.ts +198 -0
  110. package/dist/permissions.js +272 -0
  111. package/dist/property.d.ts +188 -0
  112. package/dist/property.js +301 -0
  113. package/dist/query.d.ts +245 -0
  114. package/dist/query.js +615 -0
  115. package/dist/relationship.d.ts +99 -0
  116. package/dist/relationship.js +33 -0
  117. package/dist/render.d.ts +81 -0
  118. package/dist/render.js +512 -0
  119. package/dist/replication/baseline.d.ts +51 -0
  120. package/dist/replication/baseline.js +215 -0
  121. package/dist/replication/bigquery.d.ts +37 -0
  122. package/dist/replication/bigquery.js +211 -0
  123. package/dist/replication/coverage.d.ts +14 -0
  124. package/dist/replication/coverage.js +53 -0
  125. package/dist/replication/evolution.d.ts +25 -0
  126. package/dist/replication/evolution.js +184 -0
  127. package/dist/replication/identities.d.ts +6 -0
  128. package/dist/replication/identities.js +47 -0
  129. package/dist/replication/legacy-baseline.d.ts +27 -0
  130. package/dist/replication/legacy-baseline.js +109 -0
  131. package/dist/replication/legacy-store.d.ts +19 -0
  132. package/dist/replication/legacy-store.js +63 -0
  133. package/dist/replication/lineage.d.ts +36 -0
  134. package/dist/replication/lineage.js +72 -0
  135. package/dist/replication/migrate.d.ts +21 -0
  136. package/dist/replication/migrate.js +84 -0
  137. package/dist/replication/model.d.ts +52 -0
  138. package/dist/replication/model.js +99 -0
  139. package/dist/replication/scans.d.ts +34 -0
  140. package/dist/replication/scans.js +158 -0
  141. package/dist/replication/schema.d.ts +11 -0
  142. package/dist/replication/schema.js +226 -0
  143. package/dist/replication/shadow-schema.d.ts +4 -0
  144. package/dist/replication/shadow-schema.js +61 -0
  145. package/dist/replication/shadow.d.ts +127 -0
  146. package/dist/replication/shadow.js +614 -0
  147. package/dist/replication/source-replacement.d.ts +33 -0
  148. package/dist/replication/source-replacement.js +76 -0
  149. package/dist/replication/store.d.ts +36 -0
  150. package/dist/replication/store.js +382 -0
  151. package/dist/replication/transaction.d.ts +23 -0
  152. package/dist/replication/transaction.js +88 -0
  153. package/dist/role.d.ts +61 -0
  154. package/dist/role.js +76 -0
  155. package/dist/runtime/action-deadlocks.d.ts +21 -0
  156. package/dist/runtime/action-deadlocks.js +130 -0
  157. package/dist/runtime/action-transactions.d.ts +35 -0
  158. package/dist/runtime/action-transactions.js +54 -0
  159. package/dist/runtime/agent-counters.d.ts +26 -0
  160. package/dist/runtime/agent-counters.js +98 -0
  161. package/dist/runtime/agent-tasks.d.ts +63 -0
  162. package/dist/runtime/agent-tasks.js +120 -0
  163. package/dist/runtime/agents.d.ts +15 -0
  164. package/dist/runtime/agents.js +457 -0
  165. package/dist/runtime/batch-diagnostics.d.ts +22 -0
  166. package/dist/runtime/batch-diagnostics.js +89 -0
  167. package/dist/runtime/batch.d.ts +52 -0
  168. package/dist/runtime/batch.js +534 -0
  169. package/dist/runtime/channel-session-revocation.d.ts +3 -0
  170. package/dist/runtime/channel-session-revocation.js +5 -0
  171. package/dist/runtime/channel-sessions.d.ts +4 -0
  172. package/dist/runtime/channel-sessions.js +61 -0
  173. package/dist/runtime/confirmations.d.ts +29 -0
  174. package/dist/runtime/confirmations.js +57 -0
  175. package/dist/runtime/cursor.d.ts +23 -0
  176. package/dist/runtime/cursor.js +100 -0
  177. package/dist/runtime/deployment.d.ts +7 -0
  178. package/dist/runtime/deployment.js +4 -0
  179. package/dist/runtime/errors.d.ts +118 -0
  180. package/dist/runtime/errors.js +109 -0
  181. package/dist/runtime/federation-tables.d.ts +2 -0
  182. package/dist/runtime/federation-tables.js +20 -0
  183. package/dist/runtime/federation.d.ts +42 -0
  184. package/dist/runtime/federation.js +222 -0
  185. package/dist/runtime/files.d.ts +39 -0
  186. package/dist/runtime/files.js +44 -0
  187. package/dist/runtime/generated-actions.d.ts +37 -0
  188. package/dist/runtime/generated-actions.js +307 -0
  189. package/dist/runtime/history.d.ts +91 -0
  190. package/dist/runtime/history.js +77 -0
  191. package/dist/runtime/ids.d.ts +6 -0
  192. package/dist/runtime/ids.js +39 -0
  193. package/dist/runtime/member-tables.d.ts +8 -0
  194. package/dist/runtime/member-tables.js +33 -0
  195. package/dist/runtime/member-writes.d.ts +78 -0
  196. package/dist/runtime/member-writes.js +202 -0
  197. package/dist/runtime/metric-query.d.ts +19 -0
  198. package/dist/runtime/metric-query.js +411 -0
  199. package/dist/runtime/model.d.ts +67 -0
  200. package/dist/runtime/model.js +150 -0
  201. package/dist/runtime/new-user-hook.d.ts +6 -0
  202. package/dist/runtime/new-user-hook.js +37 -0
  203. package/dist/runtime/oauth.d.ts +9 -0
  204. package/dist/runtime/oauth.js +299 -0
  205. package/dist/runtime/pipeline.d.ts +155 -0
  206. package/dist/runtime/pipeline.js +597 -0
  207. package/dist/runtime/postgres-tls.d.ts +10 -0
  208. package/dist/runtime/postgres-tls.js +14 -0
  209. package/dist/runtime/principals.d.ts +302 -0
  210. package/dist/runtime/principals.js +1307 -0
  211. package/dist/runtime/reads.d.ts +55 -0
  212. package/dist/runtime/reads.js +313 -0
  213. package/dist/runtime/records.d.ts +42 -0
  214. package/dist/runtime/records.js +245 -0
  215. package/dist/runtime/resolve-agent-identity.d.ts +6 -0
  216. package/dist/runtime/resolve-agent-identity.js +181 -0
  217. package/dist/runtime/service-binding.d.ts +18 -0
  218. package/dist/runtime/service-binding.js +266 -0
  219. package/dist/runtime/sign-in-links.d.ts +68 -0
  220. package/dist/runtime/sign-in-links.js +147 -0
  221. package/dist/runtime/sql-runtime.d.ts +131 -0
  222. package/dist/runtime/sql-runtime.js +362 -0
  223. package/dist/runtime/statement.d.ts +18 -0
  224. package/dist/runtime/statement.js +31 -0
  225. package/dist/runtime/user-identities.d.ts +66 -0
  226. package/dist/runtime/user-identities.js +106 -0
  227. package/dist/runtime/user-identity-sql.d.ts +86 -0
  228. package/dist/runtime/user-identity-sql.js +297 -0
  229. package/dist/runtime/user-roles.d.ts +16 -0
  230. package/dist/runtime/user-roles.js +32 -0
  231. package/dist/runtime/validation.d.ts +16 -0
  232. package/dist/runtime/validation.js +26 -0
  233. package/dist/runtime/where.d.ts +57 -0
  234. package/dist/runtime/where.js +404 -0
  235. package/dist/runtime/workflow-admission.d.ts +49 -0
  236. package/dist/runtime/workflow-admission.js +92 -0
  237. package/dist/runtime/workflow-argument-codec.d.ts +10 -0
  238. package/dist/runtime/workflow-argument-codec.js +120 -0
  239. package/dist/runtime/workflow-arguments.d.ts +17 -0
  240. package/dist/runtime/workflow-arguments.js +99 -0
  241. package/dist/runtime/workflow-starts.d.ts +203 -0
  242. package/dist/runtime/workflow-starts.js +493 -0
  243. package/dist/runtime/workflow-users.d.ts +9 -0
  244. package/dist/runtime/workflow-users.js +17 -0
  245. package/dist/runtime/workload.d.ts +25 -0
  246. package/dist/runtime/workload.js +24 -0
  247. package/dist/runtime/writes.d.ts +108 -0
  248. package/dist/runtime/writes.js +491 -0
  249. package/dist/runtime-source.d.ts +22 -0
  250. package/dist/runtime-source.js +28 -0
  251. package/dist/runtime.d.ts +310 -0
  252. package/dist/runtime.js +31 -0
  253. package/dist/server.d.ts +23 -0
  254. package/dist/server.js +107 -0
  255. package/dist/service/agent/attachments.d.ts +33 -0
  256. package/dist/service/agent/attachments.js +228 -0
  257. package/dist/service/agent/authentication.d.ts +22 -0
  258. package/dist/service/agent/authentication.js +58 -0
  259. package/dist/service/agent/confirmations.d.ts +5 -0
  260. package/dist/service/agent/confirmations.js +73 -0
  261. package/dist/service/agent/conversation-routes.d.ts +14 -0
  262. package/dist/service/agent/conversation-routes.js +45 -0
  263. package/dist/service/agent/conversations.d.ts +40 -0
  264. package/dist/service/agent/conversations.js +69 -0
  265. package/dist/service/agent/files.d.ts +12 -0
  266. package/dist/service/agent/files.js +69 -0
  267. package/dist/service/agent/protocol.d.ts +90 -0
  268. package/dist/service/agent/protocol.js +114 -0
  269. package/dist/service/agent/server.d.ts +28 -0
  270. package/dist/service/agent/server.js +374 -0
  271. package/dist/service/agent/task-caller.d.ts +21 -0
  272. package/dist/service/agent/task-caller.js +35 -0
  273. package/dist/service/agent/task-start.d.ts +53 -0
  274. package/dist/service/agent/task-start.js +161 -0
  275. package/dist/service/agent/tasks.d.ts +40 -0
  276. package/dist/service/agent/tasks.js +155 -0
  277. package/dist/service/api.d.ts +50 -0
  278. package/dist/service/api.js +288 -0
  279. package/dist/service/authentication.d.ts +227 -0
  280. package/dist/service/authentication.js +767 -0
  281. package/dist/service/caller-context.d.ts +24 -0
  282. package/dist/service/caller-context.js +6 -0
  283. package/dist/service/catalog.d.ts +42 -0
  284. package/dist/service/catalog.js +66 -0
  285. package/dist/service/channel/provider.d.ts +10 -0
  286. package/dist/service/channel/provider.js +1 -0
  287. package/dist/service/channel/providers/telegram.d.ts +18 -0
  288. package/dist/service/channel/providers/telegram.js +108 -0
  289. package/dist/service/channel/sessions.d.ts +5 -0
  290. package/dist/service/channel/sessions.js +53 -0
  291. package/dist/service/channel/sign-in.d.ts +7 -0
  292. package/dist/service/channel/sign-in.js +78 -0
  293. package/dist/service/chat/archive.d.ts +64 -0
  294. package/dist/service/chat/archive.js +62 -0
  295. package/dist/service/chat/attribution.d.ts +26 -0
  296. package/dist/service/chat/attribution.js +28 -0
  297. package/dist/service/chat/delivery.d.ts +18 -0
  298. package/dist/service/chat/delivery.js +251 -0
  299. package/dist/service/chat/diagnostics.d.ts +2 -0
  300. package/dist/service/chat/diagnostics.js +35 -0
  301. package/dist/service/chat/envelope.d.ts +96 -0
  302. package/dist/service/chat/envelope.js +39 -0
  303. package/dist/service/chat/idempotency.d.ts +19 -0
  304. package/dist/service/chat/idempotency.js +37 -0
  305. package/dist/service/chat/providers/telegram.d.ts +36 -0
  306. package/dist/service/chat/providers/telegram.js +133 -0
  307. package/dist/service/chat/reads.d.ts +25 -0
  308. package/dist/service/chat/reads.js +75 -0
  309. package/dist/service/chat/resolve.d.ts +34 -0
  310. package/dist/service/chat/resolve.js +150 -0
  311. package/dist/service/chat/routes.d.ts +23 -0
  312. package/dist/service/chat/routes.js +75 -0
  313. package/dist/service/chat/schemas.d.ts +43 -0
  314. package/dist/service/chat/schemas.js +31 -0
  315. package/dist/service/config.d.ts +218 -0
  316. package/dist/service/config.js +265 -0
  317. package/dist/service/connection-stream.d.ts +10 -0
  318. package/dist/service/connection-stream.js +191 -0
  319. package/dist/service/connections.d.ts +60 -0
  320. package/dist/service/connections.js +271 -0
  321. package/dist/service/decisions.d.ts +35 -0
  322. package/dist/service/decisions.js +63 -0
  323. package/dist/service/descriptions.d.ts +8 -0
  324. package/dist/service/descriptions.js +20 -0
  325. package/dist/service/discovery-schemas.d.ts +92 -0
  326. package/dist/service/discovery-schemas.js +59 -0
  327. package/dist/service/discovery-search.d.ts +30 -0
  328. package/dist/service/discovery-search.js +95 -0
  329. package/dist/service/discovery.d.ts +37 -0
  330. package/dist/service/discovery.js +436 -0
  331. package/dist/service/docs.d.ts +9 -0
  332. package/dist/service/docs.js +197 -0
  333. package/dist/service/errors.d.ts +145 -0
  334. package/dist/service/errors.js +704 -0
  335. package/dist/service/federation-provider.d.ts +36 -0
  336. package/dist/service/federation-provider.js +110 -0
  337. package/dist/service/federation-server.d.ts +20 -0
  338. package/dist/service/federation-server.js +249 -0
  339. package/dist/service/federation-status.d.ts +40 -0
  340. package/dist/service/federation-status.js +151 -0
  341. package/dist/service/handlers.d.ts +18 -0
  342. package/dist/service/handlers.js +287 -0
  343. package/dist/service/mcp/confirmation.d.ts +68 -0
  344. package/dist/service/mcp/confirmation.js +178 -0
  345. package/dist/service/mcp/find-input.d.ts +12 -0
  346. package/dist/service/mcp/find-input.js +122 -0
  347. package/dist/service/mcp/input-schema.d.ts +6 -0
  348. package/dist/service/mcp/input-schema.js +126 -0
  349. package/dist/service/mcp/listing.d.ts +26 -0
  350. package/dist/service/mcp/listing.js +92 -0
  351. package/dist/service/mcp/metric-tools.d.ts +85 -0
  352. package/dist/service/mcp/metric-tools.js +258 -0
  353. package/dist/service/mcp/request-log.d.ts +5 -0
  354. package/dist/service/mcp/request-log.js +53 -0
  355. package/dist/service/mcp/runtime-policy.d.ts +27 -0
  356. package/dist/service/mcp/runtime-policy.js +62 -0
  357. package/dist/service/mcp/server.d.ts +52 -0
  358. package/dist/service/mcp/server.js +861 -0
  359. package/dist/service/mcp/tools.d.ts +99 -0
  360. package/dist/service/mcp/tools.js +938 -0
  361. package/dist/service/member-file-routes.d.ts +22 -0
  362. package/dist/service/member-file-routes.js +52 -0
  363. package/dist/service/member-files.d.ts +245 -0
  364. package/dist/service/member-files.js +258 -0
  365. package/dist/service/metric-query-platform.d.ts +77 -0
  366. package/dist/service/metric-query-platform.js +198 -0
  367. package/dist/service/metric-query-scopes.d.ts +43 -0
  368. package/dist/service/metric-query-scopes.js +147 -0
  369. package/dist/service/metric-query.d.ts +48 -0
  370. package/dist/service/metric-query.js +200 -0
  371. package/dist/service/name-suggestions.d.ts +3 -0
  372. package/dist/service/name-suggestions.js +38 -0
  373. package/dist/service/navigation-schemas.d.ts +80 -0
  374. package/dist/service/navigation-schemas.js +49 -0
  375. package/dist/service/navigation.d.ts +20 -0
  376. package/dist/service/navigation.js +165 -0
  377. package/dist/service/oauth/protocol.d.ts +70 -0
  378. package/dist/service/oauth/protocol.js +157 -0
  379. package/dist/service/oauth/refresh-replay.d.ts +2 -0
  380. package/dist/service/oauth/refresh-replay.js +20 -0
  381. package/dist/service/oauth/server.d.ts +28 -0
  382. package/dist/service/oauth/server.js +769 -0
  383. package/dist/service/operations.d.ts +170 -0
  384. package/dist/service/operations.js +392 -0
  385. package/dist/service/plan.d.ts +57 -0
  386. package/dist/service/plan.js +96 -0
  387. package/dist/service/rate-limit.d.ts +22 -0
  388. package/dist/service/rate-limit.js +52 -0
  389. package/dist/service/record-reads.d.ts +21 -0
  390. package/dist/service/record-reads.js +155 -0
  391. package/dist/service/replication.d.ts +5 -0
  392. package/dist/service/replication.js +39 -0
  393. package/dist/service/runtime-contract.d.ts +508 -0
  394. package/dist/service/runtime-contract.js +18 -0
  395. package/dist/service/runtime-identity.d.ts +71 -0
  396. package/dist/service/runtime-identity.js +122 -0
  397. package/dist/service/schemas.d.ts +961 -0
  398. package/dist/service/schemas.js +639 -0
  399. package/dist/service/service.d.ts +21 -0
  400. package/dist/service/service.js +526 -0
  401. package/dist/service/warehouse-platform.d.ts +17 -0
  402. package/dist/service/warehouse-platform.js +122 -0
  403. package/dist/service/warehouse-query.d.ts +24 -0
  404. package/dist/service/warehouse-query.js +280 -0
  405. package/dist/service/webhooks.d.ts +106 -0
  406. package/dist/service/webhooks.js +233 -0
  407. package/dist/service/workflow-admission-provider.d.ts +31 -0
  408. package/dist/service/workflow-admission-provider.js +205 -0
  409. package/dist/service/workflow-argument-serialization.d.ts +2 -0
  410. package/dist/service/workflow-argument-serialization.js +14 -0
  411. package/dist/service/workflow-callback.d.ts +22 -0
  412. package/dist/service/workflow-callback.js +75 -0
  413. package/dist/service/workflow-deployment.d.ts +8 -0
  414. package/dist/service/workflow-deployment.js +131 -0
  415. package/dist/service/workflow-diagnostics.d.ts +23 -0
  416. package/dist/service/workflow-diagnostics.js +263 -0
  417. package/dist/service/workflow-errors.d.ts +26 -0
  418. package/dist/service/workflow-errors.js +181 -0
  419. package/dist/service/workflow-logging.d.ts +2 -0
  420. package/dist/service/workflow-logging.js +50 -0
  421. package/dist/service/workflow-queue-fence.d.ts +6 -0
  422. package/dist/service/workflow-queue-fence.js +66 -0
  423. package/dist/service/workflows.d.ts +200 -0
  424. package/dist/service/workflows.js +1549 -0
  425. package/dist/sign-in.d.ts +58 -0
  426. package/dist/sign-in.js +57 -0
  427. package/dist/source.d.ts +30 -0
  428. package/dist/source.js +107 -0
  429. package/dist/start-recovery-contract.d.ts +49 -0
  430. package/dist/start-recovery-contract.js +26 -0
  431. package/dist/start-recovery.d.ts +27 -0
  432. package/dist/start-recovery.js +81 -0
  433. package/dist/storage/api.d.ts +4 -0
  434. package/dist/storage/api.js +40 -0
  435. package/dist/storage/attachments.d.ts +146 -0
  436. package/dist/storage/attachments.js +733 -0
  437. package/dist/storage/authorization.d.ts +38 -0
  438. package/dist/storage/authorization.js +83 -0
  439. package/dist/storage/file-access.d.ts +17 -0
  440. package/dist/storage/file-access.js +8 -0
  441. package/dist/storage/limits.d.ts +12 -0
  442. package/dist/storage/limits.js +17 -0
  443. package/dist/storage/maintenance-auth.d.ts +20 -0
  444. package/dist/storage/maintenance-auth.js +24 -0
  445. package/dist/storage/maintenance.d.ts +11 -0
  446. package/dist/storage/maintenance.js +67 -0
  447. package/dist/storage/neon.d.ts +4 -0
  448. package/dist/storage/neon.js +318 -0
  449. package/dist/storage/operator.d.ts +11 -0
  450. package/dist/storage/operator.js +30 -0
  451. package/dist/storage/provider.d.ts +93 -0
  452. package/dist/storage/provider.js +36 -0
  453. package/dist/storage/sessions.d.ts +184 -0
  454. package/dist/storage/sessions.js +688 -0
  455. package/dist/storage/tables.d.ts +54 -0
  456. package/dist/storage/tables.js +205 -0
  457. package/dist/storage/transfers.d.ts +16 -0
  458. package/dist/storage/transfers.js +153 -0
  459. package/dist/storage/writes.d.ts +7 -0
  460. package/dist/storage/writes.js +88 -0
  461. package/dist/telegram.d.ts +35 -0
  462. package/dist/telegram.js +173 -0
  463. package/dist/user-identity.d.ts +28 -0
  464. package/dist/user-identity.js +106 -0
  465. package/dist/user.d.ts +75 -0
  466. package/dist/user.js +111 -0
  467. package/dist/warehouse-backed.d.ts +6 -0
  468. package/dist/warehouse-backed.js +495 -0
  469. package/dist/webhook-token.d.ts +11 -0
  470. package/dist/webhook-token.js +18 -0
  471. package/dist/webhooks.d.ts +40 -0
  472. package/dist/webhooks.js +55 -0
  473. package/dist/wire.d.ts +10 -0
  474. package/dist/wire.js +35 -0
  475. package/dist/workflow-runtime.d.ts +116 -0
  476. package/dist/workflow-runtime.js +109 -0
  477. package/dist/workflow-topics.d.ts +28 -0
  478. package/dist/workflow-topics.js +28 -0
  479. package/dist/workflow.d.ts +284 -0
  480. package/dist/workflow.js +259 -0
  481. package/dist/workflows.d.ts +24 -0
  482. package/dist/workflows.js +18 -0
  483. package/package.json +127 -4
@@ -0,0 +1,767 @@
1
+ import { Cause, Context, Effect, Layer, Redacted } from "effect";
2
+ import { HttpServerRequest } from "effect/unstable/http";
3
+ import { HttpApiMiddleware, HttpApiSecurity, OpenApi } from "effect/unstable/httpapi";
4
+ import { createRemoteJWKSet, decodeJwt, decodeProtectedHeader, errors, jwtVerify, } from "jose";
5
+ import { CHANNEL_COOKIE_PATTERN } from "../channel-session.js";
6
+ import { requireDeploymentCapability } from "../deployment.js";
7
+ import { API_KEY_PREFIX } from "../runtime/principals.js";
8
+ import { FEDERATION_TOKEN_PREFIX, federationDigest } from "../runtime/federation.js";
9
+ import { browserRevisionAdmitted, browserRevisionObservation, browserSessionAdmission, federationStatus, } from "./federation-status.js";
10
+ import { RequestId, crossOriginSession, forbidden, internalError, notInvited, toServerResponse, unauthorized, unavailable, } from "./errors.js";
11
+ import { ACCESS_TOKEN_PREFIX, appSessionResource, publicOrigin, callerOfAccessToken, rejectedAccessToken, } from "./oauth/protocol.js";
12
+ import { CurrentCaller } from "./caller-context.js";
13
+ import { OntologyBackend } from "./runtime-contract.js";
14
+ import { ACT_AS_HEADER, AGENT_TASK_HEADER, logRuntimeRejection, runtimeCredential, } from "./runtime-identity.js";
15
+ import { agentTaskCaller } from "./agent/task-caller.js";
16
+ import { ErrorSchemas } from "./schemas.js";
17
+ const CLOCK_TOLERANCE_SECONDS = 5;
18
+ const JWKS_TIMEOUT_MS = 5_000;
19
+ /** The principal the request runs as, provided by {@link Authentication}. */
20
+ export class CurrentPrincipal extends Context.Service()("@segmentstream/ontology/CurrentPrincipal") {
21
+ }
22
+ /**
23
+ * Authenticates every ontology route except `status`: a Neon Auth token, a SegmentStream app token,
24
+ * an API key or the deployment's runtime token acting as a member, all as `Authorization: Bearer …`;
25
+ * without one, the app's Neon Auth session cookie. Failures answer the request directly, before its
26
+ * input is decoded.
27
+ */
28
+ export class Authentication extends HttpApiMiddleware.Service()("@segmentstream/ontology/Authentication", {
29
+ security: {
30
+ bearer: HttpApiSecurity.bearer.pipe(HttpApiSecurity.annotate(OpenApi.Description, "The signed-in member's Neon Auth token (a SegmentStream app token during the move to " +
31
+ "Neon Auth), or an API key (ssk_…) for a service.")),
32
+ },
33
+ error: [ErrorSchemas.unauthorized, ErrorSchemas.notInvited, ErrorSchemas.unavailable],
34
+ }) {
35
+ }
36
+ /** The control plane's app-token key set: `GET /api/v1/app-sessions/jwks`. */
37
+ export function remoteKeySet(segmentstreamUrl) {
38
+ return createRemoteJWKSet(new URL("/api/v1/app-sessions/jwks", segmentstreamUrl), {
39
+ timeoutDuration: JWKS_TIMEOUT_MS,
40
+ });
41
+ }
42
+ /** The workspace's Neon Auth key set, at `NEON_AUTH_JWKS_URL`. */
43
+ export function neonAuthKeySet(jwksUrl) {
44
+ return createRemoteJWKSet(new URL(jwksUrl), { timeoutDuration: JWKS_TIMEOUT_MS });
45
+ }
46
+ /**
47
+ * The key set could not be read: a timeout, a network failure, a non-200 or malformed response. The
48
+ * token may be fine, so this is not the caller's fault. Every other jose error is about the token.
49
+ */
50
+ function keySetUnavailable(error) {
51
+ if (!(error instanceof errors.JOSEError)) {
52
+ return true;
53
+ }
54
+ return (error instanceof errors.JWKSTimeout ||
55
+ error instanceof errors.JWKSInvalid ||
56
+ error.code === errors.JOSEError.code);
57
+ }
58
+ function identityFromClaims(config, payload) {
59
+ const { sub, org, wsp, email, name, ss_oidc_identity } = payload;
60
+ if (typeof sub !== "string" || sub === "") {
61
+ return undefined;
62
+ }
63
+ if (org !== config.organizationId || wsp !== config.workspaceId) {
64
+ return undefined;
65
+ }
66
+ let oidcIdentity;
67
+ if (ss_oidc_identity !== undefined) {
68
+ const mapping = ss_oidc_identity;
69
+ if (!mapping ||
70
+ typeof mapping !== "object" ||
71
+ mapping.issuer !==
72
+ (config.oidc?.issuer ?? `${new URL(config.segmentstreamUrl).origin}/oidc`) ||
73
+ typeof mapping.subject !== "string" ||
74
+ !mapping.subject) {
75
+ return undefined;
76
+ }
77
+ oidcIdentity = { issuer: mapping.issuer, subject: mapping.subject };
78
+ }
79
+ return {
80
+ ...(oidcIdentity ? { oidcIdentity } : {}),
81
+ provider: "segmentstream",
82
+ subject: sub,
83
+ ...(typeof email === "string" ? { email } : {}),
84
+ ...(typeof name === "string" ? { name } : {}),
85
+ };
86
+ }
87
+ /**
88
+ * Verifies app tokens as the app SDK does: ES256 against the control plane's JWKS, issued by
89
+ * `SEGMENTSTREAM_URL` for this application (`aud: app:<application id>`), organization and workspace.
90
+ */
91
+ export function makeTokenVerifier(config, keySet) {
92
+ const issuer = new URL(config.segmentstreamUrl).origin;
93
+ const audience = `app:${config.applicationId}`;
94
+ return async function verifyToken(token) {
95
+ let payload;
96
+ try {
97
+ const verified = await jwtVerify(token, keySet, {
98
+ algorithms: ["ES256"],
99
+ typ: "JWT",
100
+ issuer,
101
+ audience,
102
+ clockTolerance: CLOCK_TOLERANCE_SECONDS,
103
+ requiredClaims: ["sub", "exp", "iat", "org", "wsp"],
104
+ });
105
+ payload = verified.payload;
106
+ }
107
+ catch (error) {
108
+ return keySetUnavailable(error) ? { status: "unavailable" } : { status: "invalid" };
109
+ }
110
+ const identity = identityFromClaims(config, payload);
111
+ return identity === undefined ? { status: "invalid" } : { status: "valid", identity };
112
+ };
113
+ }
114
+ export const WORKLOAD_TOKEN_TYPE = "segmentstream-ontology-workload+jwt";
115
+ /** The workspace's pipeline workers' workload subject: `pipeline-workers:<workspace id>`. */
116
+ export const PIPELINE_WORKERS_SUBJECT_PREFIX = "pipeline-workers:";
117
+ /**
118
+ * The platform's workload subject, `platform:<workspace id>`: backend-next acting for the console
119
+ * and the CLI. It is admitted only to the workflow routes and never resolves as a principal.
120
+ */
121
+ export const PLATFORM_SUBJECT_PREFIX = "platform:";
122
+ /**
123
+ * Who a workload token's subject names in this workspace: its pipeline workers or the platform.
124
+ * `undefined` for any other subject.
125
+ */
126
+ export function workloadKind(claims, workspaceId) {
127
+ if (claims.sub === `${PIPELINE_WORKERS_SUBJECT_PREFIX}${workspaceId}`) {
128
+ return "pipeline";
129
+ }
130
+ if (claims.sub === `${PLATFORM_SUBJECT_PREFIX}${workspaceId}`) {
131
+ return "platform";
132
+ }
133
+ return undefined;
134
+ }
135
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
136
+ /** A separate verifier: a workload token can never resolve as a human or act as an agent. */
137
+ export function makeWorkloadTokenVerifier(config, keySet) {
138
+ return async (token) => {
139
+ const preview = config.deployment?.target === "preview" ? config.deployment : undefined;
140
+ const servingDeploymentId = preview?.deploymentId ?? config.workloadTarget?.deploymentId;
141
+ if (servingDeploymentId === undefined) {
142
+ return { status: "invalid" };
143
+ }
144
+ if (preview) {
145
+ requireDeploymentCapability(preview, "workflows");
146
+ }
147
+ let payload;
148
+ try {
149
+ const verified = await jwtVerify(token, keySet, {
150
+ algorithms: ["ES256"],
151
+ typ: WORKLOAD_TOKEN_TYPE,
152
+ issuer: new URL(config.segmentstreamUrl).origin,
153
+ audience: `ontology:${config.applicationId}`,
154
+ clockTolerance: CLOCK_TOLERANCE_SECONDS,
155
+ requiredClaims: [
156
+ "sub",
157
+ "exp",
158
+ "iat",
159
+ "jti",
160
+ "org",
161
+ "wsp",
162
+ "deploymentId",
163
+ "ontologyDeploymentId",
164
+ "ontologyOrigin",
165
+ "environment",
166
+ "runId",
167
+ "attemptId",
168
+ "generation",
169
+ ],
170
+ });
171
+ payload = verified.payload;
172
+ }
173
+ catch (error) {
174
+ return keySetUnavailable(error) ? { status: "unavailable" } : { status: "invalid" };
175
+ }
176
+ const kind = workloadKind(payload, config.workspaceId);
177
+ // The platform's runId and attemptId only correlate its requests; a pipeline's name its run.
178
+ const strings = kind === "platform" ? ["jti", "runId", "attemptId"] : ["jti"];
179
+ const ids = kind === "platform"
180
+ ? ["deploymentId", "ontologyDeploymentId"]
181
+ : ["deploymentId", "ontologyDeploymentId", "runId", "attemptId"];
182
+ if (payload.org !== config.organizationId ||
183
+ payload.wsp !== config.workspaceId ||
184
+ kind === undefined ||
185
+ (kind === "pipeline" && !("executionId" in payload)) ||
186
+ payload.environment !== (preview ? "preview" : "production") ||
187
+ (preview !== undefined &&
188
+ (kind !== "platform" ||
189
+ payload.deploymentId !== preview.deploymentId ||
190
+ payload.ontologyDeploymentId !== preview.deploymentId ||
191
+ typeof payload.exp !== "number" ||
192
+ payload.exp * 1000 > Date.parse(preview.expiresAt))) ||
193
+ payload.aud !== `ontology:${config.applicationId}` ||
194
+ strings.some((name) => typeof payload[name] !== "string" || payload[name].trim() === "") ||
195
+ (payload.jobName !== undefined &&
196
+ payload.jobName !== null &&
197
+ (typeof payload.jobName !== "string" || payload.jobName.trim() === "")) ||
198
+ ids.some((name) => typeof payload[name] !== "string" || !UUID.test(payload[name])) ||
199
+ (payload.executionId !== null &&
200
+ !(kind === "platform" && payload.executionId === undefined) &&
201
+ (typeof payload.executionId !== "string" || !UUID.test(payload.executionId))) ||
202
+ !Number.isSafeInteger(payload.generation) ||
203
+ payload.generation < 1 ||
204
+ !Number.isSafeInteger(payload.iat) ||
205
+ !Number.isSafeInteger(payload.exp) ||
206
+ payload.iat > Math.floor(Date.now() / 1000) + CLOCK_TOLERANCE_SECONDS ||
207
+ payload.exp <= payload.iat ||
208
+ payload.exp - payload.iat > 300 ||
209
+ typeof payload.ontologyOrigin !== "string" ||
210
+ !URL.canParse(payload.ontologyOrigin)) {
211
+ return { status: "invalid" };
212
+ }
213
+ const origin = new URL(payload.ontologyOrigin);
214
+ if (origin.protocol !== "https:" || origin.origin !== payload.ontologyOrigin) {
215
+ return { status: "invalid" };
216
+ }
217
+ return {
218
+ status: "workload",
219
+ execution: {
220
+ issuer: payload.iss,
221
+ audience: payload.aud,
222
+ organizationId: config.organizationId,
223
+ workspaceId: config.workspaceId,
224
+ subject: payload.sub,
225
+ deploymentId: payload.deploymentId,
226
+ ontologyDeploymentId: payload.ontologyDeploymentId,
227
+ servingOntologyDeploymentId: servingDeploymentId,
228
+ ontologyOrigin: payload.ontologyOrigin,
229
+ environment: preview ? "preview" : "production",
230
+ jobName: typeof payload.jobName === "string" ? payload.jobName : null,
231
+ runId: payload.runId,
232
+ executionId: (payload.executionId ?? null),
233
+ attemptId: payload.attemptId,
234
+ generation: payload.generation,
235
+ tokenId: payload.jti,
236
+ issuedAt: payload.iat,
237
+ expiresAt: payload.exp,
238
+ },
239
+ };
240
+ };
241
+ }
242
+ /**
243
+ * Neon Auth's issuer is the origin of its Auth URL: `https://ep-….neon.tech/ontology/auth` issues
244
+ * tokens with `iss: https://ep-….neon.tech`.
245
+ */
246
+ export function neonAuthIssuer(baseUrl) {
247
+ return new URL(baseUrl).origin;
248
+ }
249
+ /**
250
+ * The member a Neon Auth token names. Its email counts only once Neon Auth verified it: sign-in links
251
+ * an invited member by email, and an unverified address (a password sign-up anyone can make) must
252
+ * never claim someone else's invitation or roles.
253
+ */
254
+ function neonAuthIdentity(payload) {
255
+ const { sub, email, emailVerified, name } = payload;
256
+ if (typeof sub !== "string" || sub === "") {
257
+ return undefined;
258
+ }
259
+ return {
260
+ provider: "neon-auth",
261
+ subject: sub,
262
+ ...(typeof email === "string" && emailVerified === true ? { email } : {}),
263
+ ...(typeof name === "string" ? { name } : {}),
264
+ };
265
+ }
266
+ /**
267
+ * Verifies the workspace's Neon Auth tokens (Managed Better Auth): EdDSA against its JWKS, issued by
268
+ * the origin of `NEON_AUTH_BASE_URL`, with a subject. The tokens carry no roles and no custom claims;
269
+ * roles come from the ontology.
270
+ */
271
+ export function makeNeonAuthTokenVerifier(config, keySet) {
272
+ const issuer = neonAuthIssuer(config.baseUrl);
273
+ return async function verifyNeonAuthToken(token) {
274
+ let payload;
275
+ try {
276
+ const verified = await jwtVerify(token, keySet, {
277
+ algorithms: ["EdDSA"],
278
+ issuer,
279
+ clockTolerance: CLOCK_TOLERANCE_SECONDS,
280
+ requiredClaims: ["sub", "exp", "iat"],
281
+ });
282
+ payload = verified.payload;
283
+ }
284
+ catch (error) {
285
+ return keySetUnavailable(error) ? { status: "unavailable" } : { status: "invalid" };
286
+ }
287
+ const identity = neonAuthIdentity(payload);
288
+ return identity === undefined ? { status: "invalid" } : { status: "valid", identity };
289
+ };
290
+ }
291
+ /** The `iss` a token claims, before anything about it is verified; `undefined` for a non-JWT. */
292
+ function claimedIssuer(token) {
293
+ try {
294
+ const { iss } = decodeJwt(token);
295
+ return typeof iss === "string" ? iss : undefined;
296
+ }
297
+ catch {
298
+ return undefined;
299
+ }
300
+ }
301
+ /**
302
+ * Verifies a token with the verifier of the issuer it claims, by origin. The claim only picks the
303
+ * verifier, which checks the issuer again with the signature; a token from any other issuer is
304
+ * invalid without a key-set fetch.
305
+ */
306
+ export function verifyByIssuer(verifiers) {
307
+ return async function verifyToken(token) {
308
+ const issuer = claimedIssuer(token);
309
+ const verify = issuer === undefined ? undefined : verifiers.get(issuer);
310
+ return verify === undefined ? { status: "invalid" } : verify(token);
311
+ };
312
+ }
313
+ /**
314
+ * The service's token verification: SegmentStream app tokens, and the workspace's Neon Auth tokens
315
+ * once it has Neon Auth. Both are accepted while workspaces move to Neon Auth.
316
+ */
317
+ export function tokenVerifier(config) {
318
+ const platformKeys = remoteKeySet(config.segmentstreamUrl);
319
+ const human = makeTokenVerifier(config, platformKeys);
320
+ const workload = makeWorkloadTokenVerifier(config, platformKeys);
321
+ const platform = (token) => {
322
+ try {
323
+ return decodeProtectedHeader(token).typ === WORKLOAD_TOKEN_TYPE
324
+ ? workload(token)
325
+ : config.deployment?.target === "preview"
326
+ ? Promise.resolve({ status: "invalid" })
327
+ : human(token);
328
+ }
329
+ catch {
330
+ return Promise.resolve({ status: "invalid" });
331
+ }
332
+ };
333
+ const verifiers = new Map([
334
+ [new URL(config.segmentstreamUrl).origin, platform],
335
+ ]);
336
+ if (config.neonAuth !== undefined &&
337
+ (!config.browserMethods || config.browserMethods.includes("email"))) {
338
+ verifiers.set(neonAuthIssuer(config.neonAuth.baseUrl), makeNeonAuthTokenVerifier(config.neonAuth, neonAuthKeySet(config.neonAuth.jwksUrl)));
339
+ }
340
+ const verify = verifyByIssuer(verifiers);
341
+ return Object.assign(async (token) => {
342
+ if (config.deployment) {
343
+ requireDeploymentCapability(config.deployment);
344
+ }
345
+ return verify(token);
346
+ }, {
347
+ deployment: config.deployment,
348
+ browserRevision: config.browserRevision,
349
+ browserMethods: config.browserMethods,
350
+ oidc: config.oidc,
351
+ });
352
+ }
353
+ /**
354
+ * The session cookie the app's Neon Auth sets on the app's domain. The ontology service shares the
355
+ * domain, so a signed-in browser sends it here too: the docs page relies on it.
356
+ */
357
+ export const NEON_AUTH_SESSION_COOKIE = "__Secure-neon-auth.session_token";
358
+ /** Session tokens kept at once; past it the oldest go first. */
359
+ const SESSION_CACHE_SIZE = 1_000;
360
+ /** A session's token is fetched again this long before it expires. */
361
+ const SESSION_TOKEN_MARGIN_MS = 60_000;
362
+ const SESSION_EXCHANGE_TIMEOUT_MS = 5_000;
363
+ /**
364
+ * Exchanges a session cookie for its token at Neon Auth's `GET <base URL>/token`, as the app's
365
+ * `@neondatabase/auth` does, and reuses the token until shortly before it expires. The token is then
366
+ * verified like any bearer token, so the exchange never vouches for a session on its own.
367
+ */
368
+ export function neonAuthSessionExchange(config, options = {}) {
369
+ const fetchToken = options.fetch ?? fetch;
370
+ const now = options.now ?? Date.now;
371
+ const endpoint = new URL("token", config.baseUrl.endsWith("/") ? config.baseUrl : `${config.baseUrl}/`);
372
+ const cache = new Map();
373
+ return async function exchangeSession(session, origin) {
374
+ const value = Redacted.value(session);
375
+ const cached = cache.get(value);
376
+ if (cached !== undefined && cached.refreshAt > now()) {
377
+ return { status: "token", token: cached.token };
378
+ }
379
+ cache.delete(value);
380
+ let response;
381
+ try {
382
+ response = await fetchToken(endpoint, {
383
+ headers: { cookie: `${NEON_AUTH_SESSION_COOKIE}=${value}`, origin },
384
+ redirect: "error",
385
+ signal: AbortSignal.timeout(SESSION_EXCHANGE_TIMEOUT_MS),
386
+ });
387
+ }
388
+ catch {
389
+ return { status: "unavailable" };
390
+ }
391
+ if (response.status === 401 || response.status === 403) {
392
+ return { status: "invalid" };
393
+ }
394
+ if (!response.ok) {
395
+ return { status: "unavailable" };
396
+ }
397
+ const body = (await response.json().catch(() => undefined));
398
+ const token = body?.token;
399
+ if (typeof token !== "string" || token === "") {
400
+ return { status: "unavailable" };
401
+ }
402
+ const expiresAt = tokenExpiry(token);
403
+ if (expiresAt !== undefined) {
404
+ if (cache.size >= SESSION_CACHE_SIZE) {
405
+ cache.delete(cache.keys().next().value);
406
+ }
407
+ cache.set(value, { token, refreshAt: expiresAt - SESSION_TOKEN_MARGIN_MS });
408
+ }
409
+ return { status: "token", token };
410
+ };
411
+ }
412
+ /** When a token expires, in milliseconds; `undefined` for a token without a readable `exp`. */
413
+ function tokenExpiry(token) {
414
+ try {
415
+ const { exp } = decodeJwt(token);
416
+ return typeof exp === "number" ? exp * 1_000 : undefined;
417
+ }
418
+ catch {
419
+ return undefined;
420
+ }
421
+ }
422
+ const SAFE_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
423
+ /**
424
+ * The origin the browser addressed. Vercel and the app's development proxy name it in the forwarded
425
+ * headers; otherwise it is the request URL's, which Nitro passes on whole.
426
+ */
427
+ function requestOrigin(request) {
428
+ const first = (value) => value?.split(",")[0]?.trim() || undefined;
429
+ const url = URL.canParse(request.originalUrl) ? new URL(request.originalUrl) : undefined;
430
+ const host = first(request.headers["x-forwarded-host"]) ?? url?.host ?? request.headers.host;
431
+ if (host === undefined || host === "") {
432
+ return undefined;
433
+ }
434
+ const forwardedProto = first(request.headers["x-forwarded-proto"]);
435
+ const protocol = forwardedProto === "http" || forwardedProto === "https"
436
+ ? forwardedProto
437
+ : (url?.protocol.slice(0, -1) ?? "https");
438
+ return `${protocol}://${host}`;
439
+ }
440
+ /**
441
+ * A request the session cookie may authenticate: any read, and a change only when the browser says
442
+ * it comes from the app's own origin. Browsers send `Origin` with every cross-origin request and
443
+ * with same-origin `POST`s, so a change without one is refused too.
444
+ */
445
+ export function sessionMayAuthenticate(request) {
446
+ if (SAFE_METHODS.has(request.method)) {
447
+ return true;
448
+ }
449
+ const origin = request.headers.origin;
450
+ return origin !== undefined && origin === requestOrigin(request);
451
+ }
452
+ /**
453
+ * The member a verified runtime caller acts for: the member `X-SegmentStream-Act-As` names, with the
454
+ * roles they hold now, while they are active and paired with the agent. Without the header, the
455
+ * runtime may call only the agent's own routes, which authenticate it themselves.
456
+ */
457
+ function actingMember(actAs, provider) {
458
+ return Effect.gen(function* () {
459
+ const backend = yield* OntologyBackend;
460
+ if (actAs === undefined) {
461
+ return {
462
+ status: "forbidden",
463
+ detail: `The app's agent names the member it acts for in ${ACT_AS_HEADER}.`,
464
+ };
465
+ }
466
+ const member = backend.agents === undefined
467
+ ? undefined
468
+ : yield* backend.agents.actingMember(actAs, provider);
469
+ return member === undefined || member.kind !== "member"
470
+ ? {
471
+ status: "forbidden",
472
+ detail: "The member is inactive or has not paired with the app's agent.",
473
+ }
474
+ : {
475
+ status: "authenticated",
476
+ principal: { ...member, authenticatedVia: provider ?? "agent" },
477
+ caller: { kind: "runtime", subjectId: member.id },
478
+ };
479
+ });
480
+ }
481
+ /**
482
+ * The workflow user a verified runtime caller acts as while it runs a task a workflow handed it:
483
+ * the task's secret names it, never the caller. Refused on a route that does not accept tasks, and
484
+ * with a member named as well.
485
+ */
486
+ function agentTaskPrincipal(secret, actAs, accepted) {
487
+ return Effect.gen(function* () {
488
+ if (accepted === undefined) {
489
+ return {
490
+ status: "forbidden",
491
+ detail: `This route does not accept ${AGENT_TASK_HEADER}.`,
492
+ };
493
+ }
494
+ if (actAs !== undefined) {
495
+ return {
496
+ status: "forbidden",
497
+ detail: `A request names a member in ${ACT_AS_HEADER} or a task in ${AGENT_TASK_HEADER}, not both.`,
498
+ };
499
+ }
500
+ const resolved = yield* agentTaskCaller(secret, accepted.workspaceId);
501
+ return resolved.status === "refused"
502
+ ? { status: "forbidden", detail: resolved.detail }
503
+ : {
504
+ status: "authenticated",
505
+ principal: resolved.principal,
506
+ caller: { kind: "runtime", subjectId: resolved.principal.id },
507
+ };
508
+ });
509
+ }
510
+ /** Resolves a bearer credential to its current principal and verified credential provenance. */
511
+ export function authenticate(credential, verifyToken, options = {}) {
512
+ return Effect.gen(function* () {
513
+ const backend = yield* OntologyBackend;
514
+ const token = Redacted.value(credential);
515
+ if (verifyToken.deployment) {
516
+ requireDeploymentCapability(verifyToken.deployment);
517
+ }
518
+ if (verifyToken.deployment?.target === "preview" &&
519
+ ((token.startsWith(FEDERATION_TOKEN_PREFIX) && !verifyToken.browserMethods) ||
520
+ token.startsWith(ACCESS_TOKEN_PREFIX) ||
521
+ token.startsWith(API_KEY_PREFIX) ||
522
+ options.runtime !== undefined)) {
523
+ return { status: "rejected" };
524
+ }
525
+ if (token === "") {
526
+ return { status: "missing" };
527
+ }
528
+ if (token.startsWith(FEDERATION_TOKEN_PREFIX)) {
529
+ const revision = verifyToken.browserRevision
530
+ ? yield* Effect.promise(() => browserRevisionObservation(verifyToken.browserRevision))
531
+ : { active: true };
532
+ if (!browserRevisionAdmitted(revision)) {
533
+ return { status: "rejected" };
534
+ }
535
+ const store = backend.federation;
536
+ const session = store ? yield* store.read(federationDigest(token)) : undefined;
537
+ const admission = !verifyToken.browserMethods
538
+ ? { active: true }
539
+ : verifyToken.browserMethods.includes("segmentstream") &&
540
+ session !== undefined &&
541
+ verifyToken.oidc !== undefined
542
+ ? yield* Effect.promise(() => browserSessionAdmission(session, verifyToken.oidc))
543
+ : { active: false };
544
+ const active = browserRevisionAdmitted(admission) &&
545
+ session?.userId &&
546
+ (yield* Effect.promise(() => federationStatus(session)));
547
+ const principal = active && session?.userId ? yield* store.principal(session.userId) : undefined;
548
+ return principal && browserRevisionAdmitted(revision) && browserRevisionAdmitted(admission)
549
+ ? {
550
+ status: "authenticated",
551
+ principal: { ...principal, authenticatedVia: principal.authenticatedVia ?? "oidc" },
552
+ caller: { kind: "member", subjectId: principal.id },
553
+ }
554
+ : { status: "rejected" };
555
+ }
556
+ if (token.startsWith(ACCESS_TOKEN_PREFIX)) {
557
+ if (options.oauthResource === undefined || backend.oauth === undefined) {
558
+ yield* rejectedAccessToken(backend.oauth === undefined ? "oauth_unavailable" : "unsupported_route");
559
+ return { status: "rejected" };
560
+ }
561
+ const authenticated = yield* callerOfAccessToken(backend.oauth, token, options.oauthResource);
562
+ return authenticated === undefined
563
+ ? { status: "rejected" }
564
+ : {
565
+ status: "authenticated",
566
+ ...authenticated,
567
+ principal: {
568
+ ...authenticated.principal,
569
+ authenticatedVia: authenticated.principal.authenticatedVia ?? "oauth",
570
+ },
571
+ };
572
+ }
573
+ if (token.startsWith(API_KEY_PREFIX)) {
574
+ const principal = yield* backend.resolveApiKey(credential);
575
+ return principal === undefined
576
+ ? { status: "rejected" }
577
+ : {
578
+ status: "authenticated",
579
+ principal: { ...principal, authenticatedVia: "api_key" },
580
+ caller: {
581
+ kind: principal.kind === "service" ? "service" : "member",
582
+ subjectId: principal.id,
583
+ },
584
+ };
585
+ }
586
+ if (options.runtime !== undefined) {
587
+ const { verify, actAs, provider, agentTask } = options.runtime;
588
+ const runtime = yield* Effect.promise(() => verify(token));
589
+ switch (runtime.status) {
590
+ case "valid":
591
+ return agentTask === undefined
592
+ ? yield* actingMember(actAs, provider)
593
+ : yield* agentTaskPrincipal(agentTask, actAs, options.agentTasks);
594
+ case "invalid":
595
+ yield* logRuntimeRejection(runtime.reason);
596
+ return { status: "rejected" };
597
+ case "unavailable":
598
+ return { status: "unavailable" };
599
+ case "other":
600
+ if (agentTask !== undefined) {
601
+ return {
602
+ status: "forbidden",
603
+ detail: `${AGENT_TASK_HEADER} authenticates only with the deployment's runtime token.`,
604
+ };
605
+ }
606
+ break;
607
+ }
608
+ }
609
+ const verification = yield* Effect.promise(() => verifyToken(token));
610
+ if (verification.status === "workload") {
611
+ // Only the pipeline workers resolve as a principal. The platform's subject is admitted by the
612
+ // workflow routes alone; here, as everywhere else, it is refused.
613
+ const { execution } = verification;
614
+ const principal = workloadKind({ sub: execution.subject }, execution.workspaceId) !== "pipeline" ||
615
+ backend.resolvePipelineWorker === undefined
616
+ ? undefined
617
+ : yield* backend.resolvePipelineWorker(execution);
618
+ return principal === undefined
619
+ ? { status: "rejected" }
620
+ : {
621
+ status: "authenticated",
622
+ principal: { ...principal, authenticatedVia: "workload" },
623
+ caller: { kind: "workload", subjectId: principal.id },
624
+ };
625
+ }
626
+ if (verification.status !== "valid") {
627
+ return verification.status === "invalid"
628
+ ? { status: "rejected" }
629
+ : { status: "unavailable" };
630
+ }
631
+ const revision = verification.identity.provider === "neon-auth" && verifyToken.browserRevision
632
+ ? yield* Effect.promise(() => browserRevisionObservation(verifyToken.browserRevision))
633
+ : { active: true };
634
+ if (!browserRevisionAdmitted(revision)) {
635
+ return { status: "rejected" };
636
+ }
637
+ return yield* backend.resolvePrincipal(verification.identity).pipe(Effect.map((member) => member === undefined || !browserRevisionAdmitted(revision)
638
+ ? { status: "rejected" }
639
+ : {
640
+ status: "authenticated",
641
+ principal: { ...member, authenticatedVia: verification.identity.provider },
642
+ caller: { kind: "member", subjectId: member.id },
643
+ }), Effect.catchTag("NotInvited", () => Effect.succeed({ status: "not_invited" })));
644
+ });
645
+ }
646
+ /**
647
+ * Resolves the Neon Auth session cookie to a principal through the session's token. `undefined`
648
+ * when the request has no session cookie, or the service no Neon Auth.
649
+ */
650
+ function authenticateSession(request, exchangeSession, verifyToken) {
651
+ return Effect.gen(function* () {
652
+ const channelCookies = Object.entries(request.cookies).filter(([name]) => CHANNEL_COOKIE_PATTERN.test(name));
653
+ if (channelCookies.length > 0) {
654
+ if (!sessionMayAuthenticate(request)) {
655
+ return { status: "cross_origin" };
656
+ }
657
+ for (const [, token] of channelCookies) {
658
+ if (!token?.startsWith(ACCESS_TOKEN_PREFIX)) {
659
+ continue;
660
+ }
661
+ const outcome = yield* authenticate(Redacted.make(token), verifyToken, {
662
+ oauthResource: appSessionResource(publicOrigin(request)),
663
+ });
664
+ if (outcome.status === "authenticated") {
665
+ return outcome;
666
+ }
667
+ }
668
+ }
669
+ const federationCookies = Object.entries(request.cookies).filter(([name]) => /^(?:__Host-)?ss_oidc_session\.[A-Za-z0-9_-]+$/.test(name));
670
+ if (federationCookies.length > 0) {
671
+ if (!sessionMayAuthenticate(request)) {
672
+ return { status: "cross_origin" };
673
+ }
674
+ for (const [, token] of federationCookies) {
675
+ if (!token?.startsWith(FEDERATION_TOKEN_PREFIX)) {
676
+ continue;
677
+ }
678
+ const outcome = yield* authenticate(Redacted.make(token ?? ""), verifyToken);
679
+ if (outcome.status === "authenticated") {
680
+ return outcome;
681
+ }
682
+ }
683
+ return { status: "rejected" };
684
+ }
685
+ const session = request.cookies[NEON_AUTH_SESSION_COOKIE];
686
+ const origin = requestOrigin(request);
687
+ if (exchangeSession === undefined || session === undefined || session === "") {
688
+ return undefined;
689
+ }
690
+ if (origin === undefined || !sessionMayAuthenticate(request)) {
691
+ return { status: "cross_origin" };
692
+ }
693
+ const exchange = yield* Effect.promise(() => exchangeSession(Redacted.make(session), origin));
694
+ switch (exchange.status) {
695
+ case "token":
696
+ return yield* authenticate(Redacted.make(exchange.token), verifyToken);
697
+ case "invalid":
698
+ return { status: "rejected" };
699
+ case "unavailable":
700
+ return { status: "unavailable" };
701
+ }
702
+ });
703
+ }
704
+ /**
705
+ * Runs `effect` as the principal a bearer credential names, or answers the request as every route
706
+ * does: 401 without a valid credential, 403 for a person nobody invited or a session cookie sent
707
+ * from another origin, 503 while sign-in cannot be verified, and a sanitized 500 when
708
+ * authentication itself fails.
709
+ */
710
+ export function withPrincipal(credential, verifyToken, backend, effect, options = {}) {
711
+ return Effect.gen(function* () {
712
+ const requestId = yield* RequestId;
713
+ const outcome = yield* Effect.gen(function* () {
714
+ const fromSession = Redacted.value(credential) === "" && options.session !== undefined
715
+ ? yield* authenticateSession(options.session.request, options.session.exchange, verifyToken)
716
+ : undefined;
717
+ const ordinaryResource = options.session === undefined
718
+ ? undefined
719
+ : appSessionResource(publicOrigin(options.session.request));
720
+ return (fromSession ??
721
+ (yield* authenticate(credential, verifyToken, {
722
+ ...options,
723
+ oauthResource: options.oauthResource ?? ordinaryResource,
724
+ })));
725
+ }).pipe(Effect.provideService(OntologyBackend, backend), Effect.annotateLogs({ requestId }), Effect.catchCause((cause) => Cause.hasInterruptsOnly(cause)
726
+ ? Effect.failCause(cause)
727
+ : Effect.logError("ontology.authentication.failed", cause).pipe(Effect.annotateLogs({ requestId }), Effect.as({ status: "failed" }))));
728
+ switch (outcome.status) {
729
+ case "authenticated":
730
+ return yield* Effect.provideContext(effect, Context.make(CurrentPrincipal, outcome.principal).pipe(Context.add(CurrentCaller, outcome.caller)));
731
+ case "missing":
732
+ return toServerResponse(unauthorized(requestId, "A bearer token is required.", options.challenge?.(true)));
733
+ case "rejected":
734
+ return toServerResponse(unauthorized(requestId, "The bearer token is invalid, expired or revoked.", options.challenge?.(false)));
735
+ case "not_invited":
736
+ return toServerResponse(notInvited(requestId));
737
+ case "forbidden":
738
+ return toServerResponse(forbidden(requestId, outcome.detail));
739
+ case "cross_origin":
740
+ return toServerResponse(crossOriginSession(requestId));
741
+ case "unavailable":
742
+ return yield* Effect.logWarning("ontology.authentication.unavailable").pipe(Effect.annotateLogs({ requestId }), Effect.as(toServerResponse(unavailable(requestId))));
743
+ case "failed":
744
+ return toServerResponse(internalError(requestId));
745
+ }
746
+ });
747
+ }
748
+ /**
749
+ * The {@link Authentication} middleware, verifying tokens with `verifyToken`. With `exchangeSession`,
750
+ * a request without a bearer token may authenticate with the app's Neon Auth session cookie; with
751
+ * `verifyRuntime`, the deployment's own runtime token may act as the member it names.
752
+ */
753
+ export function authenticationLayer(verifyToken, exchangeSession, verifyRuntime) {
754
+ return Layer.effect(Authentication, Effect.gen(function* () {
755
+ const backend = yield* OntologyBackend;
756
+ return Authentication.of({
757
+ bearer: (httpEffect, { credential }) => Effect.gen(function* () {
758
+ const request = yield* HttpServerRequest.HttpServerRequest;
759
+ const runtime = runtimeCredential(verifyRuntime, request);
760
+ return yield* withPrincipal(credential, verifyToken, backend, httpEffect, {
761
+ session: { request, exchange: exchangeSession },
762
+ ...(runtime === undefined ? {} : { runtime }),
763
+ });
764
+ }),
765
+ });
766
+ }));
767
+ }