@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.
- package/CHANGELOG.md +169 -0
- package/README.md +26 -16
- package/dist/adapters/execution/restate.d.ts +15 -18
- package/dist/adapters/execution/restate.js +31 -27
- package/dist/adapters/replication/pgoutput.d.ts +1 -1
- package/dist/adapters/replication/pgoutput.js +3 -2
- package/dist/adapters/sandbox/local.js +8 -5
- package/dist/adapters/sandbox/virtual.js +2 -2
- package/dist/adapters/streams/s2.d.ts +1 -1
- package/dist/adapters/streams/s2.js +18 -14
- package/dist/api/a2a/card.js +1 -1
- package/dist/api/a2a/endpoint.js +3 -4
- package/dist/api/a2a/protocol.js +4 -0
- package/dist/api/a2a/routes.d.ts +2 -6
- package/dist/api/a2a/routes.js +12 -18
- package/dist/api/ag-ui/endpoint.js +2 -3
- package/dist/api/ag-ui/routes.js +4 -4
- package/dist/api/components.d.ts +326 -45
- package/dist/api/components.js +5 -1
- package/dist/api/gate/keys.js +7 -4
- package/dist/api/gate/routes.d.ts +6 -2
- package/dist/api/gate/routes.js +15 -11
- package/dist/api/http/app.d.ts +2 -2
- package/dist/api/http/app.js +2 -2
- package/dist/api/http/body.d.ts +15 -3
- package/dist/api/http/body.js +15 -7
- package/dist/api/http/define.d.ts +1 -1
- package/dist/api/http/respond.js +7 -3
- package/dist/api/http/routes/access.js +5 -4
- package/dist/api/http/routes/artifacts.js +19 -7
- package/dist/api/http/routes/coverage.js +1 -1
- package/dist/api/http/routes/environment-manifests.js +1 -1
- package/dist/api/http/routes/environments.js +6 -6
- package/dist/api/http/routes/files.d.ts +2 -1
- package/dist/api/http/routes/files.js +31 -5
- package/dist/api/http/routes/mcp.js +1 -1
- package/dist/api/http/routes/reads.d.ts +35 -0
- package/dist/api/http/routes/reads.js +50 -22
- package/dist/api/http/routes/sessions.js +12 -11
- package/dist/api/http/routes/tenant.d.ts +2 -2
- package/dist/api/http/routes/tenant.js +69 -16
- package/dist/api/inbound-files.d.ts +3 -9
- package/dist/api/inbound-files.js +18 -24
- package/dist/api/openapi.js +6 -2
- package/dist/artifacts/disk.d.ts +0 -4
- package/dist/artifacts/disk.js +77 -73
- package/dist/artifacts/files.d.ts +13 -4
- package/dist/artifacts/files.js +27 -9
- package/dist/artifacts/folder-upload.d.ts +75 -0
- package/dist/artifacts/folder-upload.js +263 -0
- package/dist/artifacts/folders.d.ts +14 -8
- package/dist/artifacts/folders.js +19 -11
- package/dist/artifacts/links.js +7 -6
- package/dist/artifacts/parts.d.ts +9 -14
- package/dist/artifacts/parts.js +11 -9
- package/dist/artifacts/pipe.d.ts +15 -0
- package/dist/artifacts/pipe.js +71 -0
- package/dist/artifacts/quota.d.ts +36 -0
- package/dist/artifacts/quota.js +44 -0
- package/dist/artifacts/service.d.ts +25 -1
- package/dist/artifacts/service.js +70 -25
- package/dist/blob/fs.js +2 -1
- package/dist/blob/s3.d.ts +6 -2
- package/dist/blob/s3.js +9 -7
- package/dist/blob/types.d.ts +1 -1
- package/dist/blob/types.js +1 -1
- package/dist/core/limits.d.ts +11 -35
- package/dist/core/limits.js +5 -73
- package/dist/core/sandbox-routes.js +0 -1
- package/dist/core/turn-manifest.d.ts +1 -2
- package/dist/core/turn-manifest.js +4 -28
- package/dist/execution/memory.d.ts +8 -5
- package/dist/execution/memory.js +8 -6
- package/dist/execution/types.d.ts +1 -6
- package/dist/execution/types.js +0 -5
- package/dist/gates/contract.d.ts +3 -2
- package/dist/gates/contract.js +1 -1
- package/dist/gates/egress-credentials.js +4 -3
- package/dist/gates/egress.d.ts +9 -9
- package/dist/gates/egress.js +19 -19
- package/dist/gates/fixture-model.js +13 -2
- package/dist/gates/handler.d.ts +1 -3
- package/dist/gates/handler.js +4 -3
- package/dist/gates/http-client.d.ts +4 -3
- package/dist/gates/http-client.js +5 -7
- package/dist/gates/http-tool.d.ts +24 -4
- package/dist/gates/http-tool.js +53 -17
- package/dist/gates/in-process.d.ts +2 -1
- package/dist/gates/in-process.js +17 -9
- package/dist/gates/inflight.d.ts +2 -2
- package/dist/gates/inflight.js +3 -2
- package/dist/gates/journal.js +5 -7
- package/dist/gates/mcp-handler.d.ts +4 -3
- package/dist/gates/mcp-handler.js +15 -5
- package/dist/gates/model-gate.d.ts +11 -2
- package/dist/gates/policy.d.ts +28 -5
- package/dist/gates/policy.js +60 -17
- package/dist/gates/provider-gate.d.ts +22 -0
- package/dist/gates/provider-gate.js +30 -0
- package/dist/gates/tool-calls.d.ts +1 -3
- package/dist/gates/tool-calls.js +2 -3
- package/dist/gates/tool-client.d.ts +1 -1
- package/dist/gates/tool-client.js +5 -6
- package/dist/gates/tool-contract.d.ts +8 -5
- package/dist/gates/tool-contract.js +1 -1
- package/dist/gates/tool-gate.d.ts +18 -7
- package/dist/gates/tool-gate.js +49 -7
- package/dist/harness/calls.d.ts +27 -25
- package/dist/harness/calls.js +40 -46
- package/dist/harness/executors.d.ts +10 -3
- package/dist/harness/executors.js +53 -23
- package/dist/harness/main.js +2 -2
- package/dist/harness/pod.d.ts +0 -2
- package/dist/harness/pod.js +7 -6
- package/dist/harness/run-tokens.d.ts +4 -1
- package/dist/harness/run-tokens.js +6 -2
- package/dist/harness/service.d.ts +17 -14
- package/dist/harness/service.js +21 -35
- package/dist/harness/setup.d.ts +0 -2
- package/dist/harness/setup.js +4 -9
- package/dist/harness/ws-client.d.ts +2 -2
- package/dist/harness/ws-client.js +7 -5
- package/dist/harness/ws-port.d.ts +3 -4
- package/dist/harness/ws-port.js +3 -4
- package/dist/harness-api/artifacts.d.ts +20 -0
- package/dist/harness-api/artifacts.js +478 -0
- package/dist/harness-api/in-process.d.ts +2 -2
- package/dist/harness-api/in-process.js +18 -16
- package/dist/harness-api/record.d.ts +10 -9
- package/dist/harness-api/record.js +102 -157
- package/dist/harness-api/renew.d.ts +1 -1
- package/dist/harness-api/renew.js +2 -2
- package/dist/harness-api/server.d.ts +1 -16
- package/dist/harness-api/server.js +82 -73
- package/dist/harness-api/start.d.ts +20 -2
- package/dist/harness-api/start.js +57 -18
- package/dist/harness-api/tool-journal.d.ts +15 -10
- package/dist/harness-api/tool-journal.js +26 -24
- package/dist/harness-api/workspace.d.ts +0 -4
- package/dist/harness-api/workspace.js +2 -45
- package/dist/harness-api/ws-server.js +10 -10
- package/dist/host/create-host.js +2 -3
- package/dist/host/execution.js +2 -3
- package/dist/host/gates.d.ts +2 -9
- package/dist/host/gates.js +15 -12
- package/dist/host/http.d.ts +0 -2
- package/dist/host/http.js +0 -27
- package/dist/host/main.js +10 -3
- package/dist/host/operate.js +12 -3
- package/dist/host/stack-config.d.ts +11 -0
- package/dist/host/stack-config.js +21 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/infra/index.js +2 -1
- package/dist/infra/readiness.d.ts +0 -2
- package/dist/infra/readiness.js +4 -3
- package/dist/keys/client.d.ts +1 -0
- package/dist/keys/client.js +2 -3
- package/dist/keys/contract.d.ts +1 -3
- package/dist/keys/contract.js +1 -3
- package/dist/keys/egress-ca.d.ts +0 -2
- package/dist/keys/egress-ca.js +2 -3
- package/dist/keys/keys.js +6 -1
- package/dist/keys/x509.d.ts +8 -4
- package/dist/keys/x509.js +14 -5
- package/dist/management-openapi.json +1961 -994
- package/dist/mcp/connect.d.ts +35 -26
- package/dist/mcp/connect.js +112 -141
- package/dist/mcp/pool.d.ts +27 -22
- package/dist/mcp/pool.js +34 -48
- package/dist/mcp/preview.d.ts +13 -6
- package/dist/mcp/preview.js +37 -20
- package/dist/mcp/snapshot.d.ts +35 -86
- package/dist/mcp/snapshot.js +93 -135
- package/dist/model/auth-store.js +5 -3
- package/dist/model/capabilities.d.ts +1 -1
- package/dist/model/catalog.d.ts +9 -36
- package/dist/model/catalog.js +6 -33
- package/dist/model/descriptor.d.ts +51 -0
- package/dist/model/descriptor.js +83 -0
- package/dist/model/models.d.ts +0 -3
- package/dist/model/models.js +3 -5
- package/dist/model/native-blocks.js +1 -1
- package/dist/model/pi-model.d.ts +16 -5
- package/dist/model/pi-model.js +86 -105
- package/dist/openapi.json +866 -1218
- package/dist/reads/cursor.js +3 -1
- package/dist/record/append.d.ts +34 -2
- package/dist/record/append.js +50 -1
- package/dist/record/environment.d.ts +2 -0
- package/dist/record/environment.js +2 -0
- package/dist/record/index.d.ts +1 -1
- package/dist/record/index.js +1 -1
- package/dist/redact.d.ts +1 -1
- package/dist/redact.js +3 -2
- package/dist/sandbox/egress-token.d.ts +3 -3
- package/dist/sandbox/egress-token.js +3 -3
- package/dist/sandbox/join.js +3 -2
- package/dist/sandbox/manager.d.ts +41 -41
- package/dist/sandbox/manager.js +112 -44
- package/dist/sandbox/placement.d.ts +1 -1
- package/dist/sandbox/placement.js +5 -8
- package/dist/sandbox/pods/client.d.ts +1 -10
- package/dist/sandbox/pods/client.js +8 -4
- package/dist/sandbox/pods/lifecycle.d.ts +19 -11
- package/dist/sandbox/pods/lifecycle.js +45 -23
- package/dist/sandbox/pods/network-gate.d.ts +4 -5
- package/dist/sandbox/pods/network-gate.js +7 -7
- package/dist/sandbox/pods/reconcile.js +4 -1
- package/dist/sandbox/pods/spec.js +8 -5
- package/dist/sandbox/policy.d.ts +7 -1
- package/dist/sandbox/policy.js +10 -3
- package/dist/sandbox/resolve.d.ts +8 -3
- package/dist/sandbox/resolve.js +12 -2
- package/dist/sandbox/setup.d.ts +3 -1
- package/dist/sandbox/setup.js +34 -11
- package/dist/sandbox/share.d.ts +5 -14
- package/dist/sandbox/share.js +5 -34
- package/dist/sandbox/skills.d.ts +7 -13
- package/dist/sandbox/skills.js +16 -31
- package/dist/sandbox/tenant-config.d.ts +2 -2
- package/dist/sandbox/tenant-config.js +4 -3
- package/dist/sandbox/tools.d.ts +7 -1
- package/dist/sandbox/tools.js +26 -26
- package/dist/sandbox/types.d.ts +10 -3
- package/dist/sandbox/types.js +9 -0
- package/dist/store/postgres/connect.d.ts +6 -5
- package/dist/store/postgres/connect.js +14 -11
- package/dist/store/postgres/control.js +13 -13
- package/dist/store/postgres/drizzle/0028_artifact_write_keys.sql +2 -0
- package/dist/store/postgres/drizzle/0029_protocol_15.sql +11 -0
- package/dist/store/postgres/drizzle/0030_protocol_15_runtime_block.sql +11 -0
- package/dist/store/postgres/drizzle/0031_protocol_15_mcp_snapshot.sql +8 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
- package/dist/store/postgres/migrate.js +1 -1
- package/dist/store/postgres/reads.js +10 -2
- package/dist/store/postgres/schema.d.ts +19 -0
- package/dist/store/postgres/schema.js +7 -0
- package/dist/store/postgres/store.js +55 -26
- package/dist/store/types.d.ts +17 -7
- package/dist/streams/relay/core.d.ts +3 -3
- package/dist/streams/relay/core.js +9 -10
- package/dist/tenant/advance.js +21 -31
- package/dist/tenant/commands.js +9 -16
- package/dist/tenant/context.d.ts +14 -17
- package/dist/tenant/definition-files.d.ts +25 -4
- package/dist/tenant/definition-files.js +85 -47
- package/dist/tenant/effects.js +9 -36
- package/dist/tenant/environment-manifests.js +9 -1
- package/dist/tenant/environments.d.ts +0 -2
- package/dist/tenant/environments.js +54 -30
- package/dist/tenant/ephemeral.d.ts +1 -1
- package/dist/tenant/ephemeral.js +2 -1
- package/dist/tenant/history.d.ts +1 -1
- package/dist/tenant/history.js +1 -1
- package/dist/tenant/host-token.d.ts +3 -3
- package/dist/tenant/host-token.js +12 -11
- package/dist/tenant/http.d.ts +5 -8
- package/dist/tenant/http.js +9 -0
- package/dist/tenant/identity-file.d.ts +24 -1
- package/dist/tenant/identity-file.js +35 -7
- package/dist/tenant/issuers.d.ts +5 -5
- package/dist/tenant/issuers.js +31 -23
- package/dist/tenant/jwt.d.ts +8 -2
- package/dist/tenant/jwt.js +10 -2
- package/dist/tenant/limits.d.ts +90 -0
- package/dist/tenant/limits.js +175 -0
- package/dist/tenant/module.d.ts +4 -1
- package/dist/tenant/module.js +9 -8
- package/dist/tenant/outbound.d.ts +17 -19
- package/dist/tenant/outbound.js +18 -21
- package/dist/tenant/run-grants.js +3 -2
- package/dist/tenant/run-token.d.ts +0 -4
- package/dist/tenant/run-token.js +6 -11
- package/dist/tenant/runtime-limits.d.ts +24 -0
- package/dist/tenant/runtime-limits.js +27 -0
- package/dist/tenant/runtime.js +30 -43
- package/dist/tenant/session-streams.js +7 -6
- package/dist/tenant/session.d.ts +1 -1
- package/dist/tenant/session.js +1 -1
- package/dist/tenant/sessions.js +32 -29
- package/dist/tenant/signing-keys.d.ts +1 -1
- package/dist/tenant/signing-keys.js +5 -6
- package/dist/tenant/status.js +4 -3
- package/dist/tenant/streams.js +18 -20
- package/dist/tenant/sweep.d.ts +1 -21
- package/dist/tenant/sweep.js +39 -48
- package/dist/tenant/transcript.d.ts +70 -23
- package/dist/tenant/transcript.js +28 -22
- package/dist/tenant/types.d.ts +11 -16
- package/dist/tenant/worker.d.ts +2 -10
- package/dist/tenant/worker.js +5 -14
- package/dist/traces/ids.js +5 -1
- package/dist/traces/map.d.ts +9 -6
- package/dist/traces/map.js +9 -11
- package/dist/traces/otlp.d.ts +3 -3
- package/dist/traces/otlp.js +5 -3
- package/dist/traces/projector.d.ts +9 -4
- package/dist/traces/projector.js +13 -7
- package/dist/traces/read.js +6 -1
- package/dist/tuning.d.ts +383 -0
- package/dist/tuning.js +658 -0
- package/dist/vault/headers.js +4 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/dist/artifacts/export.d.ts +0 -8
- package/dist/artifacts/export.js +0 -204
- package/dist/artifacts/media-types.d.ts +0 -30
- package/dist/artifacts/media-types.js +0 -137
- package/dist/artifacts/workspace.d.ts +0 -60
- package/dist/artifacts/workspace.js +0 -45
- package/dist/media.d.ts +0 -10
- package/dist/media.js +0 -58
- package/dist/sandbox/runtime-tools.d.ts +0 -9
- package/dist/sandbox/runtime-tools.js +0 -16
- package/dist/sandbox/session-sandbox.d.ts +0 -16
- package/dist/sandbox/session-sandbox.js +0 -77
- package/dist/tenant/artifact-tool.d.ts +0 -13
- package/dist/tenant/artifact-tool.js +0 -243
- package/dist/tenant/skill-tool.d.ts +0 -20
- package/dist/tenant/skill-tool.js +0 -67
- package/dist/tenant/tool-results.d.ts +0 -57
- package/dist/tenant/tool-results.js +0 -298
- package/dist/tenant/tool-search.d.ts +0 -39
- package/dist/tenant/tool-search.js +0 -103
package/dist/keys/contract.d.ts
CHANGED
|
@@ -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
|
|
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;
|
package/dist/keys/contract.js
CHANGED
|
@@ -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
|
|
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;
|
package/dist/keys/egress-ca.d.ts
CHANGED
|
@@ -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;
|
package/dist/keys/egress-ca.js
CHANGED
|
@@ -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
|
-
|
|
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, {
|
|
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
|
};
|
package/dist/keys/x509.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
|
15
|
-
*
|
|
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
|
|
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
|
-
/**
|
|
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() -
|
|
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
|
|
113
|
-
*
|
|
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() -
|
|
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. */
|