@kindgi/api 0.0.0-bootstrap.0 → 0.1.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 (505) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +216 -1
  3. package/dist/adapter-binding.d.ts +177 -0
  4. package/dist/adapter-binding.d.ts.map +1 -0
  5. package/dist/adapter-binding.js +12 -0
  6. package/dist/adapter-binding.js.map +1 -0
  7. package/dist/agent-binding.d.ts +207 -0
  8. package/dist/agent-binding.d.ts.map +1 -0
  9. package/dist/agent-binding.js +4 -0
  10. package/dist/agent-binding.js.map +1 -0
  11. package/dist/app.d.ts +770 -0
  12. package/dist/app.d.ts.map +1 -0
  13. package/dist/app.js +396 -0
  14. package/dist/app.js.map +1 -0
  15. package/dist/capability-binding.d.ts +76 -0
  16. package/dist/capability-binding.d.ts.map +1 -0
  17. package/dist/capability-binding.js +4 -0
  18. package/dist/capability-binding.js.map +1 -0
  19. package/dist/cost-binding.d.ts +175 -0
  20. package/dist/cost-binding.d.ts.map +1 -0
  21. package/dist/cost-binding.js +13 -0
  22. package/dist/cost-binding.js.map +1 -0
  23. package/dist/deployment-binding.d.ts +201 -0
  24. package/dist/deployment-binding.d.ts.map +1 -0
  25. package/dist/deployment-binding.js +4 -0
  26. package/dist/deployment-binding.js.map +1 -0
  27. package/dist/env-binding.d.ts +132 -0
  28. package/dist/env-binding.d.ts.map +1 -0
  29. package/dist/env-binding.js +4 -0
  30. package/dist/env-binding.js.map +1 -0
  31. package/dist/errors.d.ts +37 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +264 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/eval-run-binding.d.ts +196 -0
  36. package/dist/eval-run-binding.d.ts.map +1 -0
  37. package/dist/eval-run-binding.js +16 -0
  38. package/dist/eval-run-binding.js.map +1 -0
  39. package/dist/eval-run-dispatcher.d.ts +131 -0
  40. package/dist/eval-run-dispatcher.d.ts.map +1 -0
  41. package/dist/eval-run-dispatcher.js +368 -0
  42. package/dist/eval-run-dispatcher.js.map +1 -0
  43. package/dist/eval-suite-binding.d.ts +227 -0
  44. package/dist/eval-suite-binding.d.ts.map +1 -0
  45. package/dist/eval-suite-binding.js +24 -0
  46. package/dist/eval-suite-binding.js.map +1 -0
  47. package/dist/event-bus-binding.d.ts +107 -0
  48. package/dist/event-bus-binding.d.ts.map +1 -0
  49. package/dist/event-bus-binding.js +5 -0
  50. package/dist/event-bus-binding.js.map +1 -0
  51. package/dist/flow-binding.d.ts +194 -0
  52. package/dist/flow-binding.d.ts.map +1 -0
  53. package/dist/flow-binding.js +4 -0
  54. package/dist/flow-binding.js.map +1 -0
  55. package/dist/guardrail-binding.d.ts +138 -0
  56. package/dist/guardrail-binding.d.ts.map +1 -0
  57. package/dist/guardrail-binding.js +4 -0
  58. package/dist/guardrail-binding.js.map +1 -0
  59. package/dist/handler-binding.d.ts +126 -0
  60. package/dist/handler-binding.d.ts.map +1 -0
  61. package/dist/handler-binding.js +4 -0
  62. package/dist/handler-binding.js.map +1 -0
  63. package/dist/hitl-binding.d.ts +115 -0
  64. package/dist/hitl-binding.d.ts.map +1 -0
  65. package/dist/hitl-binding.js +4 -0
  66. package/dist/hitl-binding.js.map +1 -0
  67. package/dist/identity-directory-binding.d.ts +116 -0
  68. package/dist/identity-directory-binding.d.ts.map +1 -0
  69. package/dist/identity-directory-binding.js +4 -0
  70. package/dist/identity-directory-binding.js.map +1 -0
  71. package/dist/identity-provider-binding.d.ts +184 -0
  72. package/dist/identity-provider-binding.d.ts.map +1 -0
  73. package/dist/identity-provider-binding.js +4 -0
  74. package/dist/identity-provider-binding.js.map +1 -0
  75. package/dist/image-registry-binding.d.ts +165 -0
  76. package/dist/image-registry-binding.d.ts.map +1 -0
  77. package/dist/image-registry-binding.js +4 -0
  78. package/dist/image-registry-binding.js.map +1 -0
  79. package/dist/index.d.ts +72 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +26 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/key-management-binding.d.ts +101 -0
  84. package/dist/key-management-binding.d.ts.map +1 -0
  85. package/dist/key-management-binding.js +4 -0
  86. package/dist/key-management-binding.js.map +1 -0
  87. package/dist/mcp-endpoint-binding.d.ts +312 -0
  88. package/dist/mcp-endpoint-binding.d.ts.map +1 -0
  89. package/dist/mcp-endpoint-binding.js +12 -0
  90. package/dist/mcp-endpoint-binding.js.map +1 -0
  91. package/dist/memory-binding.d.ts +209 -0
  92. package/dist/memory-binding.d.ts.map +1 -0
  93. package/dist/memory-binding.js +4 -0
  94. package/dist/memory-binding.js.map +1 -0
  95. package/dist/middleware/auth.d.ts +168 -0
  96. package/dist/middleware/auth.d.ts.map +1 -0
  97. package/dist/middleware/auth.js +247 -0
  98. package/dist/middleware/auth.js.map +1 -0
  99. package/dist/middleware/authorize.d.ts +26 -0
  100. package/dist/middleware/authorize.d.ts.map +1 -0
  101. package/dist/middleware/authorize.js +65 -0
  102. package/dist/middleware/authorize.js.map +1 -0
  103. package/dist/middleware/error-mapper.d.ts +13 -0
  104. package/dist/middleware/error-mapper.d.ts.map +1 -0
  105. package/dist/middleware/error-mapper.js +32 -0
  106. package/dist/middleware/error-mapper.js.map +1 -0
  107. package/dist/middleware/idempotency.d.ts +43 -0
  108. package/dist/middleware/idempotency.d.ts.map +1 -0
  109. package/dist/middleware/idempotency.js +118 -0
  110. package/dist/middleware/idempotency.js.map +1 -0
  111. package/dist/middleware/principal.d.ts +4 -0
  112. package/dist/middleware/principal.d.ts.map +1 -0
  113. package/dist/middleware/principal.js +42 -0
  114. package/dist/middleware/principal.js.map +1 -0
  115. package/dist/middleware/public-run-routes.d.ts +16 -0
  116. package/dist/middleware/public-run-routes.d.ts.map +1 -0
  117. package/dist/middleware/public-run-routes.js +43 -0
  118. package/dist/middleware/public-run-routes.js.map +1 -0
  119. package/dist/middleware/request-id.d.ts +14 -0
  120. package/dist/middleware/request-id.d.ts.map +1 -0
  121. package/dist/middleware/request-id.js +24 -0
  122. package/dist/middleware/request-id.js.map +1 -0
  123. package/dist/middleware/sigv4-verify.d.ts +64 -0
  124. package/dist/middleware/sigv4-verify.d.ts.map +1 -0
  125. package/dist/middleware/sigv4-verify.js +286 -0
  126. package/dist/middleware/sigv4-verify.js.map +1 -0
  127. package/dist/middleware/sigv4.d.ts +25 -0
  128. package/dist/middleware/sigv4.d.ts.map +1 -0
  129. package/dist/middleware/sigv4.js +120 -0
  130. package/dist/middleware/sigv4.js.map +1 -0
  131. package/dist/openapi/generate.d.ts +15 -0
  132. package/dist/openapi/generate.d.ts.map +1 -0
  133. package/dist/openapi/generate.js +241 -0
  134. package/dist/openapi/generate.js.map +1 -0
  135. package/dist/openapi/operations.d.ts +70 -0
  136. package/dist/openapi/operations.d.ts.map +1 -0
  137. package/dist/openapi/operations.js +5051 -0
  138. package/dist/openapi/operations.js.map +1 -0
  139. package/dist/openapi/schemas.d.ts +590 -0
  140. package/dist/openapi/schemas.d.ts.map +1 -0
  141. package/dist/openapi/schemas.js +5820 -0
  142. package/dist/openapi/schemas.js.map +1 -0
  143. package/dist/provenance-binding.d.ts +116 -0
  144. package/dist/provenance-binding.d.ts.map +1 -0
  145. package/dist/provenance-binding.js +31 -0
  146. package/dist/provenance-binding.js.map +1 -0
  147. package/dist/provider-binding.d.ts +174 -0
  148. package/dist/provider-binding.d.ts.map +1 -0
  149. package/dist/provider-binding.js +4 -0
  150. package/dist/provider-binding.js.map +1 -0
  151. package/dist/public-run-token.d.ts +97 -0
  152. package/dist/public-run-token.d.ts.map +1 -0
  153. package/dist/public-run-token.js +167 -0
  154. package/dist/public-run-token.js.map +1 -0
  155. package/dist/retention-binding.d.ts +69 -0
  156. package/dist/retention-binding.d.ts.map +1 -0
  157. package/dist/retention-binding.js +4 -0
  158. package/dist/retention-binding.js.map +1 -0
  159. package/dist/reviewer-binding.d.ts +84 -0
  160. package/dist/reviewer-binding.d.ts.map +1 -0
  161. package/dist/reviewer-binding.js +4 -0
  162. package/dist/reviewer-binding.js.map +1 -0
  163. package/dist/rotation-status-store.d.ts +96 -0
  164. package/dist/rotation-status-store.d.ts.map +1 -0
  165. package/dist/rotation-status-store.js +106 -0
  166. package/dist/rotation-status-store.js.map +1 -0
  167. package/dist/routes/adapters.d.ts +29 -0
  168. package/dist/routes/adapters.d.ts.map +1 -0
  169. package/dist/routes/adapters.js +230 -0
  170. package/dist/routes/adapters.js.map +1 -0
  171. package/dist/routes/agents.d.ts +17 -0
  172. package/dist/routes/agents.d.ts.map +1 -0
  173. package/dist/routes/agents.js +342 -0
  174. package/dist/routes/agents.js.map +1 -0
  175. package/dist/routes/approvals.d.ts +37 -0
  176. package/dist/routes/approvals.d.ts.map +1 -0
  177. package/dist/routes/approvals.js +551 -0
  178. package/dist/routes/approvals.js.map +1 -0
  179. package/dist/routes/artifacts.d.ts +25 -0
  180. package/dist/routes/artifacts.d.ts.map +1 -0
  181. package/dist/routes/artifacts.js +265 -0
  182. package/dist/routes/artifacts.js.map +1 -0
  183. package/dist/routes/audit.d.ts +6 -0
  184. package/dist/routes/audit.d.ts.map +1 -0
  185. package/dist/routes/audit.js +162 -0
  186. package/dist/routes/audit.js.map +1 -0
  187. package/dist/routes/auth.d.ts +47 -0
  188. package/dist/routes/auth.d.ts.map +1 -0
  189. package/dist/routes/auth.js +630 -0
  190. package/dist/routes/auth.js.map +1 -0
  191. package/dist/routes/capabilities.d.ts +14 -0
  192. package/dist/routes/capabilities.d.ts.map +1 -0
  193. package/dist/routes/capabilities.js +62 -0
  194. package/dist/routes/capabilities.js.map +1 -0
  195. package/dist/routes/compliance.d.ts +37 -0
  196. package/dist/routes/compliance.d.ts.map +1 -0
  197. package/dist/routes/compliance.js +321 -0
  198. package/dist/routes/compliance.js.map +1 -0
  199. package/dist/routes/conversations.d.ts +13 -0
  200. package/dist/routes/conversations.d.ts.map +1 -0
  201. package/dist/routes/conversations.js +295 -0
  202. package/dist/routes/conversations.js.map +1 -0
  203. package/dist/routes/cost.d.ts +24 -0
  204. package/dist/routes/cost.d.ts.map +1 -0
  205. package/dist/routes/cost.js +243 -0
  206. package/dist/routes/cost.js.map +1 -0
  207. package/dist/routes/deployments.d.ts +122 -0
  208. package/dist/routes/deployments.d.ts.map +1 -0
  209. package/dist/routes/deployments.js +1036 -0
  210. package/dist/routes/deployments.js.map +1 -0
  211. package/dist/routes/env.d.ts +62 -0
  212. package/dist/routes/env.d.ts.map +1 -0
  213. package/dist/routes/env.js +311 -0
  214. package/dist/routes/env.js.map +1 -0
  215. package/dist/routes/eval-runs.d.ts +28 -0
  216. package/dist/routes/eval-runs.d.ts.map +1 -0
  217. package/dist/routes/eval-runs.js +479 -0
  218. package/dist/routes/eval-runs.js.map +1 -0
  219. package/dist/routes/eval-suites.d.ts +24 -0
  220. package/dist/routes/eval-suites.d.ts.map +1 -0
  221. package/dist/routes/eval-suites.js +381 -0
  222. package/dist/routes/eval-suites.js.map +1 -0
  223. package/dist/routes/event-triggers.d.ts +12 -0
  224. package/dist/routes/event-triggers.d.ts.map +1 -0
  225. package/dist/routes/event-triggers.js +218 -0
  226. package/dist/routes/event-triggers.js.map +1 -0
  227. package/dist/routes/flows.d.ts +23 -0
  228. package/dist/routes/flows.d.ts.map +1 -0
  229. package/dist/routes/flows.js +344 -0
  230. package/dist/routes/flows.js.map +1 -0
  231. package/dist/routes/guardrails.d.ts +33 -0
  232. package/dist/routes/guardrails.d.ts.map +1 -0
  233. package/dist/routes/guardrails.js +236 -0
  234. package/dist/routes/guardrails.js.map +1 -0
  235. package/dist/routes/identity.d.ts +39 -0
  236. package/dist/routes/identity.d.ts.map +1 -0
  237. package/dist/routes/identity.js +138 -0
  238. package/dist/routes/identity.js.map +1 -0
  239. package/dist/routes/mcp.d.ts +23 -0
  240. package/dist/routes/mcp.d.ts.map +1 -0
  241. package/dist/routes/mcp.js +727 -0
  242. package/dist/routes/mcp.js.map +1 -0
  243. package/dist/routes/memory.d.ts +16 -0
  244. package/dist/routes/memory.d.ts.map +1 -0
  245. package/dist/routes/memory.js +353 -0
  246. package/dist/routes/memory.js.map +1 -0
  247. package/dist/routes/observations.d.ts +19 -0
  248. package/dist/routes/observations.d.ts.map +1 -0
  249. package/dist/routes/observations.js +135 -0
  250. package/dist/routes/observations.js.map +1 -0
  251. package/dist/routes/orgs.d.ts +24 -0
  252. package/dist/routes/orgs.d.ts.map +1 -0
  253. package/dist/routes/orgs.js +208 -0
  254. package/dist/routes/orgs.js.map +1 -0
  255. package/dist/routes/pagination.d.ts +18 -0
  256. package/dist/routes/pagination.d.ts.map +1 -0
  257. package/dist/routes/pagination.js +35 -0
  258. package/dist/routes/pagination.js.map +1 -0
  259. package/dist/routes/policies.d.ts +23 -0
  260. package/dist/routes/policies.d.ts.map +1 -0
  261. package/dist/routes/policies.js +314 -0
  262. package/dist/routes/policies.js.map +1 -0
  263. package/dist/routes/projects.d.ts +45 -0
  264. package/dist/routes/projects.d.ts.map +1 -0
  265. package/dist/routes/projects.js +485 -0
  266. package/dist/routes/projects.js.map +1 -0
  267. package/dist/routes/proposals.d.ts +24 -0
  268. package/dist/routes/proposals.d.ts.map +1 -0
  269. package/dist/routes/proposals.js +581 -0
  270. package/dist/routes/proposals.js.map +1 -0
  271. package/dist/routes/provenance.d.ts +34 -0
  272. package/dist/routes/provenance.d.ts.map +1 -0
  273. package/dist/routes/provenance.js +274 -0
  274. package/dist/routes/provenance.js.map +1 -0
  275. package/dist/routes/providers.d.ts +32 -0
  276. package/dist/routes/providers.d.ts.map +1 -0
  277. package/dist/routes/providers.js +490 -0
  278. package/dist/routes/providers.js.map +1 -0
  279. package/dist/routes/public-run-tokens.d.ts +17 -0
  280. package/dist/routes/public-run-tokens.d.ts.map +1 -0
  281. package/dist/routes/public-run-tokens.js +69 -0
  282. package/dist/routes/public-run-tokens.js.map +1 -0
  283. package/dist/routes/retention.d.ts +19 -0
  284. package/dist/routes/retention.d.ts.map +1 -0
  285. package/dist/routes/retention.js +152 -0
  286. package/dist/routes/retention.js.map +1 -0
  287. package/dist/routes/reviewers.d.ts +5 -0
  288. package/dist/routes/reviewers.d.ts.map +1 -0
  289. package/dist/routes/reviewers.js +161 -0
  290. package/dist/routes/reviewers.js.map +1 -0
  291. package/dist/routes/runs.d.ts +34 -0
  292. package/dist/routes/runs.d.ts.map +1 -0
  293. package/dist/routes/runs.js +773 -0
  294. package/dist/routes/runs.js.map +1 -0
  295. package/dist/routes/s3.d.ts +31 -0
  296. package/dist/routes/s3.d.ts.map +1 -0
  297. package/dist/routes/s3.js +433 -0
  298. package/dist/routes/s3.js.map +1 -0
  299. package/dist/routes/schedules.d.ts +20 -0
  300. package/dist/routes/schedules.d.ts.map +1 -0
  301. package/dist/routes/schedules.js +234 -0
  302. package/dist/routes/schedules.js.map +1 -0
  303. package/dist/routes/scope-params.d.ts +57 -0
  304. package/dist/routes/scope-params.d.ts.map +1 -0
  305. package/dist/routes/scope-params.js +105 -0
  306. package/dist/routes/scope-params.js.map +1 -0
  307. package/dist/routes/secret-ref.d.ts +20 -0
  308. package/dist/routes/secret-ref.d.ts.map +1 -0
  309. package/dist/routes/secret-ref.js +42 -0
  310. package/dist/routes/secret-ref.js.map +1 -0
  311. package/dist/routes/secrets.d.ts +53 -0
  312. package/dist/routes/secrets.d.ts.map +1 -0
  313. package/dist/routes/secrets.js +715 -0
  314. package/dist/routes/secrets.js.map +1 -0
  315. package/dist/routes/signing-keys.d.ts +23 -0
  316. package/dist/routes/signing-keys.d.ts.map +1 -0
  317. package/dist/routes/signing-keys.js +212 -0
  318. package/dist/routes/signing-keys.js.map +1 -0
  319. package/dist/routes/sse.d.ts +58 -0
  320. package/dist/routes/sse.d.ts.map +1 -0
  321. package/dist/routes/sse.js +92 -0
  322. package/dist/routes/sse.js.map +1 -0
  323. package/dist/routes/teams.d.ts +30 -0
  324. package/dist/routes/teams.d.ts.map +1 -0
  325. package/dist/routes/teams.js +443 -0
  326. package/dist/routes/teams.js.map +1 -0
  327. package/dist/routes/tenant.d.ts +57 -0
  328. package/dist/routes/tenant.d.ts.map +1 -0
  329. package/dist/routes/tenant.js +352 -0
  330. package/dist/routes/tenant.js.map +1 -0
  331. package/dist/routes/tokens.d.ts +14 -0
  332. package/dist/routes/tokens.d.ts.map +1 -0
  333. package/dist/routes/tokens.js +231 -0
  334. package/dist/routes/tokens.js.map +1 -0
  335. package/dist/routes/tools.d.ts +33 -0
  336. package/dist/routes/tools.d.ts.map +1 -0
  337. package/dist/routes/tools.js +380 -0
  338. package/dist/routes/tools.js.map +1 -0
  339. package/dist/routes/webhook-endpoints.d.ts +10 -0
  340. package/dist/routes/webhook-endpoints.d.ts.map +1 -0
  341. package/dist/routes/webhook-endpoints.js +407 -0
  342. package/dist/routes/webhook-endpoints.js.map +1 -0
  343. package/dist/routes/webhooks.d.ts +21 -0
  344. package/dist/routes/webhooks.d.ts.map +1 -0
  345. package/dist/routes/webhooks.js +228 -0
  346. package/dist/routes/webhooks.js.map +1 -0
  347. package/dist/s3-credential-binding.d.ts +54 -0
  348. package/dist/s3-credential-binding.d.ts.map +1 -0
  349. package/dist/s3-credential-binding.js +4 -0
  350. package/dist/s3-credential-binding.js.map +1 -0
  351. package/dist/secrets-binding.d.ts +281 -0
  352. package/dist/secrets-binding.d.ts.map +1 -0
  353. package/dist/secrets-binding.js +10 -0
  354. package/dist/secrets-binding.js.map +1 -0
  355. package/dist/secrets-provider-binding.d.ts +164 -0
  356. package/dist/secrets-provider-binding.d.ts.map +1 -0
  357. package/dist/secrets-provider-binding.js +4 -0
  358. package/dist/secrets-provider-binding.js.map +1 -0
  359. package/dist/session-store-binding.d.ts +148 -0
  360. package/dist/session-store-binding.d.ts.map +1 -0
  361. package/dist/session-store-binding.js +4 -0
  362. package/dist/session-store-binding.js.map +1 -0
  363. package/dist/signing-key-binding.d.ts +210 -0
  364. package/dist/signing-key-binding.d.ts.map +1 -0
  365. package/dist/signing-key-binding.js +4 -0
  366. package/dist/signing-key-binding.js.map +1 -0
  367. package/dist/state-store-binding.d.ts +53 -0
  368. package/dist/state-store-binding.d.ts.map +1 -0
  369. package/dist/state-store-binding.js +38 -0
  370. package/dist/state-store-binding.js.map +1 -0
  371. package/dist/supervisor-binding.d.ts +526 -0
  372. package/dist/supervisor-binding.d.ts.map +1 -0
  373. package/dist/supervisor-binding.js +4 -0
  374. package/dist/supervisor-binding.js.map +1 -0
  375. package/dist/tenant-host-access.d.ts +41 -0
  376. package/dist/tenant-host-access.d.ts.map +1 -0
  377. package/dist/tenant-host-access.js +42 -0
  378. package/dist/tenant-host-access.js.map +1 -0
  379. package/dist/token-admin.d.ts +99 -0
  380. package/dist/token-admin.d.ts.map +1 -0
  381. package/dist/token-admin.js +4 -0
  382. package/dist/token-admin.js.map +1 -0
  383. package/dist/tool-binding.d.ts +247 -0
  384. package/dist/tool-binding.d.ts.map +1 -0
  385. package/dist/tool-binding.js +4 -0
  386. package/dist/tool-binding.js.map +1 -0
  387. package/dist/trigger-binding.d.ts +13 -0
  388. package/dist/trigger-binding.d.ts.map +1 -0
  389. package/dist/trigger-binding.js +4 -0
  390. package/dist/trigger-binding.js.map +1 -0
  391. package/dist/types.d.ts +71 -0
  392. package/dist/types.d.ts.map +1 -0
  393. package/dist/types.js +4 -0
  394. package/dist/types.js.map +1 -0
  395. package/dist/webhook-endpoint-binding.d.ts +230 -0
  396. package/dist/webhook-endpoint-binding.d.ts.map +1 -0
  397. package/dist/webhook-endpoint-binding.js +12 -0
  398. package/dist/webhook-endpoint-binding.js.map +1 -0
  399. package/dist/xml.d.ts +79 -0
  400. package/dist/xml.d.ts.map +1 -0
  401. package/dist/xml.js +115 -0
  402. package/dist/xml.js.map +1 -0
  403. package/openapi.json +29659 -0
  404. package/package.json +76 -4
  405. package/scripts/emit-openapi.mjs +44 -0
  406. package/src/adapter-binding.ts +204 -0
  407. package/src/agent-binding.ts +231 -0
  408. package/src/app.ts +1285 -0
  409. package/src/capability-binding.ts +83 -0
  410. package/src/cost-binding.ts +213 -0
  411. package/src/deployment-binding.ts +225 -0
  412. package/src/env-binding.ts +140 -0
  413. package/src/errors.ts +291 -0
  414. package/src/eval-run-binding.ts +209 -0
  415. package/src/eval-run-dispatcher.ts +497 -0
  416. package/src/eval-suite-binding.ts +257 -0
  417. package/src/event-bus-binding.ts +127 -0
  418. package/src/flow-binding.ts +213 -0
  419. package/src/guardrail-binding.ts +151 -0
  420. package/src/handler-binding.ts +132 -0
  421. package/src/hitl-binding.ts +172 -0
  422. package/src/identity-directory-binding.ts +128 -0
  423. package/src/identity-provider-binding.ts +203 -0
  424. package/src/image-registry-binding.ts +193 -0
  425. package/src/index.ts +606 -0
  426. package/src/key-management-binding.ts +91 -0
  427. package/src/mcp-endpoint-binding.ts +311 -0
  428. package/src/memory-binding.ts +239 -0
  429. package/src/middleware/auth.ts +437 -0
  430. package/src/middleware/authorize.ts +125 -0
  431. package/src/middleware/error-mapper.ts +37 -0
  432. package/src/middleware/idempotency.ts +160 -0
  433. package/src/middleware/principal.ts +64 -0
  434. package/src/middleware/public-run-routes.ts +50 -0
  435. package/src/middleware/request-id.ts +28 -0
  436. package/src/middleware/sigv4-verify.ts +374 -0
  437. package/src/middleware/sigv4.ts +165 -0
  438. package/src/openapi/generate.ts +307 -0
  439. package/src/openapi/operations.ts +5445 -0
  440. package/src/openapi/schemas.ts +6363 -0
  441. package/src/provenance-binding.ts +169 -0
  442. package/src/provider-binding.ts +196 -0
  443. package/src/public-run-token.ts +263 -0
  444. package/src/retention-binding.ts +78 -0
  445. package/src/reviewer-binding.ts +99 -0
  446. package/src/rotation-status-store.ts +209 -0
  447. package/src/routes/adapters.ts +319 -0
  448. package/src/routes/agents.ts +424 -0
  449. package/src/routes/approvals.ts +759 -0
  450. package/src/routes/artifacts.ts +317 -0
  451. package/src/routes/audit.ts +219 -0
  452. package/src/routes/auth.ts +806 -0
  453. package/src/routes/capabilities.ts +79 -0
  454. package/src/routes/compliance.ts +482 -0
  455. package/src/routes/conversations.ts +369 -0
  456. package/src/routes/cost.ts +327 -0
  457. package/src/routes/deployments.ts +1493 -0
  458. package/src/routes/env.ts +429 -0
  459. package/src/routes/eval-runs.ts +631 -0
  460. package/src/routes/eval-suites.ts +490 -0
  461. package/src/routes/event-triggers.ts +283 -0
  462. package/src/routes/flows.ts +423 -0
  463. package/src/routes/guardrails.ts +320 -0
  464. package/src/routes/identity.ts +203 -0
  465. package/src/routes/mcp.ts +940 -0
  466. package/src/routes/memory.ts +430 -0
  467. package/src/routes/observations.ts +175 -0
  468. package/src/routes/orgs.ts +273 -0
  469. package/src/routes/pagination.ts +51 -0
  470. package/src/routes/policies.ts +413 -0
  471. package/src/routes/projects.ts +634 -0
  472. package/src/routes/proposals.ts +719 -0
  473. package/src/routes/provenance.ts +406 -0
  474. package/src/routes/providers.ts +624 -0
  475. package/src/routes/public-run-tokens.ts +104 -0
  476. package/src/routes/retention.ts +193 -0
  477. package/src/routes/reviewers.ts +209 -0
  478. package/src/routes/runs.ts +981 -0
  479. package/src/routes/s3.ts +519 -0
  480. package/src/routes/schedules.ts +300 -0
  481. package/src/routes/scope-params.ts +133 -0
  482. package/src/routes/secret-ref.ts +52 -0
  483. package/src/routes/secrets.ts +975 -0
  484. package/src/routes/signing-keys.ts +259 -0
  485. package/src/routes/sse.ts +148 -0
  486. package/src/routes/teams.ts +584 -0
  487. package/src/routes/tenant.ts +530 -0
  488. package/src/routes/tokens.ts +285 -0
  489. package/src/routes/tools.ts +491 -0
  490. package/src/routes/webhook-endpoints.ts +534 -0
  491. package/src/routes/webhooks.ts +296 -0
  492. package/src/s3-credential-binding.ts +58 -0
  493. package/src/secrets-binding.ts +308 -0
  494. package/src/secrets-provider-binding.ts +167 -0
  495. package/src/session-store-binding.ts +163 -0
  496. package/src/signing-key-binding.ts +235 -0
  497. package/src/state-store-binding.ts +84 -0
  498. package/src/supervisor-binding.ts +554 -0
  499. package/src/tenant-host-access.ts +62 -0
  500. package/src/token-admin.ts +104 -0
  501. package/src/tool-binding.ts +274 -0
  502. package/src/trigger-binding.ts +38 -0
  503. package/src/types.ts +74 -0
  504. package/src/webhook-endpoint-binding.ts +246 -0
  505. package/src/xml.ts +196 -0
@@ -0,0 +1,437 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type { Context, MiddlewareHandler, Next } from 'hono';
5
+
6
+ import type { ReviewerRole } from '@kindgi/authz';
7
+ import type { ApiTokenId, SessionId, TenantId, UserId } from '@kindgi/types';
8
+
9
+ import type { SigningKeyBinding } from '@kindgi/crypto';
10
+
11
+ import { statusFor, toWireError } from '../errors.js';
12
+ import { PUBLIC_RUN_TOKEN_PREFIX, verifyPublicRunToken } from '../public-run-token.js';
13
+ import type { SessionStoreBinding } from '../session-store-binding.js';
14
+
15
+ /**
16
+ * Resolve an API token → tenant identity. For static bearer tokens this
17
+ * is a caller-injected function: the platform's actual token store (auth
18
+ * service, database, …) plugs in. Signature stays stable across
19
+ * implementations.
20
+ *
21
+ * Return `null` for missing / expired / revoked tokens; the middleware
22
+ * translates to 401 with a specific error code.
23
+ */
24
+ export type TokenResolver = (token: string) => Promise<TokenResolution | null>;
25
+
26
+ export interface TokenResolution {
27
+ readonly tenantId: TenantId;
28
+ /**
29
+ * Optional expiration; if set and in the past, the middleware treats
30
+ * as expired even if the resolver returned a value.
31
+ */
32
+ readonly expiresAt?: Date;
33
+ /** Optional revocation marker; `true` → 401 auth-revoked. */
34
+ readonly revoked?: boolean;
35
+ /**
36
+ * Optional reviewer role granted to this token. When present, the
37
+ * middleware surfaces it as `c.get('reviewerRole')` and approvals
38
+ * routes gate visibility / decisions on the `standard < senior < admin`
39
+ * hierarchy. Absent for tokens that were never provisioned with a
40
+ * reviewer role — such tokens can still hit `/v1/runs` etc., but any
41
+ * approvals route returns `403 permission-denied`.
42
+ */
43
+ readonly reviewerRole?: ReviewerRole;
44
+ /**
45
+ * Optional user identity behind the token. Approvals routes forward
46
+ * this to a `ReviewerBinding` to translate `UserId → ReviewerId`
47
+ * before calling `hitl.submitReview` (which needs the reviewer id).
48
+ */
49
+ readonly userId?: UserId;
50
+ /**
51
+ * The id of a durable API key (`POST /v1/tokens`). The caller is then
52
+ * the key's service account (`service_account:<tokenId>`), not a user;
53
+ * the middleware surfaces it as `c.get('tokenId')`.
54
+ */
55
+ readonly tokenId?: ApiTokenId;
56
+ /**
57
+ * Optional session id. Populated by the session-token verifier path
58
+ * (`kgi_sk_*` tokens) so `/v1/identity/whoami` and `/v1/auth/logout`
59
+ * can introspect / revoke the caller's own session without a second
60
+ * lookup. Absent for static bearer tokens.
61
+ */
62
+ readonly sessionId?: SessionId;
63
+ /**
64
+ * Optional identity-provider id that authenticated the caller. Only
65
+ * populated by session-token verification.
66
+ */
67
+ readonly providerId?: string;
68
+ /**
69
+ * Optional OAuth scopes granted to the session. Only populated by
70
+ * session-token verification.
71
+ */
72
+ readonly scopes?: readonly string[];
73
+ /**
74
+ * Optional last-observed-activity timestamp. Populated by
75
+ * `resolveSessionToken` when the session-store adapter carries
76
+ * `lastActiveAt` on the row. Used by the middleware to enforce the
77
+ * `inactivityTimeoutMs` policy. Absent → inactivity check is
78
+ * skipped.
79
+ */
80
+ readonly lastActiveAt?: Date;
81
+ /**
82
+ * Optional flag set by `resolveSessionToken` when the session was
83
+ * revoked specifically via rotation (`POST /v1/auth/refresh`). The
84
+ * middleware maps this to `401 refresh-token-invalid` instead of
85
+ * the generic `401 auth-revoked`, matching OAuth 2.1 BCP refresh-
86
+ * token-reuse semantics.
87
+ */
88
+ readonly rotated?: boolean;
89
+ /**
90
+ * Optional framework capabilities granted to the bearer. Route
91
+ * handlers gate write / reveal ops on
92
+ * specific capability strings (`env:write`, `secrets:write`,
93
+ * `secrets:rotate`, `secrets:revoke`, `secrets:revoke:hard`,
94
+ * `secrets:reveal`, `kindgi:system`). Callers that plug their
95
+ * own resolver populate this list from their token store; deployments
96
+ * without capability data leave it absent — routes that require a
97
+ * capability then return 403 `permission-denied`.
98
+ *
99
+ * Kindgi's stance: fail-closed on writes when the capability is
100
+ * unset (a token without an explicit `secrets:write` claim cannot
101
+ * mutate the secrets store). Deployments that want any authenticated
102
+ * bearer to be able to write grant the capability on every token.
103
+ */
104
+ readonly capabilities?: readonly string[];
105
+ }
106
+
107
+ /**
108
+ * Session-token prefix. Framework-issued opaque tokens minted by
109
+ * `POST /v1/auth/callback/:providerId` carry this prefix so the auth
110
+ * middleware can route them to the session store instead of the caller-
111
+ * plugged `TokenResolver`. Distinct prefix means a static bearer token
112
+ * and a session token can coexist byte-shape-identical on the wire.
113
+ */
114
+ export const SESSION_TOKEN_PREFIX = 'kgi_sk_' as const;
115
+
116
+ /**
117
+ * Compose the on-wire session token from a `SessionId`. Session tokens
118
+ * are opaque to clients — the shape below is a framework convention,
119
+ * not part of the wire contract. Do NOT parse it in downstream code
120
+ * outside the middleware.
121
+ */
122
+ export function encodeSessionToken(sessionId: SessionId): string {
123
+ return `${SESSION_TOKEN_PREFIX}${sessionId as unknown as string}`;
124
+ }
125
+
126
+ /**
127
+ * Optional wiring for the session-token flavor. Provided to the
128
+ * middleware via `bearerAuthMiddleware(resolveToken, { sessionStore })`
129
+ * when the deployment mounts `SessionStoreBinding`. Absent → session-
130
+ * shape tokens fall through to `TokenResolver` (which will typically
131
+ * `null` them → 401 auth-missing) so a deployment without a session
132
+ * store still behaves consistently.
133
+ */
134
+ export interface BearerAuthMiddlewareOptions {
135
+ readonly sessionStore?: SessionStoreBinding;
136
+ /**
137
+ * Inactivity timeout — sessions whose `lastActiveAt` is older than
138
+ * `Date.now() - inactivityTimeoutMs` are rejected with 401
139
+ * `session-inactive`. Absent → inactivity enforcement disabled
140
+ * (only absolute TTL applies).
141
+ *
142
+ * Sensible default: 4 hours (`4 * 60 * 60 * 1000`). Deployments
143
+ * customize via `CreateAppInput.session.inactivityTimeout`.
144
+ */
145
+ readonly inactivityTimeoutMs?: number;
146
+ /**
147
+ * How often (per session) the middleware should call
148
+ * `sessionStore.touch` to bump `lastActiveAt`. Higher throttle ⇒
149
+ * fewer writes but coarser inactivity enforcement. Defaults to 60s.
150
+ */
151
+ readonly touchThrottleMs?: number;
152
+ /**
153
+ * Accept public run tokens (`kgi_pt_…`), verified against
154
+ * `signingKey`, on the routes `isAllowed` admits (every other route
155
+ * answers 403). Absent → such tokens are not recognized (401).
156
+ */
157
+ readonly publicRunTokens?: {
158
+ readonly signingKey: SigningKeyBinding;
159
+ readonly isAllowed: (method: string, path: string) => boolean;
160
+ };
161
+ }
162
+
163
+ const DEFAULT_TOUCH_THROTTLE_MS = 60_000;
164
+
165
+ /**
166
+ * Bearer-token middleware. Fails 401 on missing / malformed / expired /
167
+ * revoked. On success, sets `c.set('tenantId', tenantId)` for downstream
168
+ * handlers.
169
+ *
170
+ * Two token flavors are accepted:
171
+ * - `kgi_sk_<sessionId>` — framework-issued OAuth session tokens.
172
+ * Verified via `sessionStore.get`; expiration + revocation are pulled
173
+ * from the session row.
174
+ * - anything else — caller-plugged static bearer tokens. Verified via
175
+ * `resolveToken`. Byte-shape-identical with the session-less contract.
176
+ */
177
+ export function bearerAuthMiddleware(
178
+ resolve: TokenResolver,
179
+ options: BearerAuthMiddlewareOptions = {},
180
+ ): MiddlewareHandler {
181
+ const { sessionStore, inactivityTimeoutMs } = options;
182
+ const touchThrottleMs = options.touchThrottleMs ?? DEFAULT_TOUCH_THROTTLE_MS;
183
+ // Per-process throttle bucket: session id → last touch millis.
184
+ // A shared Map is fine — session ids are opaque strings and the
185
+ // bucket is bounded by the number of active sessions the process
186
+ // has recently observed.
187
+ const touchBucket = new Map<string, number>();
188
+ return async (c, next) => {
189
+ const requestId = c.get('requestId') as string;
190
+ const header = c.req.header('authorization');
191
+ if (header === undefined || header.length === 0) {
192
+ const body = toWireError(
193
+ { code: 'auth-missing', message: 'Authorization header is required' },
194
+ requestId,
195
+ );
196
+ return c.json(body, statusFor('auth-missing') as never);
197
+ }
198
+ const match = /^Bearer\s+(.+)$/i.exec(header);
199
+ if (match === null) {
200
+ const body = toWireError(
201
+ {
202
+ code: 'auth-missing',
203
+ message: 'Authorization header must be "Bearer <token>"',
204
+ },
205
+ requestId,
206
+ );
207
+ return c.json(body, statusFor('auth-missing') as never);
208
+ }
209
+ const token = match[1]?.trim() ?? '';
210
+ if (token.length === 0) {
211
+ const body = toWireError(
212
+ { code: 'auth-missing', message: 'Bearer token is empty' },
213
+ requestId,
214
+ );
215
+ return c.json(body, statusFor('auth-missing') as never);
216
+ }
217
+
218
+ if (token.startsWith(PUBLIC_RUN_TOKEN_PREFIX)) {
219
+ return authenticatePublicRunToken(c, next, token, requestId, options.publicRunTokens);
220
+ }
221
+
222
+ const isSessionToken = sessionStore !== undefined && token.startsWith(SESSION_TOKEN_PREFIX);
223
+ const resolution = isSessionToken
224
+ ? await resolveSessionToken(sessionStore!, token)
225
+ : await resolve(token);
226
+ if (resolution === null) {
227
+ const body = toWireError(
228
+ { code: 'auth-missing', message: 'Bearer token is not recognized' },
229
+ requestId,
230
+ );
231
+ return c.json(body, statusFor('auth-missing') as never);
232
+ }
233
+ if (resolution.revoked === true) {
234
+ // Rotated sessions surface as `refresh-token-invalid` — OAuth 2.1
235
+ // BCP reuse detection. The old session token is no longer valid,
236
+ // but the semantic distinction from an explicit revoke matters
237
+ // to compliant clients (they retry with the fresh token instead
238
+ // of prompting the user to re-authenticate).
239
+ if (resolution.rotated === true) {
240
+ const body = toWireError(
241
+ {
242
+ code: 'refresh-token-invalid',
243
+ message: 'Session token was rotated — retry with the fresh token from the last refresh',
244
+ },
245
+ requestId,
246
+ );
247
+ return c.json(body, statusFor('refresh-token-invalid') as never);
248
+ }
249
+ const body = toWireError(
250
+ { code: 'auth-revoked', message: 'Bearer token has been revoked' },
251
+ requestId,
252
+ );
253
+ return c.json(body, statusFor('auth-revoked') as never);
254
+ }
255
+ if (resolution.expiresAt !== undefined && resolution.expiresAt.getTime() < Date.now()) {
256
+ // Session tokens report `session-expired` so callers can
257
+ // distinguish absolute session TTL from bearer-token expiry.
258
+ const expiredCode = isSessionToken ? 'session-expired' : 'auth-expired';
259
+ const expiredMsg = isSessionToken
260
+ ? 'Session has expired (absolute TTL reached)'
261
+ : 'Bearer token has expired';
262
+ const body = toWireError({ code: expiredCode, message: expiredMsg }, requestId);
263
+ return c.json(body, statusFor(expiredCode) as never);
264
+ }
265
+ // Inactivity timeout enforcement. Only applies when the deployment
266
+ // opted in via `inactivityTimeoutMs` AND the token is a session
267
+ // token AND the store populated `lastActiveAt`. Skipping the check
268
+ // preserves the default contract for deployments that don't wire
269
+ // the config.
270
+ if (
271
+ isSessionToken &&
272
+ inactivityTimeoutMs !== undefined &&
273
+ inactivityTimeoutMs > 0 &&
274
+ resolution.lastActiveAt !== undefined
275
+ ) {
276
+ const cutoff = Date.now() - inactivityTimeoutMs;
277
+ if (resolution.lastActiveAt.getTime() < cutoff) {
278
+ const body = toWireError(
279
+ {
280
+ code: 'session-inactive',
281
+ message: 'Session has been idle beyond the inactivity timeout',
282
+ },
283
+ requestId,
284
+ );
285
+ return c.json(body, statusFor('session-inactive') as never);
286
+ }
287
+ }
288
+
289
+ c.set('tenantId', resolution.tenantId);
290
+ if (resolution.reviewerRole !== undefined) {
291
+ c.set('reviewerRole', resolution.reviewerRole);
292
+ }
293
+ if (resolution.userId !== undefined) {
294
+ c.set('userId', resolution.userId);
295
+ }
296
+ if (resolution.tokenId !== undefined) {
297
+ c.set('tokenId', resolution.tokenId);
298
+ }
299
+ if (resolution.sessionId !== undefined) {
300
+ c.set('sessionId', resolution.sessionId);
301
+ }
302
+ if (resolution.providerId !== undefined) {
303
+ c.set('providerId', resolution.providerId);
304
+ }
305
+ if (resolution.scopes !== undefined) {
306
+ c.set('scopes', resolution.scopes);
307
+ }
308
+ if (resolution.capabilities !== undefined) {
309
+ c.set('capabilities', resolution.capabilities);
310
+ }
311
+
312
+ // Bump `lastActiveAt` (throttled) so the inactivity timeout has
313
+ // a fresh signal to compare against. Only meaningful for session
314
+ // tokens with a wired `touch()`; bearer tokens are skipped.
315
+ if (isSessionToken && sessionStore?.touch !== undefined && resolution.sessionId !== undefined) {
316
+ const sid = resolution.sessionId as unknown as string;
317
+ const last = touchBucket.get(sid) ?? 0;
318
+ const now = Date.now();
319
+ if (now - last >= touchThrottleMs) {
320
+ touchBucket.set(sid, now);
321
+ // Fire-and-forget; we don't want the write path to hold the
322
+ // request. Adapter errors surface via observability, not the
323
+ // hot path (the next check catches a genuinely stale row).
324
+ void sessionStore
325
+ .touch({
326
+ tenantId: resolution.tenantId,
327
+ sessionId: resolution.sessionId,
328
+ at: new Date(now),
329
+ })
330
+ .catch(() => {
331
+ // Best-effort — the next request retries.
332
+ });
333
+ }
334
+ }
335
+
336
+ await next();
337
+ return;
338
+ };
339
+ }
340
+
341
+ /**
342
+ * Session-token verification path. Distinct from `TokenResolver` because
343
+ * a session carries structured OAuth context (userId + providerId +
344
+ * scopes + expiration + revocation) that the store returns natively —
345
+ * we don't want to squeeze that shape through the resolver contract.
346
+ *
347
+ * Session-token tenant scoping: the stored session is the source of
348
+ * truth for `tenantId`. We look up ACROSS tenants here — the resolved
349
+ * `tenantId` is whatever the session was written under, so everything
350
+ * downstream is scoped to that tenant only. A stolen session token still
351
+ * can't cross tenants because the session it points to belongs to
352
+ * exactly one tenant.
353
+ *
354
+ * Since `SessionStoreBinding.get` requires `tenantId`, the lookup is:
355
+ * extract `sessionId` from the token, then call
356
+ * `sessionStore.get({ tenantId: MULTI_TENANT_LOOKUP, sessionId })`.
357
+ * Session-store implementations MUST recognize the `MULTI_TENANT_LOOKUP`
358
+ * sentinel and skip the tenant filter; the `tenantId` on the stored
359
+ * session is authoritative.
360
+ */
361
+ async function resolveSessionToken(
362
+ sessionStore: SessionStoreBinding,
363
+ token: string,
364
+ ): Promise<TokenResolution | null> {
365
+ const sessionIdStr = token.slice(SESSION_TOKEN_PREFIX.length);
366
+ if (sessionIdStr.length === 0) return null;
367
+ const sessionId = sessionIdStr as unknown as SessionId;
368
+ const session = await sessionStore.get({
369
+ tenantId: MULTI_TENANT_LOOKUP,
370
+ sessionId,
371
+ });
372
+ if (session === null) return null;
373
+ return {
374
+ tenantId: session.tenantId,
375
+ userId: session.userId as unknown as UserId,
376
+ sessionId: session.id,
377
+ providerId: session.providerId,
378
+ scopes: session.scopes,
379
+ expiresAt: new Date(session.expiresAt as unknown as string),
380
+ revoked: session.revokedAt !== undefined,
381
+ ...(session.rotatedAt !== undefined && { rotated: true }),
382
+ ...(session.lastActiveAt !== undefined && {
383
+ lastActiveAt: new Date(session.lastActiveAt as unknown as string),
384
+ }),
385
+ };
386
+ }
387
+
388
+ /**
389
+ * Sentinel `tenantId` value the middleware passes to
390
+ * `SessionStoreBinding.get` when it needs to look up a session by its
391
+ * id without knowing the tenant in advance. Session-store adapters
392
+ * MUST honor this by skipping the tenant filter — the tenant is not
393
+ * known until the session row has been read.
394
+ */
395
+ export const MULTI_TENANT_LOOKUP = '__kindgi_session_multi_tenant_lookup__' as unknown as TenantId;
396
+
397
+ /**
398
+ * A public run token: verify it, admit only the routes it may use, and
399
+ * mark the request so the progress routes check it against the runs
400
+ * it names.
401
+ */
402
+ async function authenticatePublicRunToken(
403
+ c: Context,
404
+ next: Next,
405
+ token: string,
406
+ requestId: string,
407
+ config: BearerAuthMiddlewareOptions['publicRunTokens'],
408
+ ): Promise<Response | undefined> {
409
+ const verified =
410
+ config === undefined
411
+ ? ({ kind: 'err', reason: 'unknown-key' } as const)
412
+ : verifyPublicRunToken(token, { signingKey: config.signingKey });
413
+ if (verified.kind === 'err') {
414
+ const expired = verified.reason === 'expired';
415
+ const code = expired ? 'auth-expired' : 'auth-missing';
416
+ const message = expired ? 'Public run token has expired' : 'Bearer token is not recognized';
417
+ return c.json(toWireError({ code, message }, requestId), statusFor(code) as never);
418
+ }
419
+ if (config === undefined || !config.isAllowed(c.req.method, c.req.path)) {
420
+ return c.json(
421
+ toWireError(
422
+ {
423
+ code: 'permission-denied',
424
+ message:
425
+ 'A public run token can only follow the runs it names: GET /v1/runs/{runId}/progress and GET /v1/runs/{runId}/progress/stream',
426
+ },
427
+ requestId,
428
+ ),
429
+ statusFor('permission-denied') as never,
430
+ );
431
+ }
432
+ c.set('tenantId', verified.claims.tenantId);
433
+ c.set('tokenKind', 'public-run');
434
+ c.set('publicRunIds', verified.claims.runIds);
435
+ await next();
436
+ return undefined;
437
+ }
@@ -0,0 +1,125 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ //
5
+ // authorize / can — Hono PEP for HTTP routes.
6
+ //
7
+ // createAuthorizer(binding) returns helpers curried against an
8
+ // `AuthzCheckBinding` (the PDP):
9
+ //
10
+ // authorize(action, resourceGetter) → Hono middleware, 403s on deny
11
+ // can(c, action, resource) → boolean, for conditional logic
12
+ // check(c, action, resource) → full Decision, for advanced cases
13
+ // filterByCan(c, action, items, fn) → the items the principal may act on
14
+ //
15
+ // Use `authorize` on any mutating route. Use `can` inside handlers when
16
+ // the decision affects response shape (e.g. filter results, include
17
+ // admin-only fields, etc.).
18
+ //
19
+
20
+ import type { Context, MiddlewareHandler } from 'hono';
21
+
22
+ import {
23
+ type Action,
24
+ type AuthzCheckBinding,
25
+ type Decision,
26
+ type Principal,
27
+ type ResourceRef,
28
+ denyPayload,
29
+ } from '@kindgi/authz';
30
+
31
+ import type { AppEnv } from '../types.js';
32
+
33
+ /**
34
+ * Callback that produces the resource being acted upon from the Hono
35
+ * context. Called at request time — can read path params, query, or
36
+ * body (if already parsed).
37
+ */
38
+ export type ResourceGetter = (c: Context<AppEnv>) => ResourceRef | Promise<ResourceRef>;
39
+
40
+ export interface Authorizer {
41
+ readonly authorize: (action: Action, getResource: ResourceGetter) => MiddlewareHandler<AppEnv>;
42
+ readonly can: (c: Context<AppEnv>, action: Action, resource: ResourceRef) => Promise<boolean>;
43
+ readonly check: (c: Context<AppEnv>, action: Action, resource: ResourceRef) => Promise<Decision>;
44
+ /**
45
+ * List-filtering helper — takes items + a ref-extractor and returns
46
+ * only those items where the principal has `action` on the derived
47
+ * resource. Preserves input order. Empty in → empty out.
48
+ *
49
+ * Use in GET-list route handlers after fetching tenant-scoped rows;
50
+ * strips rows the caller can't read so the response only includes
51
+ * what they'd be allowed to touch.
52
+ */
53
+ readonly filterByCan: <T>(
54
+ c: Context<AppEnv>,
55
+ action: Action,
56
+ items: readonly T[],
57
+ refFn: (item: T) => ResourceRef,
58
+ ) => Promise<T[]>;
59
+ }
60
+
61
+ export function createAuthorizer(binding: AuthzCheckBinding): Authorizer {
62
+ async function checkInternal(
63
+ c: Context<AppEnv>,
64
+ action: Action,
65
+ resource: ResourceRef,
66
+ ): Promise<Decision> {
67
+ const principal = c.get('principal') as Principal | undefined;
68
+ if (principal === undefined) {
69
+ return {
70
+ allowed: false,
71
+ failing: 'actor',
72
+ reason: 'no principal on request (bearer/principal middleware did not run)',
73
+ evidence: {
74
+ action,
75
+ relation: '',
76
+ resource: `${resource.type}:${resource.id}`,
77
+ actorSubject: '',
78
+ },
79
+ };
80
+ }
81
+ const requestId = c.get('requestId');
82
+ const ctx =
83
+ typeof requestId === 'string' && requestId.length > 0
84
+ ? { correlationId: requestId }
85
+ : undefined;
86
+ return binding.check(principal, action, resource, ctx);
87
+ }
88
+
89
+ return {
90
+ check: checkInternal,
91
+ async can(c, action, resource) {
92
+ const d = await checkInternal(c, action, resource);
93
+ return d.allowed;
94
+ },
95
+ authorize(action, getResource) {
96
+ return async (c, next) => {
97
+ const resource = await getResource(c);
98
+ const decision = await checkInternal(c, action, resource);
99
+ if (!decision.allowed) {
100
+ const body = denyPayload(action, resource.type, resource.id, decision.reason);
101
+ c.status(403);
102
+ return c.json(body);
103
+ }
104
+ return next();
105
+ };
106
+ },
107
+ async filterByCan(c, action, items, refFn) {
108
+ if (items.length === 0) return [];
109
+ const principal = c.get('principal') as Principal | undefined;
110
+ if (principal === undefined) return [];
111
+ const refs = items.map(refFn);
112
+ const requestId = c.get('requestId');
113
+ const ctx =
114
+ typeof requestId === 'string' && requestId.length > 0
115
+ ? { correlationId: requestId }
116
+ : undefined;
117
+ const decisions = await binding.checkBatch(principal, action, refs, ctx);
118
+ const out: (typeof items)[number][] = [];
119
+ for (let i = 0; i < items.length; i++) {
120
+ if (decisions[i]?.allowed) out.push(items[i] as (typeof items)[number]);
121
+ }
122
+ return out;
123
+ },
124
+ };
125
+ }
@@ -0,0 +1,37 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type { MiddlewareHandler } from 'hono';
5
+
6
+ import { statusFor, toWireError } from '../errors.js';
7
+
8
+ /**
9
+ * Top-level catch-all. Any uncaught exception is translated to a
10
+ * `500 internal-server-error` wire error. Domain errors returned via
11
+ * `Result<T, E>` are handled per-route — this middleware only catches
12
+ * thrown exceptions (framework bugs, DB failures without Result wrap,
13
+ * etc.).
14
+ *
15
+ * The requestId embedded in the response body matches
16
+ * `middleware/request-id.ts`, so a caller can correlate.
17
+ */
18
+ export function errorMapperMiddleware(): MiddlewareHandler {
19
+ return async (c, next) => {
20
+ try {
21
+ await next();
22
+ return;
23
+ } catch (cause) {
24
+ const requestId = (c.get('requestId') as string | undefined) ?? 'req-unknown';
25
+ const message = cause instanceof Error ? cause.message : String(cause);
26
+ const body = toWireError(
27
+ {
28
+ code: 'internal-server-error',
29
+ message: message.length > 0 ? message : 'Unhandled server error',
30
+ },
31
+ requestId,
32
+ );
33
+ c.status(statusFor('internal-server-error') as never);
34
+ return c.json(body);
35
+ }
36
+ };
37
+ }