@nylorun/runtime 0.16.0-beta → 0.19.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 +207 -0
- package/README.md +105 -63
- package/dist/adapters/execution/restate.d.ts +1 -3
- package/dist/adapters/execution/restate.js +4 -31
- package/dist/adapters/replication/pgoutput.js +1 -1
- package/dist/adapters/sandbox/local.js +1 -1
- package/dist/adapters/sandbox/virtual.js +1 -1
- package/dist/api/ag-ui/endpoint.js +1 -2
- package/dist/api/ag-ui/routes.d.ts +1 -1
- package/dist/api/ag-ui/routes.js +11 -13
- package/dist/api/ag-ui/translate.d.ts +1 -3
- package/dist/api/ag-ui/translate.js +2 -17
- package/dist/api/components.d.ts +4783 -2588
- package/dist/api/components.js +19 -21
- package/dist/api/gate/routes.d.ts +7 -8
- package/dist/api/gate/routes.js +58 -52
- package/dist/api/http/app.d.ts +6 -0
- package/dist/api/http/app.js +20 -14
- package/dist/api/http/define.d.ts +22 -13
- package/dist/api/http/define.js +43 -39
- package/dist/api/http/routes/access.d.ts +3 -19
- package/dist/api/http/routes/access.js +25 -184
- package/dist/api/http/routes/artifacts.js +3 -7
- package/dist/api/http/routes/files.d.ts +8 -0
- package/dist/api/http/routes/files.js +77 -0
- package/dist/api/http/routes/keys.d.ts +10 -0
- package/dist/api/http/routes/keys.js +64 -0
- package/dist/api/http/routes/me.d.ts +13 -0
- package/dist/api/http/routes/me.js +48 -0
- package/dist/api/http/routes/reads.d.ts +66 -0
- package/dist/api/http/routes/reads.js +127 -0
- package/dist/api/http/routes/sandboxes.d.ts +2 -2
- package/dist/api/http/routes/sandboxes.js +8 -7
- package/dist/api/http/routes/sessions.js +31 -20
- package/dist/api/http/routes/tenant.js +15 -18
- package/dist/api/http/routes/vaults.d.ts +13 -3
- package/dist/api/http/routes/vaults.js +136 -64
- package/dist/api/openapi.d.ts +10 -11
- package/dist/api/openapi.js +292 -68
- package/dist/artifacts/links.js +6 -6
- package/dist/artifacts/service.js +1 -1
- package/dist/core/flow-host.d.ts +44 -23
- package/dist/core/flow-host.js +88 -106
- package/dist/core/provider.d.ts +4 -1
- package/dist/core/provider.js +6 -1
- package/dist/core/sandbox-routes.d.ts +0 -9
- package/dist/core/sandbox-routes.js +2 -21
- package/dist/execution/memory.d.ts +4 -5
- package/dist/execution/memory.js +11 -25
- package/dist/execution/types.d.ts +3 -33
- package/dist/execution/types.js +2 -12
- package/dist/gates/http-tool.d.ts +86 -0
- package/dist/gates/http-tool.js +197 -0
- package/dist/gates/mcp-handler.d.ts +3 -0
- package/dist/gates/mcp-handler.js +6 -4
- package/dist/gates/meter.d.ts +2 -2
- package/dist/gates/meter.js +6 -0
- package/dist/gates/tenant-vaults.d.ts +19 -14
- package/dist/gates/tenant-vaults.js +17 -12
- package/dist/gates/tool-calls.d.ts +7 -15
- package/dist/gates/tool-calls.js +4 -4
- package/dist/gates/tool-client.d.ts +1 -1
- package/dist/gates/tool-client.js +23 -47
- package/dist/gates/tool-contract.d.ts +27 -39
- package/dist/gates/tool-contract.js +30 -21
- package/dist/gates/tool-gate.d.ts +25 -24
- package/dist/gates/tool-gate.js +11 -7
- package/dist/harness/calls.d.ts +10 -4
- package/dist/harness/calls.js +15 -6
- package/dist/harness/executors.d.ts +1 -1
- package/dist/harness/executors.js +17 -12
- package/dist/harness/main.d.ts +2 -2
- package/dist/harness/main.js +5 -13
- package/dist/harness/service.d.ts +4 -5
- package/dist/harness/service.js +9 -2
- package/dist/harness-api/in-process.js +2 -2
- package/dist/harness-api/record.d.ts +6 -3
- package/dist/harness-api/record.js +65 -72
- package/dist/harness-api/server.d.ts +1 -9
- package/dist/harness-api/server.js +19 -17
- package/dist/harness-api/start.js +1 -5
- package/dist/harness-api/workspace.js +2 -3
- package/dist/harness-api/ws-server.js +1 -1
- package/dist/host/app.d.ts +2 -10
- package/dist/host/app.js +24 -44
- package/dist/host/config-for.d.ts +5 -5
- package/dist/host/config-for.js +2 -3
- package/dist/host/config.d.ts +0 -11
- package/dist/host/create-host.d.ts +3 -40
- package/dist/host/create-host.js +18 -91
- package/dist/host/environment.d.ts +0 -3
- package/dist/host/environment.js +0 -9
- package/dist/host/gates.d.ts +4 -1
- package/dist/host/gates.js +9 -3
- package/dist/host/http.d.ts +1 -2
- package/dist/host/http.js +1 -7
- package/dist/host/index.d.ts +2 -2
- package/dist/host/index.js +2 -2
- package/dist/host/main.js +55 -40
- package/dist/host/operate.d.ts +29 -0
- package/dist/host/operate.js +223 -0
- package/dist/host/stack-config.d.ts +23 -20
- package/dist/host/stack-config.js +28 -44
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/infra/workers.d.ts +1 -1
- package/dist/keys/client.js +9 -1
- package/dist/keys/keys.d.ts +12 -2
- package/dist/keys/keys.js +10 -2
- package/dist/management-openapi.json +6491 -0
- package/dist/mcp/connect.d.ts +8 -4
- package/dist/mcp/connect.js +8 -27
- package/dist/mcp/pool.d.ts +6 -9
- package/dist/mcp/pool.js +8 -18
- package/dist/mcp/snapshot.d.ts +8 -2
- package/dist/mcp/snapshot.js +29 -2
- package/dist/media.d.ts +1 -1
- package/dist/media.js +1 -1
- package/dist/model/pi-model.js +3 -0
- package/dist/openapi.json +6228 -15615
- package/dist/reads/access.d.ts +4 -0
- package/dist/reads/access.js +12 -0
- package/dist/reads/cursor.d.ts +11 -0
- package/dist/reads/cursor.js +80 -0
- package/dist/reads/types.d.ts +25 -0
- package/dist/reads/types.js +1 -0
- package/dist/sandbox/manager.d.ts +16 -0
- package/dist/sandbox/manager.js +40 -0
- package/dist/sandbox/session-sandbox.js +13 -3
- package/dist/sandbox/skills.d.ts +13 -0
- package/dist/sandbox/skills.js +46 -0
- package/dist/sandbox/types.d.ts +2 -2
- package/dist/store/ownership.d.ts +9 -0
- package/dist/store/ownership.js +13 -0
- package/dist/store/postgres/connect.d.ts +2 -0
- package/dist/store/postgres/connect.js +29 -0
- package/dist/store/postgres/drizzle/0008_installation_vaults.sql +2 -0
- package/dist/store/postgres/drizzle/0009_oauth_pending.sql +19 -0
- package/dist/store/postgres/drizzle/0010_oss_auth_removals.sql +3 -0
- package/dist/store/postgres/drizzle/0011_key_roles.sql +3 -0
- package/dist/store/postgres/drizzle/0012_session_reads.sql +8 -0
- package/dist/store/postgres/drizzle/0013_definition_files.sql +16 -0
- package/dist/store/postgres/drizzle/0014_action_endpoints_removed.sql +2 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +49 -0
- package/dist/store/postgres/reads.d.ts +3 -0
- package/dist/store/postgres/reads.js +272 -0
- package/dist/store/postgres/schema.d.ts +423 -594
- package/dist/store/postgres/schema.js +84 -101
- package/dist/store/postgres/store.js +96 -248
- package/dist/store/postgres/tenant.d.ts +34 -2
- package/dist/store/postgres/tenant.js +16 -32
- package/dist/store/types.d.ts +44 -119
- package/dist/store/types.js +0 -1
- package/dist/streams/control.d.ts +0 -7
- package/dist/streams/control.js +0 -13
- package/dist/streams/types.d.ts +2 -20
- package/dist/streams/types.js +1 -1
- package/dist/tenant/advance.d.ts +3 -3
- package/dist/tenant/advance.js +10 -7
- package/dist/tenant/auth.d.ts +24 -15
- package/dist/tenant/auth.js +44 -55
- package/dist/tenant/cause.d.ts +3 -3
- package/dist/tenant/cause.js +1 -1
- package/dist/tenant/commands.d.ts +2 -18
- package/dist/tenant/commands.js +38 -179
- package/dist/tenant/context.d.ts +33 -45
- package/dist/tenant/definition-files.d.ts +24 -0
- package/dist/tenant/definition-files.js +103 -0
- package/dist/tenant/effects.d.ts +20 -18
- package/dist/tenant/effects.js +59 -133
- package/dist/tenant/ephemeral.d.ts +21 -8
- package/dist/tenant/ephemeral.js +11 -12
- package/dist/tenant/host-token.js +5 -5
- package/dist/tenant/identity-file.d.ts +75 -0
- package/dist/tenant/identity-file.js +202 -0
- package/dist/tenant/issuers.d.ts +48 -0
- package/dist/tenant/issuers.js +311 -0
- package/dist/tenant/jwt.js +3 -3
- package/dist/tenant/module.d.ts +1 -4
- package/dist/tenant/module.js +3 -12
- package/dist/tenant/operator-keys.d.ts +44 -0
- package/dist/tenant/operator-keys.js +87 -0
- package/dist/tenant/outbound.d.ts +40 -1
- package/dist/tenant/outbound.js +167 -18
- package/dist/tenant/paths.d.ts +1 -1
- package/dist/tenant/paths.js +1 -3
- package/dist/tenant/principals.d.ts +13 -13
- package/dist/tenant/principals.js +35 -36
- package/dist/tenant/run-token.js +6 -6
- package/dist/tenant/runtime.d.ts +5 -3
- package/dist/tenant/runtime.js +29 -15
- package/dist/tenant/sandboxes.d.ts +9 -6
- package/dist/tenant/sandboxes.js +16 -5
- package/dist/tenant/scheduler.d.ts +1 -5
- package/dist/tenant/scheduler.js +2 -5
- package/dist/tenant/session-streams.d.ts +8 -11
- package/dist/tenant/session-streams.js +48 -32
- package/dist/tenant/session.d.ts +8 -41
- package/dist/tenant/session.js +0 -37
- package/dist/tenant/sessions.d.ts +2 -2
- package/dist/tenant/sessions.js +17 -9
- package/dist/tenant/signing-keys.d.ts +3 -2
- package/dist/tenant/signing-keys.js +5 -5
- package/dist/tenant/skill-tool.d.ts +20 -0
- package/dist/tenant/skill-tool.js +72 -0
- package/dist/tenant/slim.d.ts +1 -1
- package/dist/tenant/slim.js +1 -1
- package/dist/tenant/status.js +7 -12
- package/dist/tenant/store-pg.d.ts +15 -0
- package/dist/tenant/store-pg.js +7 -3
- package/dist/tenant/streams.d.ts +3 -11
- package/dist/tenant/streams.js +2 -29
- package/dist/tenant/sweep.js +0 -5
- package/dist/tenant/transcript.d.ts +2 -2
- package/dist/tenant/transcript.js +2 -2
- package/dist/tenant/types.d.ts +33 -19
- package/dist/tenant/worker.d.ts +1 -3
- package/dist/tenant/worker.js +3 -8
- package/dist/vault/crypto.d.ts +7 -0
- package/dist/vault/crypto.js +16 -0
- package/dist/vault/oauth.d.ts +55 -0
- package/dist/vault/oauth.js +186 -0
- package/dist/vault/service.d.ts +54 -7
- package/dist/vault/service.js +261 -17
- package/dist/vault/sources.d.ts +60 -0
- package/dist/vault/sources.js +196 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -4
- package/dist/admin-openapi.json +0 -604
- package/dist/api/http/routes/actions.d.ts +0 -8
- package/dist/api/http/routes/actions.js +0 -76
- package/dist/api/http/routes/endpoints.d.ts +0 -7
- package/dist/api/http/routes/endpoints.js +0 -100
- package/dist/host/admin-api.d.ts +0 -23
- package/dist/host/admin-api.js +0 -74
- package/dist/host/cors.d.ts +0 -27
- package/dist/host/cors.js +0 -64
- package/dist/mcp/stdio.d.ts +0 -17
- package/dist/mcp/stdio.js +0 -82
- package/dist/tenant/access-policy.d.ts +0 -30
- package/dist/tenant/access-policy.js +0 -52
- package/dist/tenant/actions.d.ts +0 -14
- package/dist/tenant/actions.js +0 -29
- package/dist/tenant/browser.d.ts +0 -15
- package/dist/tenant/browser.js +0 -39
- package/dist/tenant/delivery-token.d.ts +0 -41
- package/dist/tenant/delivery-token.js +0 -104
- package/dist/tenant/delivery.d.ts +0 -62
- package/dist/tenant/delivery.js +0 -481
- package/dist/tenant/endpoints.d.ts +0 -67
- package/dist/tenant/endpoints.js +0 -90
- package/dist/tenant/subject-limits.d.ts +0 -16
- package/dist/tenant/subject-limits.js +0 -45
- package/dist/tenant/tokens.d.ts +0 -14
- package/dist/tenant/tokens.js +0 -187
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* `NYLORUN_GATES_TOKEN`. In a container, loop requires the gate: the loop
|
|
16
16
|
* process must never hold a model credential. `egress` (egress-gate, F7.2) joins gates and keys
|
|
17
17
|
* in the gateway and parses its listener (`NYLORUN_EGRESS_LISTEN_*`, default `0.0.0.0:4200`).
|
|
18
|
+
* Only gates reads the operator's credential resolver (`NYLORUN_RESOLVER_URL`,
|
|
19
|
+
* `NYLORUN_RESOLVER_TOKEN`, F9 C1): remote MCP calls are authorized in the gateway.
|
|
18
20
|
*
|
|
19
21
|
* `harness` (F6.2) runs alone: it holds the harness credential and nothing else. It connects to
|
|
20
22
|
* core's Harness API listener (`NYLORUN_HARNESS_URL`, `NYLORUN_HARNESS_TOKEN`), calls models and
|
|
@@ -34,9 +36,9 @@
|
|
|
34
36
|
* The Postgres, Restate and S2 endpoints are parsed and validated here;
|
|
35
37
|
* `infra/*` builds the clients from them. So is the Object store (`NYLORUN_OBJECT_STORE_*`),
|
|
36
38
|
* which every service may read; `host/main.ts` builds the `BlobStore` from it. So is who the Host's Tenant is when its database
|
|
37
|
-
* holds none yet (`NYLORUN_TENANT_ID`, `NYLORUN_TENANT_NAME
|
|
39
|
+
* holds none yet (`NYLORUN_TENANT_ID`, `NYLORUN_TENANT_NAME`).
|
|
38
40
|
*/
|
|
39
|
-
import {
|
|
41
|
+
import { isTenantId } from "@nylorun/core/compatibility";
|
|
40
42
|
import { blockedAddresses } from "../sandbox/pods/network-gate.js";
|
|
41
43
|
export const RUNTIME_SERVICES = ["core", "loop", "gates", "keys", "egress", "harness"];
|
|
42
44
|
/**
|
|
@@ -223,30 +225,6 @@ function parseListen(env) {
|
|
|
223
225
|
const allowedHosts = [...new Set([...explicit, ...loopbackForms(port)])];
|
|
224
226
|
return { host, port, allowedHosts };
|
|
225
227
|
}
|
|
226
|
-
function parseAdminListen(env) {
|
|
227
|
-
const rawPort = read(env, "NYLORUN_ADMIN_LISTEN_PORT");
|
|
228
|
-
const rawHost = read(env, "NYLORUN_ADMIN_LISTEN_HOST");
|
|
229
|
-
const rawAllowed = read(env, "NYLORUN_ADMIN_ALLOWED_HOSTS");
|
|
230
|
-
if (rawPort === undefined) {
|
|
231
|
-
if (rawHost !== undefined || rawAllowed !== undefined)
|
|
232
|
-
throw new StackConfigError("NYLORUN_ADMIN_LISTEN_PORT is required with NYLORUN_ADMIN_LISTEN_HOST or NYLORUN_ADMIN_ALLOWED_HOSTS");
|
|
233
|
-
return undefined;
|
|
234
|
-
}
|
|
235
|
-
const host = rawHost ?? DEFAULT_CONTAINER_LISTEN_HOST;
|
|
236
|
-
if (/\s|\//.test(host))
|
|
237
|
-
throw new StackConfigError(`NYLORUN_ADMIN_LISTEN_HOST is not an address: ${host}`);
|
|
238
|
-
const port = parsePort("NYLORUN_ADMIN_LISTEN_PORT", rawPort);
|
|
239
|
-
const explicit = rawAllowed === undefined
|
|
240
|
-
? []
|
|
241
|
-
: rawAllowed
|
|
242
|
-
.split(",")
|
|
243
|
-
.map((entry) => entry.trim())
|
|
244
|
-
.filter((entry) => entry !== "")
|
|
245
|
-
.map((entry) => normalizeAllowedHost("NYLORUN_ADMIN_ALLOWED_HOSTS", entry));
|
|
246
|
-
if (explicit.length === 0 && !isLoopbackAddress(host))
|
|
247
|
-
throw new StackConfigError(`NYLORUN_ADMIN_ALLOWED_HOSTS is required when NYLORUN_ADMIN_LISTEN_HOST is ${host}: list the Host headers operators send, e.g. runtime:${port},localhost:<published port>`);
|
|
248
|
-
return { host, port, allowedHosts: [...new Set([...explicit, ...loopbackForms(port)])] };
|
|
249
|
-
}
|
|
250
228
|
const IDENTITY_KEY = /^publickeyv1_[1-9A-HJ-NP-Za-km-z]{32,64}$/;
|
|
251
229
|
function parseIdentityKeys(env) {
|
|
252
230
|
const raw = read(env, "NYLORUN_RESTATE_IDENTITY_KEY");
|
|
@@ -269,15 +247,12 @@ export function parseStackConfig(env, argv) {
|
|
|
269
247
|
// The image sets NYLORUN_LISTEN_*: only the API's processes read them.
|
|
270
248
|
const servesApi = services.has("core") || services.has("loop");
|
|
271
249
|
const listen = servesApi ? parseListen(env) : undefined;
|
|
272
|
-
const operator = servesApi ? parseAdminListen(env) : undefined;
|
|
273
250
|
const gates = services.has("gates") || services.has("keys") ? parseGates(env) : undefined;
|
|
274
251
|
const egress = services.has("egress") ? parseEgress(env) : undefined;
|
|
275
|
-
// The gates service's clients: the loop's model and tool calls
|
|
252
|
+
// The gates service's clients: the loop's model and tool calls.
|
|
276
253
|
const modelGate = servesApi ? parseModelGate(env) : undefined;
|
|
277
254
|
// The keys service is the gateway's unless NYLORUN_KEYS_URL names another listener.
|
|
278
255
|
const keys = servesApi ? (parseKeysEndpoint(env) ?? modelGate) : undefined;
|
|
279
|
-
if (operator && listen && operator.port === listen.port)
|
|
280
|
-
throw new StackConfigError("NYLORUN_ADMIN_LISTEN_PORT must differ from NYLORUN_LISTEN_PORT");
|
|
281
256
|
if (services.has("loop") && listen && !modelGate)
|
|
282
257
|
throw new StackConfigError("NYLORUN_GATES_URL is required for the loop service in a container: model calls go through the gates service (the gateway container), so the loop never holds a model credential. Set NYLORUN_GATES_URL and NYLORUN_GATES_TOKEN (`nylorun start` sets both)");
|
|
283
258
|
const rawPacking = read(env, "NYLORUN_PACKING");
|
|
@@ -318,18 +293,14 @@ export function parseStackConfig(env, argv) {
|
|
|
318
293
|
if (restateIdentityKeys)
|
|
319
294
|
endpoints.restateIdentityKeys = restateIdentityKeys;
|
|
320
295
|
const publicUrl = parseUrl(env, "NYLORUN_PUBLIC_URL", http)?.replace(/\/+$/, "");
|
|
321
|
-
const rawBrowser = read(env, "NYLORUN_BROWSER_ACCESS");
|
|
322
|
-
if (rawBrowser !== undefined && rawBrowser !== "on" && rawBrowser !== "off")
|
|
323
|
-
throw new StackConfigError(`NYLORUN_BROWSER_ACCESS must be on or off, not ${rawBrowser}`);
|
|
324
296
|
const harnessMode = servesApi ? parseHarnessMode(env) : undefined;
|
|
325
297
|
const sandboxes = servesApi ? parseSandboxes(env) : undefined;
|
|
326
298
|
// Pods connect to the Harness API listener even when the Tenant runs its own harness.
|
|
327
299
|
const harnessListener = harnessMode === "remote" || sandboxes
|
|
328
300
|
? parseHarnessListener(env, harnessMode === "remote")
|
|
329
301
|
: undefined;
|
|
330
|
-
if (harnessListener &&
|
|
331
|
-
|
|
332
|
-
throw new StackConfigError("NYLORUN_HARNESS_LISTEN_PORT must differ from NYLORUN_LISTEN_PORT and NYLORUN_ADMIN_LISTEN_PORT");
|
|
302
|
+
if (harnessListener && listen?.port === harnessListener.listen.port)
|
|
303
|
+
throw new StackConfigError("NYLORUN_HARNESS_LISTEN_PORT must differ from NYLORUN_LISTEN_PORT");
|
|
333
304
|
const delivery = parseDelivery(env);
|
|
334
305
|
const tenant = servesApi ? parseTenant(env) : undefined;
|
|
335
306
|
const objectStore = parseObjectStore(env);
|
|
@@ -344,11 +315,9 @@ export function parseStackConfig(env, argv) {
|
|
|
344
315
|
...(listen ? { listen } : {}),
|
|
345
316
|
endpoints,
|
|
346
317
|
...(publicUrl ? { publicUrl } : {}),
|
|
347
|
-
...(rawBrowser === undefined ? {} : { browserAccess: rawBrowser === "on" }),
|
|
348
318
|
...(harnessMode ? { harnessMode } : {}),
|
|
349
319
|
...(harnessListener ? { harnessListener } : {}),
|
|
350
320
|
...(sandboxes ? { sandboxes } : {}),
|
|
351
|
-
...(operator ? { operator } : {}),
|
|
352
321
|
...(delivery ? { delivery } : {}),
|
|
353
322
|
...(tenant ? { tenant } : {}),
|
|
354
323
|
...(objectStore ? { objectStore } : {}),
|
|
@@ -380,15 +349,13 @@ function parseTenant(env) {
|
|
|
380
349
|
const id = read(env, "NYLORUN_TENANT_ID");
|
|
381
350
|
if (id !== undefined && !isTenantId(id))
|
|
382
351
|
throw new StackConfigError(`NYLORUN_TENANT_ID must be a Tenant id (tn_ and 26 Crockford characters), not ${id}`);
|
|
383
|
-
const
|
|
384
|
-
const
|
|
385
|
-
for (const principal of derivedPrincipals)
|
|
386
|
-
if (!DERIVED_PRINCIPAL_ID_PATTERN.test(principal) || principal === "studio")
|
|
387
|
-
throw new StackConfigError(`NYLORUN_DERIVED_PRINCIPALS has '${principal}': each entry must match ${DERIVED_PRINCIPAL_ID_PATTERN} and not be studio`);
|
|
352
|
+
const identityFile = read(env, "NYLORUN_IDENTITY_FILE");
|
|
353
|
+
const managementKeyFile = read(env, "NYLORUN_MANAGEMENT_KEY_FILE");
|
|
388
354
|
return {
|
|
389
355
|
...(id ? { id } : {}),
|
|
390
356
|
name: read(env, "NYLORUN_TENANT_NAME") ?? "default",
|
|
391
|
-
|
|
357
|
+
...(identityFile ? { identityFile } : {}),
|
|
358
|
+
...(managementKeyFile ? { managementKeyFile } : {}),
|
|
392
359
|
};
|
|
393
360
|
}
|
|
394
361
|
const GATES_TOKEN = /^[0-9a-f]{64,}$/i;
|
|
@@ -542,11 +509,28 @@ function parseGates(env) {
|
|
|
542
509
|
throw new StackConfigError("NYLORUN_GATES_TOKEN is required for --service gates: the token the loop presents (`nylorun start` sets it)");
|
|
543
510
|
if (!GATES_TOKEN.test(token))
|
|
544
511
|
throw new StackConfigError("NYLORUN_GATES_TOKEN must be at least 32 bytes as hex");
|
|
512
|
+
const resolver = parseResolver(env);
|
|
545
513
|
return {
|
|
546
514
|
listen: { host, port, allowedHosts: [...new Set([...explicit, ...loopbackForms(port)])] },
|
|
547
515
|
token,
|
|
516
|
+
...(resolver ? { resolver } : {}),
|
|
548
517
|
};
|
|
549
518
|
}
|
|
519
|
+
/** `GatesConfig.resolver` from `NYLORUN_RESOLVER_URL` and `NYLORUN_RESOLVER_TOKEN`: both or neither. */
|
|
520
|
+
function parseResolver(env) {
|
|
521
|
+
const url = parseUrl(env, "NYLORUN_RESOLVER_URL", ["http:", "https:"]);
|
|
522
|
+
const token = read(env, "NYLORUN_RESOLVER_TOKEN");
|
|
523
|
+
if (url === undefined) {
|
|
524
|
+
if (token !== undefined)
|
|
525
|
+
throw new StackConfigError("NYLORUN_RESOLVER_TOKEN is set without NYLORUN_RESOLVER_URL: set the URL of your credential resolver");
|
|
526
|
+
return undefined;
|
|
527
|
+
}
|
|
528
|
+
if (token === undefined)
|
|
529
|
+
throw new StackConfigError("NYLORUN_RESOLVER_TOKEN is required with NYLORUN_RESOLVER_URL: the bearer the gateway presents to your credential resolver");
|
|
530
|
+
if (/\s/.test(token))
|
|
531
|
+
throw new StackConfigError("NYLORUN_RESOLVER_TOKEN cannot contain whitespace");
|
|
532
|
+
return { url, token };
|
|
533
|
+
}
|
|
550
534
|
/** `StackConfig.egress` from `NYLORUN_EGRESS_LISTEN_*`. CONNECT has no Host header to check. */
|
|
551
535
|
function parseEgress(env) {
|
|
552
536
|
const host = read(env, "NYLORUN_EGRESS_LISTEN_HOST") ?? DEFAULT_CONTAINER_LISTEN_HOST;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
export { openTenantRuntime, type TenantOpenHooks, } from "./tenant/runtime.js";
|
|
2
2
|
export { startEphemeralRuntime, type StartEphemeralRuntimeOptions, type EphemeralRuntime, } from "./tenant/ephemeral.js";
|
|
3
|
+
export { parseIdentityFile, IdentityFileError, type TrustedIssuerConfig, } from "./tenant/identity-file.js";
|
|
4
|
+
export { createTrustedIssuers, type TrustedIssuers, type TrustedIssuersOptions, } from "./tenant/issuers.js";
|
|
3
5
|
export type { TenantConfig, TenantHandle, TenantPaths, Logger, OpenTenantRuntime, } from "./tenant/types.js";
|
|
4
6
|
export { scriptedModel, gatewayModel, type ModelProvider } from "./core/provider.js";
|
|
7
|
+
export type { ResolverConfig } from "./vault/sources.js";
|
|
5
8
|
export type { RuntimeAgent } from "./contracts.js";
|
|
6
9
|
export { IMAGE_MEDIA_TYPES, MAX_IMAGE_BYTES, decodeImageBase64, validateImageBytes, } from "./media.js";
|
|
7
10
|
export type { RuntimeModelAdapter } from "./contracts.js";
|
|
8
|
-
export { baselineEnvironment, hostProcessEnvironment,
|
|
11
|
+
export { baselineEnvironment, hostProcessEnvironment, } from "./host/environment.js";
|
|
9
12
|
export type { HostProcessPathInputs } from "./host/environment.js";
|
|
10
13
|
export type { HostConfigFile, HostCredentialsFile, } from "./host/config.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { openTenantRuntime, } from "./tenant/runtime.js";
|
|
2
2
|
export { startEphemeralRuntime, } from "./tenant/ephemeral.js";
|
|
3
|
+
export { parseIdentityFile, IdentityFileError, } from "./tenant/identity-file.js";
|
|
4
|
+
export { createTrustedIssuers, } from "./tenant/issuers.js";
|
|
3
5
|
export { scriptedModel, gatewayModel } from "./core/provider.js";
|
|
4
6
|
export { IMAGE_MEDIA_TYPES, MAX_IMAGE_BYTES, decodeImageBase64, validateImageBytes, } from "./media.js";
|
|
5
|
-
export { baselineEnvironment, hostProcessEnvironment,
|
|
7
|
+
export { baselineEnvironment, hostProcessEnvironment, } from "./host/environment.js";
|
package/dist/infra/workers.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* | Services | Serves | `execution.start` |
|
|
5
5
|
* | --- | --- | --- |
|
|
6
|
-
* | `core` |
|
|
6
|
+
* | `core` | Runtime and Management APIs, SSE | **never**: wakes, timers and sweep arming go through Restate's ingress, which needs no Worker endpoint |
|
|
7
7
|
* | `loop` | the Restate endpoint (`NylorunSession.advance`, `NylorunTenant.sweep`, timers) | yes |
|
|
8
8
|
* | `core,loop` | both (the local stack's `runtime` container) | yes |
|
|
9
9
|
*
|
package/dist/keys/client.js
CHANGED
|
@@ -12,10 +12,18 @@ import { KEYS_PATH } from "./contract.js";
|
|
|
12
12
|
import { KEYS_OPERATIONS } from "./keys.js";
|
|
13
13
|
/** Signing and vault writes are short; anything slower is a gateway in trouble. */
|
|
14
14
|
const KEYS_TIMEOUT_MS = 30_000;
|
|
15
|
+
/**
|
|
16
|
+
* MCP OAuth connect calls the authorization server several times (discovery, registration, the
|
|
17
|
+
* code exchange), each bounded by `guardedFetch`'s 30 s: these wait longer.
|
|
18
|
+
*/
|
|
19
|
+
const SLOW_OPERATIONS = {
|
|
20
|
+
startOAuth: 120_000,
|
|
21
|
+
finishOAuth: 60_000,
|
|
22
|
+
};
|
|
15
23
|
export function httpKeys(options) {
|
|
16
24
|
const where = new URL(options.url).origin;
|
|
17
|
-
const timeoutMs = options.timeoutMs ?? KEYS_TIMEOUT_MS;
|
|
18
25
|
function call(operation, args) {
|
|
26
|
+
const timeoutMs = Math.max(options.timeoutMs ?? KEYS_TIMEOUT_MS, SLOW_OPERATIONS[operation] ?? 0);
|
|
19
27
|
const url = new URL(`${KEYS_PATH}/${operation}`, options.url);
|
|
20
28
|
const send = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
21
29
|
const payload = Buffer.from(JSON.stringify({ args }), "utf8");
|
package/dist/keys/keys.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CreateCredentialRequest, CredentialInfo, HostModelView, PutHostModelRequest, RotateCredentialRequest, SelectHostModelRequest, SigningKeyView } from "@nylorun/core/contracts";
|
|
2
2
|
import type { SessionStore } from "../store/types.js";
|
|
3
3
|
import { type SigningKeys } from "../tenant/signing-keys.js";
|
|
4
|
-
import type { VaultService } from "../vault/service.js";
|
|
4
|
+
import type { FinishOAuthInput, StartOAuthInput, VaultService } from "../vault/service.js";
|
|
5
5
|
/** One JWT to sign: its `typ` and every claim, `iss`, `aud`, `sub`, `iat`, `exp` and `jti` included. */
|
|
6
6
|
export interface SignRequest {
|
|
7
7
|
readonly typ: string;
|
|
@@ -26,9 +26,19 @@ export interface Keys {
|
|
|
26
26
|
}): Promise<SigningKeyView[]>;
|
|
27
27
|
/** Creates the current and standby keys when the Tenant has none. */
|
|
28
28
|
ensureSigningKeys(): Promise<void>;
|
|
29
|
+
/** Starts an MCP OAuth connect into an installation vault (`VaultService.startOAuth`). */
|
|
30
|
+
startOAuth(input: StartOAuthInput): Promise<{
|
|
31
|
+
authorizeUrl: string;
|
|
32
|
+
expiresAt: string;
|
|
33
|
+
}>;
|
|
34
|
+
/** Finishes one from its callback (`VaultService.finishOAuth`). */
|
|
35
|
+
finishOAuth(input: FinishOAuthInput): Promise<{
|
|
36
|
+
vaultId: string;
|
|
37
|
+
credentialId: string;
|
|
38
|
+
}>;
|
|
29
39
|
}
|
|
30
40
|
/** The operations, by the name the HTTP route carries. */
|
|
31
|
-
export declare const KEYS_OPERATIONS: readonly ["createCredential", "rotateCredential", "putHostModel", "selectHostModel", "sign", "rotateSigningKeys", "ensureSigningKeys"];
|
|
41
|
+
export declare const KEYS_OPERATIONS: readonly ["createCredential", "rotateCredential", "putHostModel", "selectHostModel", "sign", "rotateSigningKeys", "ensureSigningKeys", "startOAuth", "finishOAuth"];
|
|
32
42
|
export type KeysOperation = (typeof KEYS_OPERATIONS)[number];
|
|
33
43
|
export interface InProcessKeysOptions {
|
|
34
44
|
readonly store: SessionStore;
|
package/dist/keys/keys.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The keys seam (blueprint §14, F4.2): everything that needs the vault key. Vault writes that
|
|
3
3
|
* touch a secret (creating and rotating a credential, setting and selecting the host model;
|
|
4
|
-
* rotation and selection decrypt the old secret first) and all token signing (
|
|
5
|
-
*
|
|
4
|
+
* rotation and selection decrypt the old secret first) and all token signing (capability
|
|
5
|
+
* links, run and host tokens, signing-key rotation) run here, whole, so the process that calls them never
|
|
6
6
|
* holds the key or a private signing key.
|
|
7
7
|
*
|
|
8
|
+
* MCP OAuth connect (F9-D14) runs here too: discovery, registration, the code exchange and the
|
|
9
|
+
* credential it seals, so the plaintext tokens, the PKCE verifier and any client secret never
|
|
10
|
+
* reach the runtime container; core only routes the start and the callback.
|
|
11
|
+
*
|
|
8
12
|
* Two implementations: `inProcessKeys` (embedding, the ephemeral Runtime, tests, and the gates
|
|
9
13
|
* service itself, which serves the HTTP routes with it), and `httpKeys` (`client.ts`), the
|
|
10
14
|
* runtime container's client of the `keys` service in the gateway.
|
|
@@ -20,6 +24,8 @@ export const KEYS_OPERATIONS = [
|
|
|
20
24
|
"sign",
|
|
21
25
|
"rotateSigningKeys",
|
|
22
26
|
"ensureSigningKeys",
|
|
27
|
+
"startOAuth",
|
|
28
|
+
"finishOAuth",
|
|
23
29
|
];
|
|
24
30
|
export function inProcessKeys(options) {
|
|
25
31
|
const { store, vault, signingKeys, kek } = options;
|
|
@@ -28,6 +34,8 @@ export function inProcessKeys(options) {
|
|
|
28
34
|
rotateCredential: (vaultId, id, body) => vault.rotateCredential(vaultId, id, body),
|
|
29
35
|
putHostModel: (body) => vault.putHostModel(body),
|
|
30
36
|
selectHostModel: (body) => vault.selectHostModel(body),
|
|
37
|
+
startOAuth: (input) => vault.startOAuth(input),
|
|
38
|
+
finishOAuth: (input) => vault.finishOAuth(input),
|
|
31
39
|
async sign(request) {
|
|
32
40
|
const key = kek();
|
|
33
41
|
const row = await store.tx((t) => signingKeys.ensure(t, key));
|