@nylorun/runtime 0.25.0-beta → 0.27.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 (326) hide show
  1. package/CHANGELOG.md +169 -0
  2. package/README.md +26 -16
  3. package/dist/adapters/execution/restate.d.ts +15 -18
  4. package/dist/adapters/execution/restate.js +31 -27
  5. package/dist/adapters/replication/pgoutput.d.ts +1 -1
  6. package/dist/adapters/replication/pgoutput.js +3 -2
  7. package/dist/adapters/sandbox/local.js +8 -5
  8. package/dist/adapters/sandbox/virtual.js +2 -2
  9. package/dist/adapters/streams/s2.d.ts +1 -1
  10. package/dist/adapters/streams/s2.js +18 -14
  11. package/dist/api/a2a/card.js +1 -1
  12. package/dist/api/a2a/endpoint.js +3 -4
  13. package/dist/api/a2a/protocol.js +4 -0
  14. package/dist/api/a2a/routes.d.ts +2 -6
  15. package/dist/api/a2a/routes.js +12 -18
  16. package/dist/api/ag-ui/endpoint.js +2 -3
  17. package/dist/api/ag-ui/routes.js +4 -4
  18. package/dist/api/components.d.ts +326 -45
  19. package/dist/api/components.js +5 -1
  20. package/dist/api/gate/keys.js +7 -4
  21. package/dist/api/gate/routes.d.ts +6 -2
  22. package/dist/api/gate/routes.js +15 -11
  23. package/dist/api/http/app.d.ts +2 -2
  24. package/dist/api/http/app.js +2 -2
  25. package/dist/api/http/body.d.ts +15 -3
  26. package/dist/api/http/body.js +15 -7
  27. package/dist/api/http/define.d.ts +1 -1
  28. package/dist/api/http/respond.js +7 -3
  29. package/dist/api/http/routes/access.js +5 -4
  30. package/dist/api/http/routes/artifacts.js +19 -7
  31. package/dist/api/http/routes/coverage.js +1 -1
  32. package/dist/api/http/routes/environment-manifests.js +1 -1
  33. package/dist/api/http/routes/environments.js +6 -6
  34. package/dist/api/http/routes/files.d.ts +2 -1
  35. package/dist/api/http/routes/files.js +31 -5
  36. package/dist/api/http/routes/mcp.js +1 -1
  37. package/dist/api/http/routes/reads.d.ts +35 -0
  38. package/dist/api/http/routes/reads.js +50 -22
  39. package/dist/api/http/routes/sessions.js +12 -11
  40. package/dist/api/http/routes/tenant.d.ts +2 -2
  41. package/dist/api/http/routes/tenant.js +69 -16
  42. package/dist/api/inbound-files.d.ts +3 -9
  43. package/dist/api/inbound-files.js +18 -24
  44. package/dist/api/openapi.js +6 -2
  45. package/dist/artifacts/disk.d.ts +0 -4
  46. package/dist/artifacts/disk.js +77 -73
  47. package/dist/artifacts/files.d.ts +13 -4
  48. package/dist/artifacts/files.js +27 -9
  49. package/dist/artifacts/folder-upload.d.ts +75 -0
  50. package/dist/artifacts/folder-upload.js +263 -0
  51. package/dist/artifacts/folders.d.ts +14 -8
  52. package/dist/artifacts/folders.js +19 -11
  53. package/dist/artifacts/links.js +7 -6
  54. package/dist/artifacts/parts.d.ts +9 -14
  55. package/dist/artifacts/parts.js +11 -9
  56. package/dist/artifacts/pipe.d.ts +15 -0
  57. package/dist/artifacts/pipe.js +71 -0
  58. package/dist/artifacts/quota.d.ts +36 -0
  59. package/dist/artifacts/quota.js +44 -0
  60. package/dist/artifacts/service.d.ts +25 -1
  61. package/dist/artifacts/service.js +70 -25
  62. package/dist/blob/fs.js +2 -1
  63. package/dist/blob/s3.d.ts +6 -2
  64. package/dist/blob/s3.js +9 -7
  65. package/dist/blob/types.d.ts +1 -1
  66. package/dist/blob/types.js +1 -1
  67. package/dist/core/limits.d.ts +11 -35
  68. package/dist/core/limits.js +5 -73
  69. package/dist/core/sandbox-routes.js +0 -1
  70. package/dist/core/turn-manifest.d.ts +1 -2
  71. package/dist/core/turn-manifest.js +4 -28
  72. package/dist/execution/memory.d.ts +8 -5
  73. package/dist/execution/memory.js +8 -6
  74. package/dist/execution/types.d.ts +1 -6
  75. package/dist/execution/types.js +0 -5
  76. package/dist/gates/contract.d.ts +3 -2
  77. package/dist/gates/contract.js +1 -1
  78. package/dist/gates/egress-credentials.js +4 -3
  79. package/dist/gates/egress.d.ts +9 -9
  80. package/dist/gates/egress.js +19 -19
  81. package/dist/gates/fixture-model.js +13 -2
  82. package/dist/gates/handler.d.ts +1 -3
  83. package/dist/gates/handler.js +4 -3
  84. package/dist/gates/http-client.d.ts +4 -3
  85. package/dist/gates/http-client.js +5 -7
  86. package/dist/gates/http-tool.d.ts +24 -4
  87. package/dist/gates/http-tool.js +53 -17
  88. package/dist/gates/in-process.d.ts +2 -1
  89. package/dist/gates/in-process.js +17 -9
  90. package/dist/gates/inflight.d.ts +2 -2
  91. package/dist/gates/inflight.js +3 -2
  92. package/dist/gates/journal.js +5 -7
  93. package/dist/gates/mcp-handler.d.ts +4 -3
  94. package/dist/gates/mcp-handler.js +15 -5
  95. package/dist/gates/model-gate.d.ts +11 -2
  96. package/dist/gates/policy.d.ts +28 -5
  97. package/dist/gates/policy.js +60 -17
  98. package/dist/gates/provider-gate.d.ts +22 -0
  99. package/dist/gates/provider-gate.js +30 -0
  100. package/dist/gates/tool-calls.d.ts +1 -3
  101. package/dist/gates/tool-calls.js +2 -3
  102. package/dist/gates/tool-client.d.ts +1 -1
  103. package/dist/gates/tool-client.js +5 -6
  104. package/dist/gates/tool-contract.d.ts +8 -5
  105. package/dist/gates/tool-contract.js +1 -1
  106. package/dist/gates/tool-gate.d.ts +18 -7
  107. package/dist/gates/tool-gate.js +49 -7
  108. package/dist/harness/calls.d.ts +27 -25
  109. package/dist/harness/calls.js +40 -46
  110. package/dist/harness/executors.d.ts +10 -3
  111. package/dist/harness/executors.js +53 -23
  112. package/dist/harness/main.js +2 -2
  113. package/dist/harness/pod.d.ts +0 -2
  114. package/dist/harness/pod.js +7 -6
  115. package/dist/harness/run-tokens.d.ts +4 -1
  116. package/dist/harness/run-tokens.js +6 -2
  117. package/dist/harness/service.d.ts +17 -14
  118. package/dist/harness/service.js +21 -35
  119. package/dist/harness/setup.d.ts +0 -2
  120. package/dist/harness/setup.js +4 -9
  121. package/dist/harness/ws-client.d.ts +2 -2
  122. package/dist/harness/ws-client.js +7 -5
  123. package/dist/harness/ws-port.d.ts +3 -4
  124. package/dist/harness/ws-port.js +3 -4
  125. package/dist/harness-api/artifacts.d.ts +20 -0
  126. package/dist/harness-api/artifacts.js +478 -0
  127. package/dist/harness-api/in-process.d.ts +2 -2
  128. package/dist/harness-api/in-process.js +18 -16
  129. package/dist/harness-api/record.d.ts +10 -9
  130. package/dist/harness-api/record.js +102 -157
  131. package/dist/harness-api/renew.d.ts +1 -1
  132. package/dist/harness-api/renew.js +2 -2
  133. package/dist/harness-api/server.d.ts +1 -16
  134. package/dist/harness-api/server.js +82 -73
  135. package/dist/harness-api/start.d.ts +20 -2
  136. package/dist/harness-api/start.js +57 -18
  137. package/dist/harness-api/tool-journal.d.ts +15 -10
  138. package/dist/harness-api/tool-journal.js +26 -24
  139. package/dist/harness-api/workspace.d.ts +0 -4
  140. package/dist/harness-api/workspace.js +2 -45
  141. package/dist/harness-api/ws-server.js +10 -10
  142. package/dist/host/create-host.js +2 -3
  143. package/dist/host/execution.js +2 -3
  144. package/dist/host/gates.d.ts +2 -9
  145. package/dist/host/gates.js +15 -12
  146. package/dist/host/http.d.ts +0 -2
  147. package/dist/host/http.js +0 -27
  148. package/dist/host/main.js +10 -3
  149. package/dist/host/operate.js +12 -3
  150. package/dist/host/stack-config.d.ts +11 -0
  151. package/dist/host/stack-config.js +21 -1
  152. package/dist/index.d.ts +0 -1
  153. package/dist/index.js +0 -1
  154. package/dist/infra/index.js +2 -1
  155. package/dist/infra/readiness.d.ts +0 -2
  156. package/dist/infra/readiness.js +4 -3
  157. package/dist/keys/client.d.ts +1 -0
  158. package/dist/keys/client.js +2 -3
  159. package/dist/keys/contract.d.ts +1 -3
  160. package/dist/keys/contract.js +1 -3
  161. package/dist/keys/egress-ca.d.ts +0 -2
  162. package/dist/keys/egress-ca.js +2 -3
  163. package/dist/keys/keys.js +6 -1
  164. package/dist/keys/x509.d.ts +8 -4
  165. package/dist/keys/x509.js +14 -5
  166. package/dist/management-openapi.json +1961 -994
  167. package/dist/mcp/connect.d.ts +35 -26
  168. package/dist/mcp/connect.js +112 -141
  169. package/dist/mcp/pool.d.ts +27 -22
  170. package/dist/mcp/pool.js +34 -48
  171. package/dist/mcp/preview.d.ts +13 -6
  172. package/dist/mcp/preview.js +37 -20
  173. package/dist/mcp/snapshot.d.ts +35 -86
  174. package/dist/mcp/snapshot.js +93 -135
  175. package/dist/model/auth-store.js +5 -3
  176. package/dist/model/capabilities.d.ts +1 -1
  177. package/dist/model/catalog.d.ts +9 -36
  178. package/dist/model/catalog.js +6 -33
  179. package/dist/model/descriptor.d.ts +51 -0
  180. package/dist/model/descriptor.js +83 -0
  181. package/dist/model/models.d.ts +0 -3
  182. package/dist/model/models.js +3 -5
  183. package/dist/model/native-blocks.js +1 -1
  184. package/dist/model/pi-model.d.ts +16 -5
  185. package/dist/model/pi-model.js +86 -105
  186. package/dist/openapi.json +866 -1218
  187. package/dist/reads/cursor.js +3 -1
  188. package/dist/record/append.d.ts +34 -2
  189. package/dist/record/append.js +50 -1
  190. package/dist/record/environment.d.ts +2 -0
  191. package/dist/record/environment.js +2 -0
  192. package/dist/record/index.d.ts +1 -1
  193. package/dist/record/index.js +1 -1
  194. package/dist/redact.d.ts +1 -1
  195. package/dist/redact.js +3 -2
  196. package/dist/sandbox/egress-token.d.ts +3 -3
  197. package/dist/sandbox/egress-token.js +3 -3
  198. package/dist/sandbox/join.js +3 -2
  199. package/dist/sandbox/manager.d.ts +41 -41
  200. package/dist/sandbox/manager.js +112 -44
  201. package/dist/sandbox/placement.d.ts +1 -1
  202. package/dist/sandbox/placement.js +5 -8
  203. package/dist/sandbox/pods/client.d.ts +1 -10
  204. package/dist/sandbox/pods/client.js +8 -4
  205. package/dist/sandbox/pods/lifecycle.d.ts +19 -11
  206. package/dist/sandbox/pods/lifecycle.js +45 -23
  207. package/dist/sandbox/pods/network-gate.d.ts +4 -5
  208. package/dist/sandbox/pods/network-gate.js +7 -7
  209. package/dist/sandbox/pods/reconcile.js +4 -1
  210. package/dist/sandbox/pods/spec.js +8 -5
  211. package/dist/sandbox/policy.d.ts +7 -1
  212. package/dist/sandbox/policy.js +10 -3
  213. package/dist/sandbox/resolve.d.ts +8 -3
  214. package/dist/sandbox/resolve.js +12 -2
  215. package/dist/sandbox/setup.d.ts +3 -1
  216. package/dist/sandbox/setup.js +34 -11
  217. package/dist/sandbox/share.d.ts +5 -14
  218. package/dist/sandbox/share.js +5 -34
  219. package/dist/sandbox/skills.d.ts +7 -13
  220. package/dist/sandbox/skills.js +16 -31
  221. package/dist/sandbox/tenant-config.d.ts +2 -2
  222. package/dist/sandbox/tenant-config.js +4 -3
  223. package/dist/sandbox/tools.d.ts +7 -1
  224. package/dist/sandbox/tools.js +26 -26
  225. package/dist/sandbox/types.d.ts +10 -3
  226. package/dist/sandbox/types.js +9 -0
  227. package/dist/store/postgres/connect.d.ts +6 -5
  228. package/dist/store/postgres/connect.js +14 -11
  229. package/dist/store/postgres/control.js +13 -13
  230. package/dist/store/postgres/drizzle/0028_artifact_write_keys.sql +2 -0
  231. package/dist/store/postgres/drizzle/0029_protocol_15.sql +11 -0
  232. package/dist/store/postgres/drizzle/0030_protocol_15_runtime_block.sql +11 -0
  233. package/dist/store/postgres/drizzle/0031_protocol_15_mcp_snapshot.sql +8 -0
  234. package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
  235. package/dist/store/postgres/migrate.js +1 -1
  236. package/dist/store/postgres/reads.js +10 -2
  237. package/dist/store/postgres/schema.d.ts +19 -0
  238. package/dist/store/postgres/schema.js +7 -0
  239. package/dist/store/postgres/store.js +55 -26
  240. package/dist/store/types.d.ts +17 -7
  241. package/dist/streams/relay/core.d.ts +3 -3
  242. package/dist/streams/relay/core.js +9 -10
  243. package/dist/tenant/advance.js +21 -31
  244. package/dist/tenant/commands.js +9 -16
  245. package/dist/tenant/context.d.ts +14 -17
  246. package/dist/tenant/definition-files.d.ts +25 -4
  247. package/dist/tenant/definition-files.js +85 -47
  248. package/dist/tenant/effects.js +9 -36
  249. package/dist/tenant/environment-manifests.js +9 -1
  250. package/dist/tenant/environments.d.ts +0 -2
  251. package/dist/tenant/environments.js +54 -30
  252. package/dist/tenant/ephemeral.d.ts +1 -1
  253. package/dist/tenant/ephemeral.js +2 -1
  254. package/dist/tenant/history.d.ts +1 -1
  255. package/dist/tenant/history.js +1 -1
  256. package/dist/tenant/host-token.d.ts +3 -3
  257. package/dist/tenant/host-token.js +12 -11
  258. package/dist/tenant/http.d.ts +5 -8
  259. package/dist/tenant/http.js +9 -0
  260. package/dist/tenant/identity-file.d.ts +24 -1
  261. package/dist/tenant/identity-file.js +35 -7
  262. package/dist/tenant/issuers.d.ts +5 -5
  263. package/dist/tenant/issuers.js +31 -23
  264. package/dist/tenant/jwt.d.ts +8 -2
  265. package/dist/tenant/jwt.js +10 -2
  266. package/dist/tenant/limits.d.ts +90 -0
  267. package/dist/tenant/limits.js +175 -0
  268. package/dist/tenant/module.d.ts +4 -1
  269. package/dist/tenant/module.js +9 -8
  270. package/dist/tenant/outbound.d.ts +17 -19
  271. package/dist/tenant/outbound.js +18 -21
  272. package/dist/tenant/run-grants.js +3 -2
  273. package/dist/tenant/run-token.d.ts +0 -4
  274. package/dist/tenant/run-token.js +6 -11
  275. package/dist/tenant/runtime-limits.d.ts +24 -0
  276. package/dist/tenant/runtime-limits.js +27 -0
  277. package/dist/tenant/runtime.js +30 -43
  278. package/dist/tenant/session-streams.js +7 -6
  279. package/dist/tenant/session.d.ts +1 -1
  280. package/dist/tenant/session.js +1 -1
  281. package/dist/tenant/sessions.js +32 -29
  282. package/dist/tenant/signing-keys.d.ts +1 -1
  283. package/dist/tenant/signing-keys.js +5 -6
  284. package/dist/tenant/status.js +4 -3
  285. package/dist/tenant/streams.js +18 -20
  286. package/dist/tenant/sweep.d.ts +1 -21
  287. package/dist/tenant/sweep.js +39 -48
  288. package/dist/tenant/transcript.d.ts +70 -23
  289. package/dist/tenant/transcript.js +28 -22
  290. package/dist/tenant/types.d.ts +11 -16
  291. package/dist/tenant/worker.d.ts +2 -10
  292. package/dist/tenant/worker.js +5 -14
  293. package/dist/traces/ids.js +5 -1
  294. package/dist/traces/map.d.ts +9 -6
  295. package/dist/traces/map.js +9 -11
  296. package/dist/traces/otlp.d.ts +3 -3
  297. package/dist/traces/otlp.js +5 -3
  298. package/dist/traces/projector.d.ts +9 -4
  299. package/dist/traces/projector.js +13 -7
  300. package/dist/traces/read.js +6 -1
  301. package/dist/tuning.d.ts +383 -0
  302. package/dist/tuning.js +658 -0
  303. package/dist/vault/headers.js +4 -2
  304. package/dist/version.d.ts +1 -1
  305. package/dist/version.js +1 -1
  306. package/package.json +3 -3
  307. package/dist/artifacts/export.d.ts +0 -8
  308. package/dist/artifacts/export.js +0 -204
  309. package/dist/artifacts/media-types.d.ts +0 -30
  310. package/dist/artifacts/media-types.js +0 -137
  311. package/dist/artifacts/workspace.d.ts +0 -60
  312. package/dist/artifacts/workspace.js +0 -45
  313. package/dist/media.d.ts +0 -10
  314. package/dist/media.js +0 -58
  315. package/dist/sandbox/runtime-tools.d.ts +0 -9
  316. package/dist/sandbox/runtime-tools.js +0 -16
  317. package/dist/sandbox/session-sandbox.d.ts +0 -16
  318. package/dist/sandbox/session-sandbox.js +0 -77
  319. package/dist/tenant/artifact-tool.d.ts +0 -13
  320. package/dist/tenant/artifact-tool.js +0 -243
  321. package/dist/tenant/skill-tool.d.ts +0 -20
  322. package/dist/tenant/skill-tool.js +0 -67
  323. package/dist/tenant/tool-results.d.ts +0 -57
  324. package/dist/tenant/tool-results.js +0 -298
  325. package/dist/tenant/tool-search.d.ts +0 -39
  326. package/dist/tenant/tool-search.js +0 -103
@@ -4,12 +4,10 @@
4
4
  * gates token. Internal: only core calls it, so it is not in the published OpenAPI documents.
5
5
  *
6
6
  * `200 {result}` when the operation succeeded, `200 {error}` when it refused: a vault error or
7
- * a Tenant API error with its status, code and details, so the route that called it answers
7
+ * a Runtime or Management API error with its status, code and details, so the route that called it answers
8
8
  * exactly what it answered when the operation ran in its own process.
9
9
  */
10
10
  export declare const KEYS_PATH = "/nylorun/v1/keys";
11
- /** Largest request body: a credential with its secret, or a token's claims. */
12
- export declare const MAX_KEYS_BODY_BYTES: number;
13
11
  export interface KeysError {
14
12
  readonly kind: "vault" | "http";
15
13
  readonly status: number;
@@ -4,9 +4,7 @@
4
4
  * gates token. Internal: only core calls it, so it is not in the published OpenAPI documents.
5
5
  *
6
6
  * `200 {result}` when the operation succeeded, `200 {error}` when it refused: a vault error or
7
- * a Tenant API error with its status, code and details, so the route that called it answers
7
+ * a Runtime or Management API error with its status, code and details, so the route that called it answers
8
8
  * exactly what it answered when the operation ran in its own process.
9
9
  */
10
10
  export const KEYS_PATH = "/nylorun/v1/keys";
11
- /** Largest request body: a credential with its secret, or a token's claims. */
12
- export const MAX_KEYS_BODY_BYTES = 1024 * 1024;
@@ -1,6 +1,4 @@
1
1
  import type { SessionStore } from "../store/types.js";
2
- /** How long a leaf egress-gate presents is valid: one connection rarely lasts this long. */
3
- export declare const EGRESS_LEAF_MINUTES = 60;
4
2
  export declare class EgressAuthority {
5
3
  private readonly store;
6
4
  private readonly kek;
@@ -10,8 +10,6 @@ import { X509Certificate } from "node:crypto";
10
10
  import { decryptSecret, encryptSecret } from "../vault/crypto.js";
11
11
  import { createCertificateAuthority, issueLeafCertificate } from "./x509.js";
12
12
  const SETTING = "egress.ca";
13
- /** How long a leaf egress-gate presents is valid: one connection rarely lasts this long. */
14
- export const EGRESS_LEAF_MINUTES = 60;
15
13
  function aad(certificate) {
16
14
  return Buffer.from(`nylorun.egress-ca:${new X509Certificate(certificate).fingerprint256}`);
17
15
  }
@@ -30,7 +28,8 @@ export class EgressAuthority {
30
28
  }
31
29
  /** A leaf for `host` and the caller's P-256 public key (SPKI PEM); the caller keeps its key. */
32
30
  async signLeaf(host, publicKey) {
33
- return issueLeafCertificate({ authority: await this.load(), host, publicKey, minutes: EGRESS_LEAF_MINUTES });
31
+ // Valid for `keys.leafLifetimeMs` (Host tuning): one connection rarely lasts this long.
32
+ return issueLeafCertificate({ authority: await this.load(), host, publicKey });
34
33
  }
35
34
  async load() {
36
35
  if (this.authority)
package/dist/keys/keys.js CHANGED
@@ -16,6 +16,7 @@
16
16
  import { EgressAuthority } from "./egress-ca.js";
17
17
  import { SignJWT } from "jose";
18
18
  import { previewMcpServer } from "../mcp/preview.js";
19
+ import { readRuntimeLimits } from "../tenant/runtime-limits.js";
19
20
  import { signingKeyView } from "../tenant/signing-keys.js";
20
21
  /** The operations, by the name the HTTP route carries. */
21
22
  export const KEYS_OPERATIONS = [
@@ -56,7 +57,11 @@ export function inProcessKeys(options) {
56
57
  const key = kek();
57
58
  await store.tx((t) => signingKeys.ensure(t, key));
58
59
  },
59
- previewMcp: (body) => previewMcpServer(body, { vault, policy: options.policy ?? {} }),
60
+ previewMcp: async (body) => previewMcpServer(body, {
61
+ vault,
62
+ policy: options.policy ?? {},
63
+ limits: await store.tx((t) => readRuntimeLimits(t)),
64
+ }),
60
65
  egressCa: () => egress.certificate(),
61
66
  signEgressLeaf: (host, publicKey) => egress.signLeaf(host, publicKey),
62
67
  };
@@ -4,22 +4,26 @@ export interface CertificateAuthority {
4
4
  /** PKCS#8 PEM of the CA key: sealed in the vault, used only by keys. */
5
5
  readonly privateKey: string;
6
6
  }
7
- /** A new P-256 CA, valid from an hour ago for `days` days. */
7
+ /**
8
+ * A new P-256 CA, valid from `keys.caBackdateMs` ago (Host tuning, an hour) for `days` days
9
+ * (default `keys.caLifetimeDays`).
10
+ */
8
11
  export declare function createCertificateAuthority(options: {
9
12
  readonly commonName: string;
10
13
  readonly days?: number;
11
14
  readonly now?: Date;
12
15
  }): CertificateAuthority;
13
16
  /**
14
- * A leaf for `host` and the caller's `publicKey` (SPKI PEM), signed by the CA, valid from five
15
- * minutes ago for `minutes` minutes. The caller keeps the leaf's private key: only the
17
+ * A leaf for `host` and the caller's `publicKey` (SPKI PEM), signed by the CA, valid from
18
+ * `keys.leafBackdateMs` ago (Host tuning, five minutes) for `lifetimeMs` (default
19
+ * `keys.leafLifetimeMs`, an hour: one connection rarely lasts this long). The caller keeps the leaf's private key: only the
16
20
  * certificate comes back, so no private key leaves whoever holds it.
17
21
  */
18
22
  export declare function issueLeafCertificate(options: {
19
23
  readonly authority: CertificateAuthority;
20
24
  readonly host: string;
21
25
  readonly publicKey: string;
22
- readonly minutes?: number;
26
+ readonly lifetimeMs?: number;
23
27
  readonly now?: Date;
24
28
  }): string;
25
29
  /** A P-256 key pair for a leaf, as PEM: SPKI for the public key, PKCS#8 for the private key. */
package/dist/keys/x509.js CHANGED
@@ -10,6 +10,7 @@
10
10
  * CA's key identifier. Go (`gh`), OpenSSL (`curl`, `git`), Node and Python accept that shape.
11
11
  */
12
12
  import { isIP } from "node:net";
13
+ import { hostTuning } from "../tuning.js";
13
14
  import { createHash, createPrivateKey, createPublicKey, generateKeyPairSync, randomBytes, sign, X509Certificate, } from "node:crypto";
14
15
  const OID = {
15
16
  ecdsaWithSha256: "1.2.840.10045.4.3.2",
@@ -96,21 +97,28 @@ function pem(der) {
96
97
  const body = der.toString("base64").replace(/(.{64})/g, "$1\n").replace(/\n$/, "");
97
98
  return `-----BEGIN CERTIFICATE-----\n${body}\n-----END CERTIFICATE-----\n`;
98
99
  }
99
- /** A new P-256 CA, valid from an hour ago for `days` days. */
100
+ /** Milliseconds in a day: a unit, not a setting. */
101
+ const DAY_MS = 86_400_000;
102
+ /**
103
+ * A new P-256 CA, valid from `keys.caBackdateMs` ago (Host tuning, an hour) for `days` days
104
+ * (default `keys.caLifetimeDays`).
105
+ */
100
106
  export function createCertificateAuthority(options) {
101
107
  const { publicKey, privateKey } = generateKeyPairSync("ec", { namedCurve: "P-256" });
102
108
  const now = options.now ?? new Date();
109
+ const tuning = hostTuning().keys;
103
110
  const subject = name({ commonName: options.commonName, organization: "Nylorun" });
104
111
  const ski = keyIdentifier(publicKey);
105
- const tbs = seq(explicit(0, integer(Buffer.from([2]))), serial(), seq(oid(OID.ecdsaWithSha256)), subject, seq(time(new Date(now.getTime() - 3_600_000)), time(new Date(now.getTime() + (options.days ?? 3650) * 86_400_000))), subject, spki(publicKey), explicit(3, seq(extension(OID.basicConstraints, true, seq(bool(true), integer(Buffer.from([0])))), extension(OID.keyUsage, true, bits(Buffer.from([0x06]), 1)), extension(OID.subjectKeyIdentifier, false, octets(ski)))));
112
+ const tbs = seq(explicit(0, integer(Buffer.from([2]))), serial(), seq(oid(OID.ecdsaWithSha256)), subject, seq(time(new Date(now.getTime() - tuning.caBackdateMs)), time(new Date(now.getTime() + (options.days ?? tuning.caLifetimeDays) * DAY_MS))), subject, spki(publicKey), explicit(3, seq(extension(OID.basicConstraints, true, seq(bool(true), integer(Buffer.from([0])))), extension(OID.keyUsage, true, bits(Buffer.from([0x06]), 1)), extension(OID.subjectKeyIdentifier, false, octets(ski)))));
106
113
  return {
107
114
  certificate: pem(certificate(tbs, privateKey)),
108
115
  privateKey: privateKey.export({ type: "pkcs8", format: "pem" }).toString(),
109
116
  };
110
117
  }
111
118
  /**
112
- * A leaf for `host` and the caller's `publicKey` (SPKI PEM), signed by the CA, valid from five
113
- * minutes ago for `minutes` minutes. The caller keeps the leaf's private key: only the
119
+ * A leaf for `host` and the caller's `publicKey` (SPKI PEM), signed by the CA, valid from
120
+ * `keys.leafBackdateMs` ago (Host tuning, five minutes) for `lifetimeMs` (default
121
+ * `keys.leafLifetimeMs`, an hour: one connection rarely lasts this long). The caller keeps the leaf's private key: only the
114
122
  * certificate comes back, so no private key leaves whoever holds it.
115
123
  */
116
124
  export function issueLeafCertificate(options) {
@@ -122,8 +130,9 @@ export function issueLeafCertificate(options) {
122
130
  if (publicKey.asymmetricKeyType !== "ec" || publicKey.asymmetricKeyDetails?.namedCurve !== "prime256v1")
123
131
  throw new Error("A leaf key must be ECDSA P-256");
124
132
  const now = options.now ?? new Date();
133
+ const tuning = hostTuning().keys;
125
134
  const issuer = Buffer.from(ca.raw);
126
- const tbs = seq(explicit(0, integer(Buffer.from([2]))), serial(), seq(oid(OID.ecdsaWithSha256)), subjectOf(issuer), seq(time(new Date(now.getTime() - 300_000)), time(new Date(now.getTime() + (options.minutes ?? 60) * 60_000))), name({ commonName: options.host }), spki(publicKey), explicit(3, seq(extension(OID.keyUsage, true, bits(Buffer.from([0x80]), 7)), extension(OID.extKeyUsage, false, seq(oid(OID.serverAuth))), extension(OID.subjectAltName, false, seq(tlv(0x82, Buffer.from(options.host, "ascii")))), extension(OID.authorityKeyIdentifier, false, seq(tlv(0x80, keyIdentifier(ca.publicKey)))))));
135
+ const tbs = seq(explicit(0, integer(Buffer.from([2]))), serial(), seq(oid(OID.ecdsaWithSha256)), subjectOf(issuer), seq(time(new Date(now.getTime() - tuning.leafBackdateMs)), time(new Date(now.getTime() + (options.lifetimeMs ?? tuning.leafLifetimeMs)))), name({ commonName: options.host }), spki(publicKey), explicit(3, seq(extension(OID.keyUsage, true, bits(Buffer.from([0x80]), 7)), extension(OID.extKeyUsage, false, seq(oid(OID.serverAuth))), extension(OID.subjectAltName, false, seq(tlv(0x82, Buffer.from(options.host, "ascii")))), extension(OID.authorityKeyIdentifier, false, seq(tlv(0x80, keyIdentifier(ca.publicKey)))))));
127
136
  return pem(certificate(tbs, caKey));
128
137
  }
129
138
  /** A P-256 key pair for a leaf, as PEM: SPKI for the public key, PKCS#8 for the private key. */