@stigmer/server 3.15.3-dev.20260916211208 → 3.16.1-dev.20260917224426
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/dist/authorization/lane-admission.d.ts +50 -0
- package/dist/authorization/lane-admission.d.ts.map +1 -0
- package/dist/authorization/lane-admission.js +13 -0
- package/dist/authorization/lane-admission.js.map +1 -0
- package/dist/authorization/schedule-fire-caller.d.ts +2 -2
- package/dist/authorization/schedule-fire-caller.d.ts.map +1 -1
- package/dist/authorization/schedule-fire-caller.js +8 -8
- package/dist/authorization/schedule-fire-caller.js.map +1 -1
- package/dist/boot/compose.d.ts +12 -0
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +68 -14
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/inprocess.d.ts.map +1 -1
- package/dist/boot/inprocess.js +6 -1
- package/dist/boot/inprocess.js.map +1 -1
- package/dist/domain/executioncontext/resolve-values-for-caller.d.ts +33 -14
- package/dist/domain/executioncontext/resolve-values-for-caller.d.ts.map +1 -1
- package/dist/domain/executioncontext/resolve-values-for-caller.js +32 -8
- package/dist/domain/executioncontext/resolve-values-for-caller.js.map +1 -1
- package/dist/domain/identityaccount/actor.d.ts +33 -18
- package/dist/domain/identityaccount/actor.d.ts.map +1 -1
- package/dist/domain/identityaccount/actor.js +20 -3
- package/dist/domain/identityaccount/actor.js.map +1 -1
- package/dist/domain/identityaccount/resolve.d.ts +19 -0
- package/dist/domain/identityaccount/resolve.d.ts.map +1 -1
- package/dist/domain/identityaccount/resolve.js +12 -0
- package/dist/domain/identityaccount/resolve.js.map +1 -1
- package/dist/domain/mcpserver/connect-execution-id.d.ts +5 -0
- package/dist/domain/mcpserver/connect-execution-id.d.ts.map +1 -0
- package/dist/domain/mcpserver/connect-execution-id.js +32 -0
- package/dist/domain/mcpserver/connect-execution-id.js.map +1 -0
- package/dist/domain/mcpserver/connect.d.ts +28 -2
- package/dist/domain/mcpserver/connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect.js +27 -7
- package/dist/domain/mcpserver/connect.js.map +1 -1
- package/dist/domain/mcpserver/engine.d.ts +9 -3
- package/dist/domain/mcpserver/engine.d.ts.map +1 -1
- package/dist/domain/mcpserver/engine.js.map +1 -1
- package/dist/domain/mcpserver/start-connect.js +1 -1
- package/dist/domain/mcpserver/start-connect.js.map +1 -1
- package/dist/domain/platform/controller.d.ts +31 -11
- package/dist/domain/platform/controller.d.ts.map +1 -1
- package/dist/domain/platform/controller.js +2 -3
- package/dist/domain/platform/controller.js.map +1 -1
- package/dist/domain/plugin/materialize/agent.d.ts +10 -1
- package/dist/domain/plugin/materialize/agent.d.ts.map +1 -1
- package/dist/domain/plugin/materialize/agent.js +35 -1
- package/dist/domain/plugin/materialize/agent.js.map +1 -1
- package/dist/domain/plugin/materialize/plan.d.ts.map +1 -1
- package/dist/domain/plugin/materialize/plan.js +1 -1
- package/dist/domain/plugin/materialize/plan.js.map +1 -1
- package/dist/domain/plugin/overlay/sanitize.d.ts.map +1 -1
- package/dist/domain/plugin/overlay/sanitize.js +4 -2
- package/dist/domain/plugin/overlay/sanitize.js.map +1 -1
- package/dist/domain/project/reconcile.d.ts.map +1 -1
- package/dist/domain/project/reconcile.js +14 -10
- package/dist/domain/project/reconcile.js.map +1 -1
- package/dist/domain/workflowexecution/phases.d.ts +21 -0
- package/dist/domain/workflowexecution/phases.d.ts.map +1 -0
- package/dist/domain/workflowexecution/phases.js +31 -0
- package/dist/domain/workflowexecution/phases.js.map +1 -0
- package/dist/identity/oidc-verifier.js +8 -1
- package/dist/identity/oidc-verifier.js.map +1 -1
- package/dist/pipeline/apiresource-meta.d.ts +15 -0
- package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
- package/dist/pipeline/apiresource-meta.js +34 -0
- package/dist/pipeline/apiresource-meta.js.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.js +5 -3
- package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
- package/dist/runnerauth/bound-execution.d.ts +27 -0
- package/dist/runnerauth/bound-execution.d.ts.map +1 -0
- package/dist/runnerauth/bound-execution.js +137 -0
- package/dist/runnerauth/bound-execution.js.map +1 -0
- package/dist/runnerauth/built-in-runner-credential-provider.d.ts +28 -0
- package/dist/runnerauth/built-in-runner-credential-provider.d.ts.map +1 -0
- package/dist/runnerauth/built-in-runner-credential-provider.js +217 -0
- package/dist/runnerauth/built-in-runner-credential-provider.js.map +1 -0
- package/dist/runnerauth/constants.d.ts +63 -0
- package/dist/runnerauth/constants.d.ts.map +1 -0
- package/dist/runnerauth/constants.js +63 -0
- package/dist/runnerauth/constants.js.map +1 -0
- package/dist/runnerauth/dispatch-credential.d.ts +38 -0
- package/dist/runnerauth/dispatch-credential.d.ts.map +1 -0
- package/dist/runnerauth/dispatch-credential.js +17 -0
- package/dist/runnerauth/dispatch-credential.js.map +1 -0
- package/dist/runnerauth/runner-credential-provider.d.ts +49 -11
- package/dist/runnerauth/runner-credential-provider.d.ts.map +1 -1
- package/dist/runnerauth/runner-credential-provider.js +16 -4
- package/dist/runnerauth/runner-credential-provider.js.map +1 -1
- package/dist/runnerauth/runner-subject-verifier.d.ts +14 -0
- package/dist/runnerauth/runner-subject-verifier.d.ts.map +1 -0
- package/dist/runnerauth/runner-subject-verifier.js +115 -0
- package/dist/runnerauth/runner-subject-verifier.js.map +1 -0
- package/dist/runnerauth/runnerauth.d.ts +33 -4
- package/dist/runnerauth/runnerauth.d.ts.map +1 -1
- package/dist/runnerauth/runnerauth.js +131 -35
- package/dist/runnerauth/runnerauth.js.map +1 -1
- package/dist/temporal/agentexecution/engine-client.d.ts +13 -0
- package/dist/temporal/agentexecution/engine-client.d.ts.map +1 -1
- package/dist/temporal/agentexecution/engine-client.js +10 -2
- package/dist/temporal/agentexecution/engine-client.js.map +1 -1
- package/dist/temporal/agentexecution/workflow-input.d.ts +13 -0
- package/dist/temporal/agentexecution/workflow-input.d.ts.map +1 -1
- package/dist/temporal/agentexecution/workflows/invoke-agent-execution.d.ts.map +1 -1
- package/dist/temporal/agentexecution/workflows/invoke-agent-execution.js +35 -31
- package/dist/temporal/agentexecution/workflows/invoke-agent-execution.js.map +1 -1
- package/dist/temporal/workflowexecution/engine-client.d.ts +24 -0
- package/dist/temporal/workflowexecution/engine-client.d.ts.map +1 -1
- package/dist/temporal/workflowexecution/engine-client.js +26 -19
- package/dist/temporal/workflowexecution/engine-client.js.map +1 -1
- package/dist/temporal/workflowexecution/workflow-input.d.ts +14 -0
- package/dist/temporal/workflowexecution/workflow-input.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/authorization/__tests__/lane-admission.test.ts +115 -0
- package/src/authorization/lane-admission.ts +73 -0
- package/src/authorization/schedule-fire-caller.ts +10 -14
- package/src/boot/compose.ts +93 -22
- package/src/boot/inprocess.ts +7 -1
- package/src/domain/executioncontext/__tests__/executioncontext.test.ts +104 -0
- package/src/domain/executioncontext/__tests__/resolve-values-capability.test.ts +33 -4
- package/src/domain/executioncontext/resolve-values-for-caller.ts +79 -22
- package/src/domain/identityaccount/__tests__/account-for-stamp.test.ts +111 -0
- package/src/domain/identityaccount/actor.ts +61 -21
- package/src/domain/identityaccount/resolve.ts +31 -0
- package/src/domain/mcpserver/__tests__/connect.test.ts +17 -2
- package/src/domain/mcpserver/connect-execution-id.ts +34 -0
- package/src/domain/mcpserver/connect.ts +38 -3
- package/src/domain/mcpserver/engine.ts +9 -3
- package/src/domain/mcpserver/start-connect.ts +1 -1
- package/src/domain/platform/__tests__/platform.test.ts +47 -1
- package/src/domain/platform/controller.ts +33 -14
- package/src/domain/plugin/__tests__/materialize.test.ts +60 -1
- package/src/domain/plugin/__tests__/plugin.test.ts +122 -1
- package/src/domain/plugin/__tests__/sanitize.test.ts +2 -2
- package/src/domain/plugin/materialize/agent.ts +38 -0
- package/src/domain/plugin/materialize/plan.ts +7 -1
- package/src/domain/plugin/overlay/sanitize.ts +4 -2
- package/src/domain/project/__tests__/reconcile.test.ts +51 -5
- package/src/domain/project/reconcile.ts +20 -15
- package/src/domain/workflowexecution/__tests__/phases.test.ts +58 -0
- package/src/domain/workflowexecution/phases.ts +33 -0
- package/src/extensions/__tests__/extension-composition.test.ts +7 -1
- package/src/identity/__tests__/oidc-verifier.test.ts +22 -0
- package/src/identity/oidc-verifier.ts +8 -1
- package/src/pipeline/__tests__/kind-by-id-prefix.test.ts +75 -0
- package/src/pipeline/apiresource-meta.ts +41 -0
- package/src/pipeline/steps/__tests__/guard-memory-capture.test.ts +55 -35
- package/src/pipeline/steps/guard-memory-capture.ts +5 -3
- package/src/runnerauth/__tests__/bound-execution.test.ts +334 -0
- package/src/runnerauth/__tests__/built-in-runner-credential-provider.test.ts +516 -0
- package/src/runnerauth/__tests__/dispatch-credential.test.ts +94 -0
- package/src/runnerauth/__tests__/runner-credential-provider.test.ts +27 -0
- package/src/runnerauth/__tests__/runner-subject-composed.test.ts +497 -0
- package/src/runnerauth/__tests__/runner-subject-verifier.test.ts +541 -0
- package/src/runnerauth/bound-execution.ts +270 -0
- package/src/runnerauth/built-in-runner-credential-provider.ts +300 -0
- package/src/runnerauth/constants.ts +74 -0
- package/src/runnerauth/dispatch-credential.ts +63 -0
- package/src/runnerauth/runner-credential-provider.ts +60 -11
- package/src/runnerauth/runner-subject-verifier.ts +152 -0
- package/src/runnerauth/runnerauth.ts +148 -38
- package/src/temporal/agentexecution/__tests__/engine-client.test.ts +107 -38
- package/src/temporal/agentexecution/__tests__/invoke-workflow.test.ts +105 -2
- package/src/temporal/agentexecution/engine-client.ts +27 -2
- package/src/temporal/agentexecution/workflow-input.ts +13 -0
- package/src/temporal/agentexecution/workflows/invoke-agent-execution.ts +90 -44
- package/src/temporal/workflowexecution/__tests__/engine-client.test.ts +139 -33
- package/src/temporal/workflowexecution/engine-client.ts +48 -21
- package/src/temporal/workflowexecution/workflow-input.ts +14 -0
|
@@ -14,21 +14,37 @@
|
|
|
14
14
|
* distinguishes itself with an execution-scoped token minted by
|
|
15
15
|
* getRunnerScopedToken and presented as a Bearer authorization header
|
|
16
16
|
* (the same header shape a cloud runner uses for its sandbox credential).
|
|
17
|
-
* Decrypt requires the FULL binding: a valid
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* Decrypt requires the FULL binding: a valid token whose execution_id
|
|
18
|
+
* claim equals this EC's spec.execution_id, and — for a RUN credential,
|
|
19
|
+
* the no-`exp` token the dispatch path hands the runner — a bound
|
|
20
|
+
* execution that is still live (runnerauth/bound-execution.ts: not
|
|
21
|
+
* terminal, or ended within the grace). Everything else — no header, a
|
|
22
|
+
* malformed or expired token, a token minted for a different execution,
|
|
23
|
+
* a run credential whose run is over — falls closed to the same
|
|
24
|
+
* redaction get/getByReference apply, as a SUCCESSFUL response, not an
|
|
25
|
+
* error.
|
|
22
26
|
*
|
|
23
|
-
*
|
|
24
|
-
* chassis
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
27
|
+
* The decrypt decision lives HERE, in the domain, whatever the identity
|
|
28
|
+
* chassis makes of the token. Under trusted-local no verifier claims it
|
|
29
|
+
* and this is the one RPC that reads the raw header (the consumer the
|
|
30
|
+
* runnerauth module header reserves, "the executioncontext resolve
|
|
31
|
+
* step"). Under the built-in authorization posture the runner-subject
|
|
32
|
+
* verifier ALSO admits the same token as the run's human at position 1
|
|
33
|
+
* (runnerauth.ts header, 2026-09-16) — that decides WHO is calling and
|
|
34
|
+
* whether they may read the row; whether the row's secrets are decrypted
|
|
35
|
+
* for them is still this lane's binding check, so a person who can view
|
|
36
|
+
* an execution's context never receives its plaintext by holding a
|
|
37
|
+
* credential for a different one. The redaction-as-success contract is
|
|
38
|
+
* pinned by the conformance suites and holds on every arm.
|
|
39
|
+
*
|
|
40
|
+
* Why liveness is read only for a no-`exp` token: a clocked token's
|
|
41
|
+
* validity was decided by `verify` (its clock) and its binding, and the
|
|
42
|
+
* ExecutionContext it opens need not name an execution row at all — the
|
|
43
|
+
* connect lane's token opens an EC for an MCP discovery, and the rosters
|
|
44
|
+
* pin a clocked token decrypting an EC whose execution id names no row.
|
|
45
|
+
* A run credential has no clock; the row is the only thing that can end
|
|
46
|
+
* it, and a plaintext token in Temporal history must not decrypt a
|
|
47
|
+
* finished run's secrets for good.
|
|
32
48
|
*
|
|
33
49
|
* # Decrypt error doctrine (the oss#405 runtime-resolution doctrine,
|
|
34
50
|
* # arms per the two-armed taxonomy in encryption/errors.ts)
|
|
@@ -51,11 +67,14 @@ import type { HandlerContext } from "@connectrpc/connect";
|
|
|
51
67
|
import type { ExecutionContext } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/api_pb";
|
|
52
68
|
import type { Logger } from "../../boot/logger.js";
|
|
53
69
|
import type { SecretService } from "../../encryption/encryption.js";
|
|
70
|
+
import type { BoundExecutionStore } from "../../runnerauth/bound-execution.js";
|
|
54
71
|
import type { RunnerCredentialProvider } from "../../runnerauth/runner-credential-provider.js";
|
|
55
72
|
export interface ResolveValuesDeps {
|
|
56
73
|
readonly logger: Logger;
|
|
57
74
|
readonly secretService: SecretService;
|
|
58
75
|
readonly runnerAuthService: RunnerCredentialProvider;
|
|
76
|
+
/** Where the bound execution lives — read for a run credential's liveness only. */
|
|
77
|
+
readonly store: BoundExecutionStore;
|
|
59
78
|
}
|
|
60
79
|
/**
|
|
61
80
|
* Applies the credential-dispatched transform in place: decrypt for a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-values-for-caller.d.ts","sourceRoot":"","sources":["../../../src/domain/executioncontext/resolve-values-for-caller.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"resolve-values-for-caller.d.ts","sourceRoot":"","sources":["../../../src/domain/executioncontext/resolve-values-for-caller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+DAA+D,CAAC;AAEtG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAOpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAC;AAQ/F,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,iBAAiB,EAAE,wBAAwB,CAAC;IACrD,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;CACrC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,iBAAiB,EACvB,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,gBAAgB,GACnB,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { EncryptionUnavailableError } from "../../encryption/encryption.js";
|
|
2
2
|
import { internalError } from "../../pipeline/errors.js";
|
|
3
3
|
import { parseBearerToken } from "../../pipeline/interceptors/auth.js";
|
|
4
|
-
import {
|
|
4
|
+
import { bindsARun, loadBoundExecution, } from "../../runnerauth/bound-execution.js";
|
|
5
|
+
import { isClockedToken, TOKEN_TYPE_EXECUTION_SCOPED, } from "../../runnerauth/runnerauth.js";
|
|
5
6
|
import { encryptionKeyMissingMessage } from "./constants.js";
|
|
6
7
|
import { redactExecutionContextSecrets } from "./redact.js";
|
|
7
8
|
/**
|
|
@@ -45,12 +46,17 @@ async function runnerMayDecrypt(deps, ctx, ec) {
|
|
|
45
46
|
return false;
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return
|
|
49
|
+
const token = bearerToken(ctx);
|
|
50
|
+
const executionId = verifyRunnerToken(deps, token, ec);
|
|
51
|
+
if (executionId === undefined) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (!isClockedToken(token) && !(await runIsLive(deps, executionId))) {
|
|
55
|
+
deps.logger.debug("Run credential presented for a run that is over - redacting execution context secrets", { executionId });
|
|
56
|
+
return false;
|
|
52
57
|
}
|
|
53
|
-
|
|
58
|
+
deps.logger.debug("Scope-bound runner token presented - decrypting execution context secrets", { executionId });
|
|
59
|
+
return true;
|
|
54
60
|
}
|
|
55
61
|
/**
|
|
56
62
|
* Go verifyRunnerToken: the execution id the token is bound to when the
|
|
@@ -64,8 +70,7 @@ async function runnerMayDecrypt(deps, ctx, ec) {
|
|
|
64
70
|
* accepts exactly the execution_scoped credential lane — the caller-side
|
|
65
71
|
* trust statement the provider contract requires.
|
|
66
72
|
*/
|
|
67
|
-
function verifyRunnerToken(deps,
|
|
68
|
-
const token = bearerToken(ctx);
|
|
73
|
+
function verifyRunnerToken(deps, token, ec) {
|
|
69
74
|
if (token === "") {
|
|
70
75
|
return undefined;
|
|
71
76
|
}
|
|
@@ -86,6 +91,25 @@ function verifyRunnerToken(deps, ctx, ec) {
|
|
|
86
91
|
}
|
|
87
92
|
return tokenExecutionId;
|
|
88
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* A run credential's liveness: the bound execution exists, IS a run
|
|
96
|
+
* (`bindsARun` — a clockless token bound to a connect is a shape no mint
|
|
97
|
+
* produces, refused here and by the verifier through the one predicate)
|
|
98
|
+
* and is live (runnerauth/bound-execution.ts). A missing row is "not
|
|
99
|
+
* live" — the credential opens nothing. A store fault is an
|
|
100
|
+
* infrastructure fault, sanitized here as every direct handler does (the
|
|
101
|
+
* store-fault doctrine): an outage must not read as a redaction decision,
|
|
102
|
+
* and the same store just served the row this read is for.
|
|
103
|
+
*/
|
|
104
|
+
async function runIsLive(deps, executionId) {
|
|
105
|
+
try {
|
|
106
|
+
const execution = await loadBoundExecution(deps.store, executionId);
|
|
107
|
+
return (execution !== undefined && bindsARun(execution.kind) && execution.live);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw internalError(error, "failed to load the run credential's execution");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
89
113
|
/**
|
|
90
114
|
* The Bearer credential from the request's authorization header; empty
|
|
91
115
|
* when absent or differently shaped. The parsing shape (Go's exact
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-values-for-caller.js","sourceRoot":"","sources":["../../../src/domain/executioncontext/resolve-values-for-caller.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-values-for-caller.js","sourceRoot":"","sources":["../../../src/domain/executioncontext/resolve-values-for-caller.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* An account acting as itself — the ONE
|
|
3
|
-
* identity
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
2
|
+
* An account acting as itself — the ONE place server code builds the
|
|
3
|
+
* caller identity for a person it has resolved from a row rather than
|
|
4
|
+
* from the token that person presented. Two constructions, one shape:
|
|
5
|
+
* the account id is the principal, so the audit actor on every write
|
|
6
|
+
* names the account the way every other write names it, and email and
|
|
7
|
+
* display name ride along when the row knows them (the trusted-local
|
|
8
|
+
* identity's shape, pipeline/interceptors/auth.ts).
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
10
|
+
* `accountAsCaller(account)` — the IN-PROCESS lane: no issuer, no token,
|
|
11
|
+
* class `user`. Two consumers: the trusted-local boot ensure, which
|
|
12
|
+
* grants the operator ownership AS their account
|
|
13
|
+
* (domain/iampolicy/membership.ts), and the built-in schedule fire
|
|
14
|
+
* caller, which makes a fire act as the schedule's creator
|
|
15
|
+
* (authorization/schedule-fire-caller.ts). Both ride the in-process
|
|
16
|
+
* transport, whose interceptor stamps `origin: "in-process"` on top —
|
|
17
|
+
* the transport-trust marker is never set here.
|
|
16
18
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* `accountAsRunnerCaller(account, rawToken)` — the WIRE lane: the
|
|
20
|
+
* runner-subject verifier (runnerauth/runner-subject-verifier.ts) admits
|
|
21
|
+
* the bearer of a run credential as the human whose run it is. Class
|
|
22
|
+
* `runner`, because the Authorizer's lane admission and the memory
|
|
23
|
+
* capture gate must tell a runner acting as a person from the person
|
|
24
|
+
* (extensions/identity.ts names the class for exactly this), and the
|
|
25
|
+
* verified token carried, because the provider's capabilities re-read the
|
|
26
|
+
* binding off `rawToken` (the cloud's own pattern) — one HMAC, no store
|
|
27
|
+
* read. No issuer: the server signed it.
|
|
28
|
+
*
|
|
29
|
+
* Why not a token for the in-process lane: open source mints no
|
|
30
|
+
* credential for a person the server is composing a request for; the
|
|
31
|
+
* identity is what the propagation header carries, and every consumer
|
|
32
|
+
* that reads a subject off the raw token (`idpIdOf`) is reached only
|
|
33
|
+
* through `accountForCaller`, which resolves this identity by its id
|
|
34
|
+
* first and never asks the token. The same holds for the runner lane:
|
|
35
|
+
* our token carries no `sub`, and nothing downstream needs one.
|
|
22
36
|
*/
|
|
23
37
|
import type { IdentityAccount } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/api_pb";
|
|
24
38
|
import type { CallerIdentity } from "../../extensions/identity.js";
|
|
25
39
|
export declare function accountAsCaller(account: IdentityAccount): CallerIdentity;
|
|
40
|
+
export declare function accountAsRunnerCaller(account: IdentityAccount, rawToken: string): CallerIdentity;
|
|
26
41
|
//# sourceMappingURL=actor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../../src/domain/identityaccount/actor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"actor.d.ts","sourceRoot":"","sources":["../../../src/domain/identityaccount/actor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAC;AAEhG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAOxE;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,MAAM,GACf,cAAc,CAYhB"}
|
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
export function accountAsCaller(account) {
|
|
2
|
+
return {
|
|
3
|
+
...principalOf(account),
|
|
4
|
+
callerClass: "user",
|
|
5
|
+
issuer: "",
|
|
6
|
+
rawToken: "",
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function accountAsRunnerCaller(account, rawToken) {
|
|
10
|
+
if (rawToken === "") {
|
|
11
|
+
throw new Error("a runner caller carries the credential it presented — refusing to build one with none");
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
...principalOf(account),
|
|
15
|
+
callerClass: "runner",
|
|
16
|
+
issuer: "",
|
|
17
|
+
rawToken,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** The account id as principal, with the display identity the row knows. */
|
|
21
|
+
function principalOf(account) {
|
|
2
22
|
const accountId = account.metadata?.id ?? "";
|
|
3
23
|
if (accountId === "") {
|
|
4
24
|
throw new Error("identity account carries no id — refusing to build a caller for an empty principal");
|
|
@@ -7,9 +27,6 @@ export function accountAsCaller(account) {
|
|
|
7
27
|
const displayName = account.metadata?.name ?? "";
|
|
8
28
|
return {
|
|
9
29
|
identityId: accountId,
|
|
10
|
-
callerClass: "user",
|
|
11
|
-
issuer: "",
|
|
12
|
-
rawToken: "",
|
|
13
30
|
...(email !== "" ? { email } : {}),
|
|
14
31
|
...(displayName !== "" ? { displayName } : {}),
|
|
15
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actor.js","sourceRoot":"","sources":["../../../src/domain/identityaccount/actor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"actor.js","sourceRoot":"","sources":["../../../src/domain/identityaccount/actor.ts"],"names":[],"mappings":"AAwCA,MAAM,UAAU,eAAe,CAAC,OAAwB;IACtD,OAAO;QACL,GAAG,WAAW,CAAC,OAAO,CAAC;QACvB,WAAW,EAAE,MAAM;QACnB,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE,EAAE;KACb,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAAwB,EACxB,QAAgB;IAEhB,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,GAAG,WAAW,CAAC,OAAO,CAAC;QACvB,WAAW,EAAE,QAAQ;QACrB,MAAM,EAAE,EAAE;QACV,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,SAAS,WAAW,CAClB,OAAwB;IAExB,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;IACxC,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;IACjD,OAAO;QACL,UAAU,EAAE,SAAS;QACrB,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/C,CAAC;AACJ,CAAC"}
|
|
@@ -41,6 +41,19 @@
|
|
|
41
41
|
* cannot answer the same question two ways. A credential naming no
|
|
42
42
|
* subject is `undefined` with no second read: the store is never asked
|
|
43
43
|
* about "".
|
|
44
|
+
*
|
|
45
|
+
* The third reading is a ROW's creator stamp, `accountForStamp`: the
|
|
46
|
+
* account a `created_by.id` names, read the two ways a stamp has been
|
|
47
|
+
* written — as an account id (rows stamped since 3.15.0) and as the raw
|
|
48
|
+
* issuer subject (rows the 3.14.x verifiers stamped) — in
|
|
49
|
+
* `accountForCaller`'s order. Two lanes make the server act as the
|
|
50
|
+
* person a row names: the built-in schedule fire caller (a fire acts as
|
|
51
|
+
* the schedule's creator) and the runner-subject verifier (a run
|
|
52
|
+
* credential admits its bearer as the execution's creator). Stated here
|
|
53
|
+
* so they cannot resolve one stamp two ways; each decides for itself
|
|
54
|
+
* what "nobody" means (the fire caller's deterministic refusal, the
|
|
55
|
+
* verifier's liveness sentence), so this function answers `undefined`
|
|
56
|
+
* and never throws for it. The empty stamp is `undefined` with no read.
|
|
44
57
|
*/
|
|
45
58
|
import type { IdentityAccount } from "@stigmer/protos/ai/stigmer/iam/identityaccount/v1/api_pb";
|
|
46
59
|
import type { CallerIdentity } from "../../extensions/identity.js";
|
|
@@ -56,4 +69,10 @@ export declare function identityIdForSubject(accounts: AccountsBySubject, subjec
|
|
|
56
69
|
* Faults propagate as they are — the caller decides the wire shape.
|
|
57
70
|
*/
|
|
58
71
|
export declare function accountForCaller(accounts: AccountsByCaller, caller: CallerIdentity): Promise<IdentityAccount | undefined>;
|
|
72
|
+
/**
|
|
73
|
+
* The account a row's creator stamp names, or `undefined` when it names
|
|
74
|
+
* nobody (the laptop's `"system"`, a trusted-local email, a deleted
|
|
75
|
+
* account, the empty stamp). Faults propagate as they are.
|
|
76
|
+
*/
|
|
77
|
+
export declare function accountForStamp(accounts: AccountsByCaller, stamp: string): Promise<IdentityAccount | undefined>;
|
|
59
78
|
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/domain/identityaccount/resolve.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/domain/identityaccount/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAC;AAEhG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,uFAAuF;AACvF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;AAEhF,mFAAmF;AACnF,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,oBAAoB,EACpB,UAAU,GAAG,mBAAmB,CACjC,CAAC;AAEF,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAUtC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAQtC"}
|
|
@@ -26,4 +26,16 @@ export async function accountForCaller(accounts, caller) {
|
|
|
26
26
|
}
|
|
27
27
|
return accounts.findDirectByIdpId(subject);
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* The account a row's creator stamp names, or `undefined` when it names
|
|
31
|
+
* nobody (the laptop's `"system"`, a trusted-local email, a deleted
|
|
32
|
+
* account, the empty stamp). Faults propagate as they are.
|
|
33
|
+
*/
|
|
34
|
+
export async function accountForStamp(accounts, stamp) {
|
|
35
|
+
if (stamp === "") {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return ((await accounts.findById(stamp)) ??
|
|
39
|
+
(await accounts.findDirectByIdpId(stamp)));
|
|
40
|
+
}
|
|
29
41
|
//# sourceMappingURL=resolve.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/domain/identityaccount/resolve.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/domain/identityaccount/resolve.ts"],"names":[],"mappings":"AA4DA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAYzC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAA2B,EAC3B,OAAe;IAEf,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC1D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC;IACtC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,iCAAiC,OAAO,wDAAwD,CACjG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA0B,EAC1B,MAAsB;IAEtB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACxD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,QAAQ,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAA0B,EAC1B,KAAa;IAEb,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,CACL,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC,MAAM,QAAQ,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAC1C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** One connect's execution id: the server it discovers plus eight hex of entropy per attempt. */
|
|
2
|
+
export declare function newConnectExecutionId(mcpServerId: string): string;
|
|
3
|
+
/** Whether `executionId` is a connect's — the runner-credential lane's recognition of the third binding. */
|
|
4
|
+
export declare function isConnectExecutionId(executionId: string): boolean;
|
|
5
|
+
//# sourceMappingURL=connect-execution-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-execution-id.d.ts","sourceRoot":"","sources":["../../../src/domain/mcpserver/connect-execution-id.ts"],"names":[],"mappings":"AAyBA,iGAAiG;AACjG,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,4GAA4G;AAC5G,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAEjE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The synthetic execution id of an MCP connect — the ONE home for its
|
|
3
|
+
* shape, built here by the connect lane and recognized here by the
|
|
4
|
+
* runner-credential lane, so the two can never drift apart.
|
|
5
|
+
*
|
|
6
|
+
* A connect is not an execution: it has no AgentExecution or
|
|
7
|
+
* WorkflowExecution row. What it has is an ephemeral ExecutionContext
|
|
8
|
+
* (connect.ts `createConnectExecutionContext`) whose `spec.execution_id`
|
|
9
|
+
* must name SOMETHING for the decrypt lane's binding check
|
|
10
|
+
* (executioncontext/resolve-values-for-caller.ts: the token's
|
|
11
|
+
* `execution_id` claim must equal the EC's), and this id is that
|
|
12
|
+
* something — an id that names no resource kind, so the contract's
|
|
13
|
+
* `kind_meta` prefix table (pipeline/apiresource-meta.ts) cannot mistake
|
|
14
|
+
* it for a row. The runner-credential lane reads it the other way round
|
|
15
|
+
* (runnerauth/bound-execution.ts `boundExecutionKindOf`): an id this
|
|
16
|
+
* predicate recognizes is a connect binding, resolved through the EC row
|
|
17
|
+
* whose `spec.execution_id` it is. Keep the builder and the predicate
|
|
18
|
+
* together; a second copy of the prefix anywhere would be the drift this
|
|
19
|
+
* module exists to prevent.
|
|
20
|
+
*/
|
|
21
|
+
import { randomUUID } from "node:crypto";
|
|
22
|
+
/** The prefix every connect execution id carries — no resource kind's id starts with it. */
|
|
23
|
+
const CONNECT_EXECUTION_ID_PREFIX = "connect-";
|
|
24
|
+
/** One connect's execution id: the server it discovers plus eight hex of entropy per attempt. */
|
|
25
|
+
export function newConnectExecutionId(mcpServerId) {
|
|
26
|
+
return `${CONNECT_EXECUTION_ID_PREFIX}${mcpServerId}-${randomUUID().slice(0, 8)}`;
|
|
27
|
+
}
|
|
28
|
+
/** Whether `executionId` is a connect's — the runner-credential lane's recognition of the third binding. */
|
|
29
|
+
export function isConnectExecutionId(executionId) {
|
|
30
|
+
return executionId.startsWith(CONNECT_EXECUTION_ID_PREFIX);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=connect-execution-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-execution-id.js","sourceRoot":"","sources":["../../../src/domain/mcpserver/connect-execution-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,4FAA4F;AAC5F,MAAM,2BAA2B,GAAG,UAAU,CAAC;AAE/C,iGAAiG;AACjG,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,OAAO,GAAG,2BAA2B,GAAG,WAAW,IAAI,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACpF,CAAC;AAED,4GAA4G;AAC5G,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,OAAO,WAAW,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -89,9 +89,19 @@ export interface ConnectEnvironmentReader {
|
|
|
89
89
|
/**
|
|
90
90
|
* The ExecutionContext lifecycle surface for the ephemeral connect EC —
|
|
91
91
|
* Go's downstream executioncontext client (create + delete).
|
|
92
|
+
*
|
|
93
|
+
* `create` takes the connecting caller and the composition creates the
|
|
94
|
+
* row AS THAT PERSON (boot/inprocess.ts, the `asCaller` lane of ruling
|
|
95
|
+
* R5), never under the internal class: the row's creator stamp is what
|
|
96
|
+
* the runner-subject verifier resolves the connect's person from when
|
|
97
|
+
* the runner presents the connect token under the built-in posture
|
|
98
|
+
* (runnerauth/bound-execution.ts, the `mcp-connect` binding). A row
|
|
99
|
+
* stamped `internal` would name nobody, and the credentialed connect
|
|
100
|
+
* would be refused at identity on every enforcing self-host. `delete`
|
|
101
|
+
* stays the server's own act: the row is the lane's, whoever asked.
|
|
92
102
|
*/
|
|
93
103
|
export interface ConnectExecutionContextClient {
|
|
94
|
-
create(executionContext: MessageInitShape<typeof ExecutionContextSchema
|
|
104
|
+
create(executionContext: MessageInitShape<typeof ExecutionContextSchema>, caller: CallerIdentity): Promise<ExecutionContext>;
|
|
95
105
|
delete(input: MessageInitShape<typeof ApiResourceDeleteInputSchema>): Promise<ExecutionContext>;
|
|
96
106
|
}
|
|
97
107
|
/**
|
|
@@ -156,8 +166,24 @@ export declare function connect(deps: McpServerConnectDeps, input: ConnectInput,
|
|
|
156
166
|
* read the caller's grant and secrets, which a background task has no
|
|
157
167
|
* request context to do (the same constraint that scopes
|
|
158
168
|
* startBestEffortConnect to env-less servers).
|
|
169
|
+
*
|
|
170
|
+
* A connect's discovery runs on the runner with TWO credentials, and the
|
|
171
|
+
* split is deliberate. The runner's own process credential reads the
|
|
172
|
+
* McpServer's metadata — under the built-in posture that credential is
|
|
173
|
+
* the operator's API key, and the operator is an organization admin
|
|
174
|
+
* (deploy/helm/stigmer: the signed-in operator mints the runner's key),
|
|
175
|
+
* whom the model makes an owner of every McpServer in the organization
|
|
176
|
+
* (authorization/model/mcp_server.ts), so a member's private server is
|
|
177
|
+
* readable. The connect token minted below reads the SECRETS: it is
|
|
178
|
+
* bound to this connect's ExecutionContext, and under the built-in
|
|
179
|
+
* posture the runner-subject verifier resolves its bearer to the person
|
|
180
|
+
* that row was created by — which is why the row is created as `identity`
|
|
181
|
+
* and not as the server. The end state where every RPC of a discovery
|
|
182
|
+
* acts as the person (the cloud's connect-sandbox shape) needs a row an
|
|
183
|
+
* env-less connect would also create; it creates none today, so that is
|
|
184
|
+
* a design act of its own, not a widening to make here.
|
|
159
185
|
*/
|
|
160
|
-
export declare function prepareConnect(deps: McpServerConnectDeps, mcpServer: McpServer, input: ConnectInput): Promise<PreparedConnect>;
|
|
186
|
+
export declare function prepareConnect(deps: McpServerConnectDeps, mcpServer: McpServer, input: ConnectInput, identity: CallerIdentity): Promise<PreparedConnect>;
|
|
161
187
|
/**
|
|
162
188
|
* Removes the ephemeral ExecutionContext after the connect workflow
|
|
163
189
|
* completes (Go deleteConnectExecutionContext). Failures are logged but
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/domain/mcpserver/connect.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAQ,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../../src/domain/mcpserver/connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { create } from "@bufbuild/protobuf";
|
|
18
18
|
import { Code, ConnectError } from "@connectrpc/connect";
|
|
19
|
-
import { randomUUID } from "node:crypto";
|
|
20
19
|
import { EnvironmentValueSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
|
|
21
20
|
import { ExecutionContextSchema } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/api_pb";
|
|
22
21
|
import { ExecutionValueSchema } from "@stigmer/protos/ai/stigmer/agentic/executioncontext/v1/spec_pb";
|
|
@@ -29,6 +28,7 @@ import { failedPreconditionError, internalError, notFoundError, invalidArgumentE
|
|
|
29
28
|
import { TOKEN_TYPE_EXECUTION_SCOPED } from "../../runnerauth/runnerauth.js";
|
|
30
29
|
import { ResourceNotFoundError } from "../../store/interface.js";
|
|
31
30
|
import { resolveOAuthAppRef } from "../oauthapp/refresolution.js";
|
|
31
|
+
import { newConnectExecutionId } from "./connect-execution-id.js";
|
|
32
32
|
import { persistConnectFailure, persistConnectResult, persistConnectStarting, } from "./connect-status.js";
|
|
33
33
|
import { refreshTokenIfExpired } from "./oauth/refresh.js";
|
|
34
34
|
import { TOKEN_AUTH_METHOD_BASIC, TOKEN_AUTH_METHOD_POST, } from "./oauth/token.js";
|
|
@@ -125,7 +125,7 @@ export async function connect(deps, input, identity) {
|
|
|
125
125
|
// McpServerConnectHandler order (load-before-authorize, stigmer#224).
|
|
126
126
|
// C2 Stage 4.
|
|
127
127
|
await authorizeDirect(McpServerCommandController.method.connect, deps.authorizer, identity, input);
|
|
128
|
-
const prepared = await prepareConnect(deps, mcpServer, input);
|
|
128
|
+
const prepared = await prepareConnect(deps, mcpServer, input, identity);
|
|
129
129
|
try {
|
|
130
130
|
let run;
|
|
131
131
|
try {
|
|
@@ -200,8 +200,24 @@ export async function connect(deps, input, identity) {
|
|
|
200
200
|
* read the caller's grant and secrets, which a background task has no
|
|
201
201
|
* request context to do (the same constraint that scopes
|
|
202
202
|
* startBestEffortConnect to env-less servers).
|
|
203
|
+
*
|
|
204
|
+
* A connect's discovery runs on the runner with TWO credentials, and the
|
|
205
|
+
* split is deliberate. The runner's own process credential reads the
|
|
206
|
+
* McpServer's metadata — under the built-in posture that credential is
|
|
207
|
+
* the operator's API key, and the operator is an organization admin
|
|
208
|
+
* (deploy/helm/stigmer: the signed-in operator mints the runner's key),
|
|
209
|
+
* whom the model makes an owner of every McpServer in the organization
|
|
210
|
+
* (authorization/model/mcp_server.ts), so a member's private server is
|
|
211
|
+
* readable. The connect token minted below reads the SECRETS: it is
|
|
212
|
+
* bound to this connect's ExecutionContext, and under the built-in
|
|
213
|
+
* posture the runner-subject verifier resolves its bearer to the person
|
|
214
|
+
* that row was created by — which is why the row is created as `identity`
|
|
215
|
+
* and not as the server. The end state where every RPC of a discovery
|
|
216
|
+
* acts as the person (the cloud's connect-sandbox shape) needs a row an
|
|
217
|
+
* env-less connect would also create; it creates none today, so that is
|
|
218
|
+
* a design act of its own, not a widening to make here.
|
|
203
219
|
*/
|
|
204
|
-
export async function prepareConnect(deps, mcpServer, input) {
|
|
220
|
+
export async function prepareConnect(deps, mcpServer, input, identity) {
|
|
205
221
|
const mcpServerId = mcpServer.metadata?.id ?? "";
|
|
206
222
|
const callerOrg = input.org;
|
|
207
223
|
// Pre-flight: refresh expired OAuth tokens before env resolution. Only
|
|
@@ -211,8 +227,8 @@ export async function prepareConnect(deps, mcpServer, input) {
|
|
|
211
227
|
if (Object.keys(input.runtimeEnv).length === 0) {
|
|
212
228
|
await refreshOAuthTokenIfNeeded(deps, mcpServer, callerOrg);
|
|
213
229
|
}
|
|
214
|
-
const executionId =
|
|
215
|
-
const ecResourceId = await createConnectExecutionContext(deps, mcpServer, executionId, callerOrg, input.runtimeEnv);
|
|
230
|
+
const executionId = newConnectExecutionId(mcpServerId);
|
|
231
|
+
const ecResourceId = await createConnectExecutionContext(deps, mcpServer, executionId, callerOrg, input.runtimeEnv, identity);
|
|
216
232
|
const workflowInput = {
|
|
217
233
|
mcp_server_id: mcpServerId,
|
|
218
234
|
...(ecResourceId !== "" ? { execution_context_id: executionId } : {}),
|
|
@@ -254,8 +270,12 @@ export async function prepareConnect(deps, mcpServer, input) {
|
|
|
254
270
|
* sources: OAuth-managed variables from the grant's managed environment,
|
|
255
271
|
* the remainder from the user's personal environment. Returns "" when the
|
|
256
272
|
* MCP server has no env declarations and no runtime_env.
|
|
273
|
+
*
|
|
274
|
+
* The row is created as `caller`, the person connecting (see the
|
|
275
|
+
* ConnectExecutionContextClient doc): its creator stamp is the connect
|
|
276
|
+
* token's person under the built-in posture.
|
|
257
277
|
*/
|
|
258
|
-
async function createConnectExecutionContext(deps, mcpServer, executionId, callerOrg, runtimeEnv) {
|
|
278
|
+
async function createConnectExecutionContext(deps, mcpServer, executionId, callerOrg, runtimeEnv, caller) {
|
|
259
279
|
let ecData;
|
|
260
280
|
if (Object.keys(runtimeEnv).length > 0) {
|
|
261
281
|
ecData = runtimeEnv;
|
|
@@ -300,7 +320,7 @@ async function createConnectExecutionContext(deps, mcpServer, executionId, calle
|
|
|
300
320
|
executionId,
|
|
301
321
|
data: ecData,
|
|
302
322
|
},
|
|
303
|
-
}));
|
|
323
|
+
}), caller);
|
|
304
324
|
}
|
|
305
325
|
catch (error) {
|
|
306
326
|
throw internalError(error, "failed to create connect ExecutionContext");
|