@nylorun/runtime 0.15.2-beta → 0.17.0-beta

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 (291) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +68 -29
  3. package/dist/adapters/execution/restate.d.ts +9 -1
  4. package/dist/adapters/execution/restate.js +64 -5
  5. package/dist/adapters/sandbox/local.d.ts +10 -0
  6. package/dist/adapters/sandbox/local.js +195 -0
  7. package/dist/adapters/sandbox/virtual.js +36 -1
  8. package/dist/admin-openapi.json +341 -7
  9. package/dist/api/a2a/tasks.js +6 -1
  10. package/dist/api/ag-ui/endpoint.js +1 -2
  11. package/dist/api/ag-ui/history.js +6 -1
  12. package/dist/api/ag-ui/routes.d.ts +1 -1
  13. package/dist/api/ag-ui/routes.js +15 -13
  14. package/dist/api/components.d.ts +2667 -711
  15. package/dist/api/components.js +24 -11
  16. package/dist/api/gate/keys.d.ts +4 -3
  17. package/dist/api/gate/routes.d.ts +19 -3
  18. package/dist/api/gate/routes.js +162 -53
  19. package/dist/api/http/app.js +6 -0
  20. package/dist/api/http/define.d.ts +19 -12
  21. package/dist/api/http/define.js +13 -27
  22. package/dist/api/http/routes/access.d.ts +3 -19
  23. package/dist/api/http/routes/access.js +12 -172
  24. package/dist/api/http/routes/actions.js +0 -1
  25. package/dist/api/http/routes/artifacts.d.ts +11 -0
  26. package/dist/api/http/routes/artifacts.js +516 -0
  27. package/dist/api/http/routes/me.d.ts +13 -0
  28. package/dist/api/http/routes/me.js +45 -0
  29. package/dist/api/http/routes/sandboxes.d.ts +9 -0
  30. package/dist/api/http/routes/sandboxes.js +150 -0
  31. package/dist/api/http/routes/sessions.js +9 -13
  32. package/dist/api/http/routes/tenant.js +36 -2
  33. package/dist/api/http/routes/vaults.d.ts +12 -3
  34. package/dist/api/http/routes/vaults.js +122 -54
  35. package/dist/api/openapi.js +4 -10
  36. package/dist/artifacts/config.d.ts +23 -0
  37. package/dist/artifacts/config.js +27 -0
  38. package/dist/artifacts/export.d.ts +8 -0
  39. package/dist/artifacts/export.js +205 -0
  40. package/dist/artifacts/files.d.ts +36 -0
  41. package/dist/artifacts/files.js +45 -0
  42. package/dist/artifacts/folders.d.ts +60 -0
  43. package/dist/artifacts/folders.js +209 -0
  44. package/dist/artifacts/links.d.ts +28 -0
  45. package/dist/artifacts/links.js +92 -0
  46. package/dist/artifacts/media-types.d.ts +13 -0
  47. package/dist/artifacts/media-types.js +80 -0
  48. package/dist/artifacts/parts.d.ts +34 -0
  49. package/dist/artifacts/parts.js +38 -0
  50. package/dist/artifacts/service.d.ts +74 -0
  51. package/dist/artifacts/service.js +301 -0
  52. package/dist/artifacts/workspace.d.ts +60 -0
  53. package/dist/artifacts/workspace.js +57 -0
  54. package/dist/artifacts/zip.d.ts +10 -0
  55. package/dist/artifacts/zip.js +126 -0
  56. package/dist/blob/fs.d.ts +13 -0
  57. package/dist/blob/fs.js +194 -0
  58. package/dist/blob/index.d.ts +9 -0
  59. package/dist/blob/index.js +9 -0
  60. package/dist/blob/s3.d.ts +42 -0
  61. package/dist/blob/s3.js +366 -0
  62. package/dist/blob/types.d.ts +108 -0
  63. package/dist/blob/types.js +85 -0
  64. package/dist/core/sandbox-routes.d.ts +2 -2
  65. package/dist/core/sandbox-routes.js +4 -3
  66. package/dist/execution/memory.d.ts +11 -1
  67. package/dist/execution/memory.js +77 -3
  68. package/dist/execution/types.d.ts +54 -1
  69. package/dist/execution/types.js +31 -0
  70. package/dist/gates/contract.d.ts +14 -13
  71. package/dist/gates/contract.js +13 -12
  72. package/dist/gates/egress.d.ts +72 -0
  73. package/dist/gates/egress.js +319 -0
  74. package/dist/gates/handler.d.ts +3 -0
  75. package/dist/gates/handler.js +3 -2
  76. package/dist/gates/http-client.d.ts +3 -2
  77. package/dist/gates/http-client.js +17 -6
  78. package/dist/gates/in-process.d.ts +13 -1
  79. package/dist/gates/in-process.js +11 -0
  80. package/dist/gates/inflight.d.ts +23 -4
  81. package/dist/gates/inflight.js +18 -4
  82. package/dist/gates/mcp-handler.js +5 -1
  83. package/dist/gates/model-gate.d.ts +6 -2
  84. package/dist/gates/tenant-vaults.d.ts +18 -9
  85. package/dist/gates/tenant-vaults.js +17 -12
  86. package/dist/gates/tool-calls.d.ts +9 -5
  87. package/dist/gates/tool-calls.js +6 -6
  88. package/dist/gates/tool-client.d.ts +9 -2
  89. package/dist/gates/tool-client.js +56 -22
  90. package/dist/gates/tool-contract.d.ts +12 -7
  91. package/dist/gates/tool-contract.js +10 -4
  92. package/dist/gates/tool-gate.d.ts +1 -0
  93. package/dist/harness/calls.d.ts +52 -0
  94. package/dist/harness/calls.js +113 -0
  95. package/dist/harness/executors.d.ts +22 -0
  96. package/dist/harness/executors.js +96 -0
  97. package/dist/harness/main.d.ts +6 -0
  98. package/dist/harness/main.js +103 -0
  99. package/dist/harness/pod.d.ts +21 -0
  100. package/dist/harness/pod.js +119 -0
  101. package/dist/harness/run-tokens.d.ts +18 -0
  102. package/dist/harness/run-tokens.js +15 -0
  103. package/dist/harness/service.d.ts +46 -0
  104. package/dist/harness/service.js +179 -0
  105. package/dist/harness/ws-client.d.ts +43 -0
  106. package/dist/harness/ws-client.js +122 -0
  107. package/dist/harness/ws-port.d.ts +22 -0
  108. package/dist/harness/ws-port.js +78 -0
  109. package/dist/harness-api/in-process.d.ts +24 -0
  110. package/dist/harness-api/in-process.js +119 -0
  111. package/dist/harness-api/record.d.ts +44 -0
  112. package/dist/harness-api/record.js +250 -0
  113. package/dist/harness-api/renew.d.ts +37 -0
  114. package/dist/harness-api/renew.js +77 -0
  115. package/dist/harness-api/server.d.ts +104 -0
  116. package/dist/harness-api/server.js +408 -0
  117. package/dist/harness-api/start.d.ts +36 -0
  118. package/dist/harness-api/start.js +118 -0
  119. package/dist/harness-api/workspace.d.ts +53 -0
  120. package/dist/harness-api/workspace.js +201 -0
  121. package/dist/harness-api/ws-server.d.ts +34 -0
  122. package/dist/harness-api/ws-server.js +227 -0
  123. package/dist/host/admin-api.d.ts +12 -5
  124. package/dist/host/admin-api.js +72 -6
  125. package/dist/host/app.d.ts +0 -1
  126. package/dist/host/app.js +35 -24
  127. package/dist/host/config-for.d.ts +4 -0
  128. package/dist/host/config-for.js +2 -0
  129. package/dist/host/config.d.ts +0 -6
  130. package/dist/host/create-host.d.ts +3 -10
  131. package/dist/host/create-host.js +4 -1
  132. package/dist/host/gates.d.ts +27 -2
  133. package/dist/host/gates.js +52 -2
  134. package/dist/host/http.d.ts +4 -1
  135. package/dist/host/http.js +6 -1
  136. package/dist/host/main.js +167 -37
  137. package/dist/host/stack-config.d.ts +112 -9
  138. package/dist/host/stack-config.js +222 -20
  139. package/dist/index.d.ts +3 -0
  140. package/dist/index.js +2 -0
  141. package/dist/keys/client.js +9 -1
  142. package/dist/keys/keys.d.ts +12 -2
  143. package/dist/keys/keys.js +8 -0
  144. package/dist/mcp/connect.js +2 -1
  145. package/dist/mcp/pool.d.ts +1 -0
  146. package/dist/mcp/pool.js +1 -0
  147. package/dist/mcp/snapshot.d.ts +8 -1
  148. package/dist/mcp/snapshot.js +28 -0
  149. package/dist/media.d.ts +5 -24
  150. package/dist/media.js +5 -0
  151. package/dist/model/pi-model.d.ts +6 -2
  152. package/dist/model/pi-model.js +39 -22
  153. package/dist/node/index.d.ts +1 -1
  154. package/dist/node/index.js +1 -1
  155. package/dist/openapi.json +14084 -9426
  156. package/dist/record/index.d.ts +1 -0
  157. package/dist/record/index.js +1 -0
  158. package/dist/record/sandbox.d.ts +25 -0
  159. package/dist/record/sandbox.js +43 -0
  160. package/dist/sandbox/capability.d.ts +3 -0
  161. package/dist/sandbox/capability.js +10 -0
  162. package/dist/sandbox/egress-token.d.ts +26 -0
  163. package/dist/sandbox/egress-token.js +8 -0
  164. package/dist/sandbox/join.d.ts +37 -0
  165. package/dist/sandbox/join.js +165 -0
  166. package/dist/sandbox/manager.d.ts +99 -34
  167. package/dist/sandbox/manager.js +216 -84
  168. package/dist/sandbox/placement.d.ts +27 -0
  169. package/dist/sandbox/placement.js +44 -0
  170. package/dist/sandbox/pods/client.d.ts +90 -0
  171. package/dist/sandbox/pods/client.js +79 -0
  172. package/dist/sandbox/pods/lifecycle.d.ts +91 -0
  173. package/dist/sandbox/pods/lifecycle.js +178 -0
  174. package/dist/sandbox/pods/name.d.ts +1 -0
  175. package/dist/sandbox/pods/name.js +28 -0
  176. package/dist/sandbox/pods/network-gate.d.ts +25 -0
  177. package/dist/sandbox/pods/network-gate.js +71 -0
  178. package/dist/sandbox/pods/reconcile.d.ts +11 -0
  179. package/dist/sandbox/pods/reconcile.js +152 -0
  180. package/dist/sandbox/pods/spec.d.ts +45 -0
  181. package/dist/sandbox/pods/spec.js +62 -0
  182. package/dist/sandbox/records.d.ts +29 -0
  183. package/dist/sandbox/records.js +79 -0
  184. package/dist/sandbox/resolve.d.ts +5 -0
  185. package/dist/sandbox/resolve.js +3 -2
  186. package/dist/sandbox/session-sandbox.js +7 -5
  187. package/dist/sandbox/share.d.ts +11 -0
  188. package/dist/sandbox/share.js +10 -0
  189. package/dist/sandbox/tenant-config.d.ts +16 -1
  190. package/dist/sandbox/tenant-config.js +9 -0
  191. package/dist/sandbox/types.d.ts +29 -1
  192. package/dist/sandbox/types.js +13 -1
  193. package/dist/store/postgres/drizzle/0004_sandbox_resources.sql +20 -0
  194. package/dist/store/postgres/drizzle/0005_artifacts.sql +27 -0
  195. package/dist/store/postgres/drizzle/0006_folder_artifacts.sql +12 -0
  196. package/dist/store/postgres/drizzle/0007_sandbox_pods.sql +14 -0
  197. package/dist/store/postgres/drizzle/0008_installation_vaults.sql +2 -0
  198. package/dist/store/postgres/drizzle/0009_oauth_pending.sql +19 -0
  199. package/dist/store/postgres/drizzle/0010_oss_auth_removals.sql +3 -0
  200. package/dist/store/postgres/drizzle/meta/_journal.json +49 -0
  201. package/dist/store/postgres/record-writer.d.ts +6 -1
  202. package/dist/store/postgres/record-writer.js +20 -2
  203. package/dist/store/postgres/schema.d.ts +1168 -250
  204. package/dist/store/postgres/schema.js +174 -28
  205. package/dist/store/postgres/store.js +339 -103
  206. package/dist/store/postgres/tenant.d.ts +1 -1
  207. package/dist/store/postgres/tenant.js +2 -2
  208. package/dist/store/types.d.ts +163 -32
  209. package/dist/streams/control.d.ts +2 -5
  210. package/dist/streams/control.js +5 -8
  211. package/dist/streams/types.d.ts +8 -8
  212. package/dist/streams/types.js +1 -1
  213. package/dist/tenant/advance.js +218 -160
  214. package/dist/tenant/artifact-tool.d.ts +5 -0
  215. package/dist/tenant/artifact-tool.js +119 -0
  216. package/dist/tenant/auth.d.ts +13 -9
  217. package/dist/tenant/auth.js +25 -32
  218. package/dist/tenant/commands.js +31 -10
  219. package/dist/tenant/context.d.ts +83 -26
  220. package/dist/tenant/delivery-token.js +4 -4
  221. package/dist/tenant/effects.d.ts +24 -14
  222. package/dist/tenant/effects.js +10 -398
  223. package/dist/tenant/ephemeral.d.ts +14 -2
  224. package/dist/tenant/ephemeral.js +8 -1
  225. package/dist/tenant/history.d.ts +13 -23
  226. package/dist/tenant/history.js +14 -62
  227. package/dist/tenant/host-token.d.ts +92 -0
  228. package/dist/tenant/host-token.js +179 -0
  229. package/dist/tenant/identity-file.d.ts +75 -0
  230. package/dist/tenant/identity-file.js +202 -0
  231. package/dist/tenant/issuers.d.ts +48 -0
  232. package/dist/tenant/issuers.js +311 -0
  233. package/dist/tenant/jwt.js +3 -3
  234. package/dist/tenant/module.js +1 -0
  235. package/dist/tenant/operator-keys.d.ts +18 -0
  236. package/dist/tenant/operator-keys.js +55 -0
  237. package/dist/tenant/outbound.d.ts +30 -0
  238. package/dist/tenant/outbound.js +142 -10
  239. package/dist/tenant/paths.d.ts +2 -1
  240. package/dist/tenant/paths.js +3 -1
  241. package/dist/tenant/principals.d.ts +2 -11
  242. package/dist/tenant/principals.js +10 -30
  243. package/dist/tenant/reset.d.ts +5 -2
  244. package/dist/tenant/reset.js +22 -2
  245. package/dist/tenant/run-grants.d.ts +49 -0
  246. package/dist/tenant/run-grants.js +62 -0
  247. package/dist/tenant/run-token.d.ts +70 -0
  248. package/dist/tenant/run-token.js +138 -0
  249. package/dist/tenant/runtime.d.ts +42 -0
  250. package/dist/tenant/runtime.js +134 -33
  251. package/dist/tenant/sandboxes.d.ts +119 -0
  252. package/dist/tenant/sandboxes.js +551 -0
  253. package/dist/tenant/session-streams.d.ts +6 -10
  254. package/dist/tenant/session-streams.js +9 -27
  255. package/dist/tenant/session.d.ts +2 -13
  256. package/dist/tenant/session.js +4 -28
  257. package/dist/tenant/sessions.d.ts +6 -1
  258. package/dist/tenant/sessions.js +29 -2
  259. package/dist/tenant/signing-keys.d.ts +2 -1
  260. package/dist/tenant/signing-keys.js +2 -2
  261. package/dist/tenant/status.d.ts +8 -3
  262. package/dist/tenant/status.js +5 -0
  263. package/dist/tenant/streams.d.ts +8 -2
  264. package/dist/tenant/streams.js +25 -6
  265. package/dist/tenant/sweep.js +37 -4
  266. package/dist/tenant/types.d.ts +39 -1
  267. package/dist/tenant/worker.d.ts +11 -5
  268. package/dist/tenant/worker.js +12 -6
  269. package/dist/vault/crypto.d.ts +7 -0
  270. package/dist/vault/crypto.js +16 -0
  271. package/dist/vault/oauth.d.ts +55 -0
  272. package/dist/vault/oauth.js +186 -0
  273. package/dist/vault/service.d.ts +54 -7
  274. package/dist/vault/service.js +261 -17
  275. package/dist/vault/sources.d.ts +54 -0
  276. package/dist/vault/sources.js +185 -0
  277. package/dist/version.d.ts +1 -1
  278. package/dist/version.js +1 -1
  279. package/package.json +14 -10
  280. package/dist/adapters/media.d.ts +0 -24
  281. package/dist/adapters/media.js +0 -111
  282. package/dist/host/cors.d.ts +0 -27
  283. package/dist/host/cors.js +0 -64
  284. package/dist/tenant/access-policy.d.ts +0 -30
  285. package/dist/tenant/access-policy.js +0 -52
  286. package/dist/tenant/browser.d.ts +0 -15
  287. package/dist/tenant/browser.js +0 -39
  288. package/dist/tenant/subject-limits.d.ts +0 -16
  289. package/dist/tenant/subject-limits.js +0 -45
  290. package/dist/tenant/tokens.d.ts +0 -14
  291. package/dist/tenant/tokens.js +0 -180
@@ -1,14 +1,12 @@
1
1
  import { z } from "zod";
2
2
  import { PROTOCOL_VERSION } from "@nylorun/core/compatibility";
3
3
  import { authenticate, requireScopes } from "../../tenant/auth.js";
4
- import { identifyClient } from "../../tenant/browser.js";
5
4
  import { fail } from "../../tenant/http.js";
6
5
  import { ProtocolRejected, Rejected } from "../components.js";
7
6
  const SCHEMES = {
8
7
  application: "applicationKey",
9
8
  subject: "applicationKey",
10
- token: "subjectToken",
11
- publishable: "publishableKey",
9
+ token: "issuerToken",
12
10
  delivery: "deliveryToken",
13
11
  };
14
12
  const rejected = (description) => ({
@@ -29,17 +27,14 @@ export function pathSegments(incoming) {
29
27
  }
30
28
  });
31
29
  }
32
- /** Who is calling: the browser client and the bearer, as every Tenant request checks them. */
30
+ /** Who is calling: the bearer, as every Tenant request checks it. */
33
31
  export async function authenticateCaller(c,
34
32
  /** The route serves public data (`RouteAccess.anonymous`): no credential is needed. */
35
33
  anonymous = false) {
36
- const { tenant, incoming, outgoing } = c.env;
37
- // The client app first: a browser's origin is checked, and CORS headers set, before the
38
- // bearer is looked at, so every answer from here on is readable by an allowed page.
39
- const client = await identifyClient(tenant, incoming, outgoing);
40
- if (anonymous && !client && incoming.headers.authorization === undefined)
34
+ const { tenant, incoming } = c.env;
35
+ if (anonymous && incoming.headers.authorization === undefined)
41
36
  return { kind: "anonymous" };
42
- return await authenticate(tenant, incoming, client);
37
+ return await authenticate(tenant, incoming);
43
38
  }
44
39
  const declared = [];
45
40
  /** The declared route `method path` is, if any. `{param}` segments match any one segment. */
@@ -53,10 +48,6 @@ function authenticated(access) {
53
48
  return async (c, next) => {
54
49
  const scope = await authenticateCaller(c, access.anonymous === true);
55
50
  requireScopes(scope, access.scopes);
56
- if (scope.kind === "publishable" && !access.credentials.includes("publishable"))
57
- fail(403, "A publishable key alone reaches only the agent list", {
58
- code: "scope_required",
59
- });
60
51
  // Handlers tell callers apart by kind, and a delivery token is none of theirs: only the
61
52
  // routes that list it may see one.
62
53
  if (scope.kind === "delivery" && !access.credentials.includes("delivery"))
@@ -68,8 +59,9 @@ function authenticated(access) {
68
59
  export function tenantRoute(api, access, route, handler) {
69
60
  const takes = (credential) => access.credentials.includes(credential);
70
61
  const schemes = [...new Set(access.credentials.map((credential) => SCHEMES[credential]))];
62
+ const protocol = z.string().meta({ description: `The protocol version, \`${PROTOCOL_VERSION}\`` });
71
63
  const headers = z.object({
72
- "Nylorun-Protocol": z.string().meta({ description: `The protocol version, \`${PROTOCOL_VERSION}\`` }),
64
+ "Nylorun-Protocol": access.unversioned ? protocol.optional() : protocol,
73
65
  ...(takes("subject")
74
66
  ? {
75
67
  "Nylorun-Subject": z
@@ -82,14 +74,6 @@ export function tenantRoute(api, access, route, handler) {
82
74
  .meta({ description: "The subject's space-separated scopes; required with a subject" }),
83
75
  }
84
76
  : {}),
85
- ...(takes("publishable")
86
- ? {
87
- "Nylorun-Key": z
88
- .string()
89
- .optional()
90
- .meta({ description: "A publishable key, from a browser page on an allowed origin" }),
91
- }
92
- : {}),
93
77
  });
94
78
  api.openAPIRegistry.registerPath({
95
79
  ...route,
@@ -101,17 +85,19 @@ export function tenantRoute(api, access, route, handler) {
101
85
  request: { ...route.request, headers },
102
86
  responses: {
103
87
  400: rejected("Invalid headers, path, body or cursor"),
104
- ...(takes("token") ? { 401: rejected("The subject token expired or was revoked (`token_expired`)") } : {}),
105
- 403: rejected("Not allowed for this credential, subject scope or origin"),
88
+ ...(takes("token")
89
+ ? {
90
+ 401: rejected("The token expired (`token_expired`), or its issuer's keys cannot be fetched now (`issuer_unavailable`)"),
91
+ }
92
+ : {}),
93
+ 403: rejected("Not allowed for this credential or subject scope, or an application key from a browser (`origin_rejected`)"),
106
94
  404: rejected("Not found, or a credential the Tenant does not know (`not_found`)"),
107
95
  426: { description: "`Nylorun-Protocol` missing or unsupported", content: { "application/json": { schema: ProtocolRejected } } },
108
- ...(takes("token") ? { 429: rejected("The subject's turn limits are reached (`limit_exceeded`)") } : {}),
109
96
  503: rejected("The Tenant's storage or streams are unavailable"),
110
97
  ...route.responses,
111
98
  },
112
99
  "x-nylorun-credentials": access.credentials,
113
100
  "x-nylorun-scopes": access.scopes,
114
- "x-nylorun-browser": access.browser === true,
115
101
  });
116
102
  declared.push({
117
103
  method: route.method.toUpperCase(),
@@ -1,24 +1,8 @@
1
1
  /**
2
- * Access management (Host feature `subject-tokens`), for the application key only: subject
3
- * tokens, the access policy, signing keys, publishable keys and subject revocation; and the
4
- * public keys, for any caller that reached the Tenant.
5
- *
6
- * Subjects travel in bodies, not paths, because they may be email addresses and request paths
7
- * are logged.
2
+ * Signing keys, for the application key only, and the public keys, for any caller that reached
3
+ * the Tenant: the Runtime signs delivery tokens and capability links with them (protocol 7 has
4
+ * no subject tokens, access policy, browser keys or revocations).
8
5
  */
9
6
  import type { OpenAPIHono } from "@hono/zod-openapi";
10
- import type { PublishableKey as PublishableKeyBody } from "@nylorun/core/contracts";
11
- import type { PublishableKeyRow } from "../../../store/types.js";
12
- import type { TenantContext } from "../../../tenant/context.js";
13
7
  import type { TenantEnv } from "../app.js";
14
8
  export declare function accessRoutes(api: OpenAPIHono<TenantEnv>): void;
15
- /** A publishable key as the API shows it. */
16
- export declare function publishableKeyView(row: PublishableKeyRow): PublishableKeyBody;
17
- /**
18
- * Ends every token of `subject` minted so far: bumps its epoch, then ends its open streams
19
- * here and, through `tenant/control`, on every other process. Running turns continue.
20
- */
21
- export declare function revokeSubject(ctx: TenantContext, subject: string): Promise<{
22
- subject: string;
23
- epoch: number;
24
- }>;
@@ -1,14 +1,8 @@
1
1
  import { z } from "zod";
2
- import { newPublishableKey, newPublishableKeyId } from "@nylorun/core/compatibility";
3
- import { CreatePublishableKeyRequestSchema, CreateTokenRequestSchema, PutAccessPolicyRequestSchema, RevokeSigningKeyRequestSchema, RevokeSubjectRequestSchema, RotateSigningKeysRequestSchema, UpdatePublishableKeyRequestSchema, } from "@nylorun/core/contracts";
4
- import { AccessPolicyResponse, CreatePublishableKeyRequest, CreateTokenRequest, CreateTokenResponse, Jwks, ListPublishableKeysResponse, PublishableKey, PutAccessPolicyRequest, RevokeSigningKeyRequest, RevokeSubjectRequest, RevokeSubjectResponse, RotateSigningKeysRequest, SigningKeyList, SigningKeyView, UpdatePublishableKeyRequest, } from "../../components.js";
5
- import { signalSubjectRevoked } from "../../../streams/control.js";
6
- import { readPolicy, writePolicy } from "../../../tenant/access-policy.js";
7
- import { currentBasin, endSubjectStreams } from "../../../tenant/session-streams.js";
2
+ import { RevokeSigningKeyRequestSchema, RotateSigningKeysRequestSchema, TOKEN_TTL_MAX_SECONDS, } from "@nylorun/core/contracts";
3
+ import { Jwks, RevokeSigningKeyRequest, RotateSigningKeysRequest, SigningKeyList, SigningKeyView, } from "../../components.js";
8
4
  import { requireApplication } from "../../../tenant/auth.js";
9
- import { fail } from "../../../tenant/http.js";
10
5
  import { publicJwk, signingKeyView } from "../../../tenant/signing-keys.js";
11
- import { mintToken } from "../../../tenant/tokens.js";
12
6
  import { readJson } from "../body.js";
13
7
  import { tenantRoute } from "../define.js";
14
8
  import { jsonResponse } from "../respond.js";
@@ -21,21 +15,19 @@ const body = (schema) => ({
21
15
  required: true,
22
16
  content: { "application/json": { schema } },
23
17
  });
24
- const keyId = z.object({ keyId: z.string() });
25
18
  export function accessRoutes(api) {
26
19
  tenantRoute(api, {
27
- credentials: ["application", "subject", "token", "publishable"],
20
+ credentials: ["application", "subject", "token"],
28
21
  scopes: "any",
29
- browser: true,
30
22
  // Public keys: an Action endpoint verifies delivery tokens with them and holds no key.
31
23
  anonymous: true,
32
24
  }, {
33
25
  method: "get",
34
26
  path: "/v1/access/jwks",
35
27
  tags: ["Access"],
36
- summary: "Get the public keys subject and delivery tokens are signed with",
37
- description: "A JSON Web Key Set, to verify a subject token or a delivery token without calling the " +
38
- "Runtime. No credential is needed.",
28
+ summary: "Get the public keys delivery tokens are signed with",
29
+ description: "A JSON Web Key Set, to verify a delivery token without calling the Runtime. No " +
30
+ "credential is needed.",
39
31
  responses: { 200: json(Jwks, "The public keys") },
40
32
  }, async (c) => {
41
33
  // Anonymous: reads the public keys. Only when the current or standby key is missing does
@@ -49,41 +41,6 @@ export function accessRoutes(api) {
49
41
  }
50
42
  return jsonResponse(200, { keys: rows.map(publicJwk) });
51
43
  });
52
- tenantRoute(api, APPLICATION, {
53
- method: "post",
54
- path: "/v1/tokens",
55
- tags: ["Access"],
56
- summary: "Mint a subject token",
57
- description: "A token for one person and one role of the access policy, for their browser or app to call the Runtime with. At most 15 minutes.",
58
- request: { body: body(CreateTokenRequest) },
59
- responses: { 200: json(CreateTokenResponse, "The token, its scopes and expiry") },
60
- }, async (c) => {
61
- requireApplication(c.get("scope"));
62
- return jsonResponse(200, await mintToken(c.env.tenant, CreateTokenRequestSchema.parse(await readJson(c.req.raw))));
63
- });
64
- tenantRoute(api, APPLICATION, {
65
- method: "get",
66
- path: "/v1/access/policy",
67
- tags: ["Access"],
68
- summary: "Get the access policy",
69
- responses: { 200: json(AccessPolicyResponse, "Roles, the anonymous grant and token lifetime") },
70
- }, async (c) => {
71
- requireApplication(c.get("scope"));
72
- return jsonResponse(200, { policy: await c.env.tenant.store.tx((t) => readPolicy(t)) });
73
- });
74
- tenantRoute(api, APPLICATION, {
75
- method: "put",
76
- path: "/v1/access/policy",
77
- tags: ["Access"],
78
- summary: "Set the access policy",
79
- request: { body: body(PutAccessPolicyRequest) },
80
- responses: { 200: json(AccessPolicyResponse, "The policy now in force") },
81
- }, async (c) => {
82
- requireApplication(c.get("scope"));
83
- const request = PutAccessPolicyRequestSchema.parse(await readJson(c.req.raw));
84
- await c.env.tenant.store.tx((t) => writePolicy(t, request.policy));
85
- return jsonResponse(200, { policy: request.policy });
86
- });
87
44
  tenantRoute(api, APPLICATION, {
88
45
  method: "get",
89
46
  path: "/v1/access/signing-keys",
@@ -106,7 +63,7 @@ export function accessRoutes(api) {
106
63
  path: "/v1/access/signing-keys/rotate",
107
64
  tags: ["Access"],
108
65
  summary: "Rotate the signing keys",
109
- description: "The standby key signs from now on; the current one still verifies tokens it signed. `force` also ends every outstanding token.",
66
+ description: "The standby key signs from now on; the current one still verifies tokens it signed. `force` also ends every outstanding delivery token and capability link.",
110
67
  request: { body: body(RotateSigningKeysRequest) },
111
68
  responses: {
112
69
  200: json(SigningKeyList, "The keys after rotation"),
@@ -116,8 +73,11 @@ export function accessRoutes(api) {
116
73
  requireApplication(c.get("scope"));
117
74
  const ctx = c.env.tenant;
118
75
  const request = RotateSigningKeysRequestSchema.parse(await readJson(c.req.raw));
119
- const maxTtlSeconds = await ctx.store.tx(async (t) => (await readPolicy(t)).tokens.maxTtlSeconds);
120
- const keys = await ctx.keys.rotateSigningKeys({ maxTtlSeconds, force: request.force === true });
76
+ // The longest any token the Runtime signs lives (delivery tokens, capability links).
77
+ const keys = await ctx.keys.rotateSigningKeys({
78
+ maxTtlSeconds: TOKEN_TTL_MAX_SECONDS,
79
+ force: request.force === true,
80
+ });
121
81
  ctx.config.logger.info("signing keys rotated", { force: request.force === true });
122
82
  return jsonResponse(200, { keys });
123
83
  });
@@ -139,126 +99,6 @@ export function accessRoutes(api) {
139
99
  ctx.config.logger.info("signing key revoked", { kid: row.id });
140
100
  return jsonResponse(200, signingKeyView(row));
141
101
  });
142
- tenantRoute(api, APPLICATION, {
143
- method: "get",
144
- path: "/v1/access/publishable-keys",
145
- tags: ["Access"],
146
- summary: "List publishable keys",
147
- responses: { 200: json(ListPublishableKeysResponse, "The keys, revoked ones included") },
148
- }, async (c) => {
149
- requireApplication(c.get("scope"));
150
- return jsonResponse(200, {
151
- keys: (await c.env.tenant.store.tx((t) => t.publishableKeys())).map(publishableKeyView),
152
- });
153
- });
154
- tenantRoute(api, APPLICATION, {
155
- method: "post",
156
- path: "/v1/access/publishable-keys",
157
- tags: ["Access"],
158
- summary: "Create a publishable key",
159
- description: "A key a browser page on one of the origins sends as `Nylorun-Key`. Public by design; it grants the policy's anonymous scopes.",
160
- request: { body: body(CreatePublishableKeyRequest) },
161
- responses: {
162
- 200: json(PublishableKey, "The key"),
163
- 409: { description: "A key with this name exists" },
164
- },
165
- }, async (c) => {
166
- requireApplication(c.get("scope"));
167
- const ctx = c.env.tenant;
168
- const request = CreatePublishableKeyRequestSchema.parse(await readJson(c.req.raw));
169
- const row = {
170
- id: newPublishableKeyId(),
171
- key: newPublishableKey(ctx.config.tenantId),
172
- name: request.name,
173
- originsJson: JSON.stringify(request.origins),
174
- createdAt: new Date().toISOString(),
175
- revokedAt: null,
176
- };
177
- await ctx.store.tx(async (t) => {
178
- if ((await t.publishableKeys()).some((other) => other.name === request.name))
179
- fail(409, `A publishable key named ${request.name} exists`);
180
- await t.insertPublishableKey(row);
181
- });
182
- ctx.config.logger.info("publishable key created", { keyId: row.id });
183
- return jsonResponse(200, publishableKeyView(row));
184
- });
185
- for (const method of ["put", "delete"])
186
- tenantRoute(api, APPLICATION, {
187
- method,
188
- path: "/v1/access/publishable-keys/{keyId}",
189
- tags: ["Access"],
190
- summary: method === "put" ? "Set a publishable key's origins" : "Revoke a publishable key",
191
- request: {
192
- params: keyId,
193
- ...(method === "put" ? { body: body(UpdatePublishableKeyRequest) } : {}),
194
- },
195
- responses: {
196
- 200: json(PublishableKey, method === "put" ? "The key" : "The key, revoked (again: unchanged)"),
197
- },
198
- }, async (c) => {
199
- requireApplication(c.get("scope"));
200
- const ctx = c.env.tenant;
201
- const id = c.req.param("keyId");
202
- const patch = method === "put"
203
- ? {
204
- originsJson: JSON.stringify(UpdatePublishableKeyRequestSchema.parse(await readJson(c.req.raw)).origins),
205
- }
206
- : { revokedAt: new Date().toISOString() };
207
- const row = await ctx.store.tx(async (t) => {
208
- const existing = (await t.publishableKey(id)) ?? fail(404, "Publishable key not found");
209
- // Revoking twice keeps the first time.
210
- if (method === "delete" && existing.revokedAt !== null)
211
- return existing;
212
- await t.updatePublishableKey(id, patch);
213
- return { ...existing, ...patch };
214
- });
215
- ctx.config.logger.info(method === "put" ? "publishable key updated" : "publishable key revoked", { keyId: row.id });
216
- return jsonResponse(200, publishableKeyView(row));
217
- });
218
- tenantRoute(api, APPLICATION, {
219
- method: "post",
220
- path: "/v1/access/revocations",
221
- tags: ["Access"],
222
- summary: "Revoke a subject",
223
- description: "Ends every token minted for the subject so far, and their open streams on every process. Turns in progress continue.",
224
- request: { body: body(RevokeSubjectRequest) },
225
- responses: { 200: json(RevokeSubjectResponse, "The subject's new epoch") },
226
- }, async (c) => {
227
- requireApplication(c.get("scope"));
228
- const request = RevokeSubjectRequestSchema.parse(await readJson(c.req.raw));
229
- return jsonResponse(200, await revokeSubject(c.env.tenant, request.subject));
230
- });
231
- }
232
- /** A publishable key as the API shows it. */
233
- export function publishableKeyView(row) {
234
- return {
235
- id: row.id,
236
- name: row.name,
237
- key: row.key,
238
- origins: JSON.parse(row.originsJson),
239
- createdAt: row.createdAt,
240
- revokedAt: row.revokedAt,
241
- };
242
- }
243
- /**
244
- * Ends every token of `subject` minted so far: bumps its epoch, then ends its open streams
245
- * here and, through `tenant/control`, on every other process. Running turns continue.
246
- */
247
- export async function revokeSubject(ctx, subject) {
248
- const epoch = await ctx.store.tx(async (t) => {
249
- const next = await t.bumpSubjectEpoch(subject, new Date().toISOString());
250
- t.afterCommit(async () => {
251
- endSubjectStreams(ctx.sessionStreams, subject, next);
252
- const streams = ctx.sessionStreams.wiring?.streams;
253
- if (streams)
254
- await signalSubjectRevoked(streams, currentBasin(ctx), subject, next).catch((error) => ctx.config.logger.warn("subject revocation signal failed", {
255
- message: error instanceof Error ? error.message : String(error),
256
- }));
257
- });
258
- return next;
259
- });
260
- ctx.config.logger.info("subject revoked", { epoch });
261
- return { subject, epoch };
262
102
  }
263
103
  /** True when the Tenant has a current and a standby signing key. */
264
104
  function complete(rows) {
@@ -57,7 +57,6 @@ export function actionRoutes(api) {
57
57
  tenantRoute(api, {
58
58
  credentials: ["application", "subject", "token"],
59
59
  scopes: ["sessions:own"],
60
- browser: true,
61
60
  }, {
62
61
  method: "post",
63
62
  path: "/v1/sessions/{sessionId}/commands",
@@ -0,0 +1,11 @@
1
+ import type { OpenAPIHono } from "@hono/zod-openapi";
2
+ import type { TenantEnv } from "../app.js";
3
+ /**
4
+ * One `bytes=` range of a file of `size` bytes: what to send, `"unsatisfiable"`, or undefined
5
+ * to send the whole file (no header, several ranges, or one the Runtime ignores).
6
+ */
7
+ export declare function parseRange(header: string | undefined, size: number): {
8
+ start: number;
9
+ end: number;
10
+ } | "unsatisfiable" | undefined;
11
+ export declare function artifactRoutes(api: OpenAPIHono<TenantEnv>): void;