@stigmer/server 3.15.0 → 3.15.2-dev.20260913223433
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/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +23 -2
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/config.d.ts +14 -0
- package/dist/boot/config.d.ts.map +1 -1
- package/dist/boot/config.js +1 -0
- package/dist/boot/config.js.map +1 -1
- package/dist/domain/agentchannel/controller.js +15 -26
- package/dist/domain/agentchannel/controller.js.map +1 -1
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +3 -2
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentexecution/steps.d.ts +20 -8
- package/dist/domain/agentexecution/steps.d.ts.map +1 -1
- package/dist/domain/agentexecution/steps.js +32 -12
- package/dist/domain/agentexecution/steps.js.map +1 -1
- package/dist/domain/agentinstance/steps.d.ts.map +1 -1
- package/dist/domain/agentinstance/steps.js +9 -22
- package/dist/domain/agentinstance/steps.js.map +1 -1
- package/dist/domain/agentshare/controller.js +15 -26
- package/dist/domain/agentshare/controller.js.map +1 -1
- package/dist/domain/environment/controller.js +8 -10
- package/dist/domain/environment/controller.js.map +1 -1
- package/dist/domain/memory/steps.d.ts.map +1 -1
- package/dist/domain/memory/steps.js +5 -10
- package/dist/domain/memory/steps.js.map +1 -1
- package/dist/domain/schedule/controller.js +15 -24
- package/dist/domain/schedule/controller.js.map +1 -1
- package/dist/domain/session/steps.d.ts.map +1 -1
- package/dist/domain/session/steps.js +8 -4
- package/dist/domain/session/steps.js.map +1 -1
- package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
- package/dist/domain/workflowexecution/controller.js +12 -6
- package/dist/domain/workflowexecution/controller.js.map +1 -1
- package/dist/domain/workflowexecution/list-pending-approvals.d.ts.map +1 -1
- package/dist/domain/workflowexecution/list-pending-approvals.js +19 -8
- package/dist/domain/workflowexecution/list-pending-approvals.js.map +1 -1
- package/dist/domain/workflowinstance/controller.js +6 -13
- package/dist/domain/workflowinstance/controller.js.map +1 -1
- package/dist/extensions/list-read-scope.d.ts +31 -4
- package/dist/extensions/list-read-scope.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.js +12 -10
- package/dist/extensions/list-read-scope.js.map +1 -1
- package/dist/transport/console/handler.d.ts +22 -5
- package/dist/transport/console/handler.d.ts.map +1 -1
- package/dist/transport/console/handler.js +53 -24
- package/dist/transport/console/handler.js.map +1 -1
- package/package.json +4 -4
- package/src/boot/__tests__/auth-enabled-composition.test.ts +49 -3
- package/src/boot/__tests__/config.test.ts +41 -3
- package/src/boot/compose.ts +30 -2
- package/src/boot/config.ts +15 -0
- package/src/domain/agentchannel/controller.ts +23 -31
- package/src/domain/agentexecution/controller.ts +11 -5
- package/src/domain/agentexecution/steps.ts +47 -22
- package/src/domain/agentinstance/steps.ts +17 -26
- package/src/domain/agentshare/controller.ts +23 -31
- package/src/domain/environment/controller.ts +12 -12
- package/src/domain/memory/steps.ts +6 -12
- package/src/domain/schedule/controller.ts +25 -33
- package/src/domain/session/steps.ts +24 -11
- package/src/domain/workflowexecution/controller.ts +32 -26
- package/src/domain/workflowexecution/list-pending-approvals.ts +37 -16
- package/src/domain/workflowinstance/controller.ts +11 -18
- package/src/extensions/__tests__/list-read-scope.test.ts +29 -7
- package/src/extensions/list-read-scope.ts +37 -12
- package/src/transport/console/__tests__/handler.test.ts +93 -23
- package/src/transport/console/__tests__/resolver.test.ts +6 -0
- package/src/transport/console/handler.ts +84 -30
|
@@ -7,13 +7,30 @@ import type { ConsoleAssets } from "./assets.js";
|
|
|
7
7
|
* of RPC path shapes belongs to this module.
|
|
8
8
|
*/
|
|
9
9
|
export declare function consoleLaneEligible(request: LaneRequest): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* How the console this lane serves signs in — the server's authentication
|
|
12
|
+
* posture as the console needs to hear it (20260913.02 sp.console-login).
|
|
13
|
+
* A modeled state, never a nullable: "no issuer configured" and "forgot to
|
|
14
|
+
* wire the posture" must stay distinguishable at the call site.
|
|
15
|
+
*
|
|
16
|
+
* Under `oidc`, `consoleClientId` is the PUBLIC client the operator
|
|
17
|
+
* registered for the browser's PKCE flow, or "" when they have not
|
|
18
|
+
* (Q-CL-1): the lane publishes that truth as-is and the console refuses
|
|
19
|
+
* with copy that names the knob (Q-CL-2), while the composition root has
|
|
20
|
+
* already WARNed at wiring time. Emitting `disabled` instead would send
|
|
21
|
+
* the console into every RPC tokenless, to fail with a worse message.
|
|
22
|
+
*/
|
|
23
|
+
export type ConsoleSignInPosture = {
|
|
24
|
+
readonly posture: "trusted-local";
|
|
25
|
+
} | {
|
|
26
|
+
readonly posture: "oidc";
|
|
27
|
+
readonly issuer: string;
|
|
28
|
+
readonly audience: string;
|
|
29
|
+
readonly consoleClientId: string;
|
|
30
|
+
};
|
|
10
31
|
export interface ConsoleLaneOptions {
|
|
11
32
|
readonly assets: ConsoleAssets;
|
|
12
|
-
|
|
13
|
-
* Fallback port for the synthesized apiUrl when a request carries no
|
|
14
|
-
* Host/:authority (technically possible on HTTP/1.0-style clients).
|
|
15
|
-
*/
|
|
16
|
-
readonly grpcPort: number;
|
|
33
|
+
readonly signIn: ConsoleSignInPosture;
|
|
17
34
|
readonly logger: Logger;
|
|
18
35
|
}
|
|
19
36
|
export declare function createConsoleLane(options: ConsoleLaneOptions): LaneHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/transport/console/handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/transport/console/handler.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAkBjD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAYjE;AAQD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GACrC;IACE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC,CAAC;AAEN,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAiD1E"}
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
* nginx-equivalence-gated); this module owns the HTTP half: the lane
|
|
7
7
|
* guard, header policy, config synthesis, and file streaming.
|
|
8
8
|
*
|
|
9
|
+
* /config.json is also how the served console learns to sign in
|
|
10
|
+
* (20260913.02 sp.console-login; stigmer#924): the composition root hands
|
|
11
|
+
* the lane the server's authentication posture (ConsoleSignInPosture) and
|
|
12
|
+
* the lane publishes it in the console's own vocabulary — the OIDC
|
|
13
|
+
* issuer, audience and the console's PKCE client id under the posture,
|
|
14
|
+
* `disabled` under trusted local.
|
|
15
|
+
*
|
|
9
16
|
* Lane guard (consoleLaneEligible): the lane claims GET/HEAD only — RPC
|
|
10
17
|
* traffic is POST on service-qualified paths, and OPTIONS preflights keep
|
|
11
18
|
* flowing to the RPC lane's CORS handling — and it never claims:
|
|
@@ -63,14 +70,17 @@ function isServiceShapedPath(pathname) {
|
|
|
63
70
|
return segments.length === 2 && (segments[0] ?? "").includes(".");
|
|
64
71
|
}
|
|
65
72
|
export function createConsoleLane(options) {
|
|
66
|
-
const { assets,
|
|
73
|
+
const { assets, signIn, logger } = options;
|
|
74
|
+
// The console's runtime config is a pure function of the posture: one
|
|
75
|
+
// body, built once, served on every request.
|
|
76
|
+
const configJsonBody = JSON.stringify(consoleRuntimeConfig(signIn));
|
|
67
77
|
return (request, response) => {
|
|
68
78
|
const url = request.url ?? "";
|
|
69
79
|
const queryStart = url.indexOf("?");
|
|
70
80
|
const rawPath = queryStart === -1 ? url : url.slice(0, queryStart);
|
|
71
81
|
const query = queryStart === -1 ? "" : url.slice(queryStart);
|
|
72
82
|
if (rawPath === CONFIG_JSON_PATH) {
|
|
73
|
-
serveConfigJson(request, response,
|
|
83
|
+
serveConfigJson(request, response, configJsonBody);
|
|
74
84
|
return;
|
|
75
85
|
}
|
|
76
86
|
let pathname;
|
|
@@ -108,29 +118,48 @@ export function createConsoleLane(options) {
|
|
|
108
118
|
}
|
|
109
119
|
/**
|
|
110
120
|
* The runtime config the cloud container's entrypoint.sh generates from
|
|
111
|
-
* env
|
|
112
|
-
* the nginx entrypoint script is not ported).
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
121
|
+
* env, synthesized here from the server's own knowledge instead (DD-012:
|
|
122
|
+
* the nginx entrypoint script is not ported). The field names are the
|
|
123
|
+
* console's loader's (client-apps/web/src/config/runtime-config.ts).
|
|
124
|
+
*
|
|
125
|
+
* `apiUrl` is the empty string, which the console reads as "my own
|
|
126
|
+
* origin" — the rule its `appUrl` already follows (20260913.02 Q-CL-3).
|
|
127
|
+
* This lane and the RPC lane share one port, so the console can never
|
|
128
|
+
* need a different origin, and it makes the answer right behind a
|
|
129
|
+
* TLS-terminating proxy without trusting x-forwarded-proto: the earlier
|
|
130
|
+
* Host-derived `http://<host>` sent an https-loaded console to an http
|
|
131
|
+
* API and died on mixed content.
|
|
132
|
+
*
|
|
133
|
+
* Every value here is public metadata: an OIDC issuer URL, an audience
|
|
134
|
+
* string and a PKCE client id are what a browser is handed by design.
|
|
118
135
|
*/
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
function consoleRuntimeConfig(signIn) {
|
|
137
|
+
switch (signIn.posture) {
|
|
138
|
+
case "trusted-local":
|
|
139
|
+
return {
|
|
140
|
+
apiUrl: "",
|
|
141
|
+
appUrl: "",
|
|
142
|
+
authMode: "disabled",
|
|
143
|
+
oidcIssuer: "",
|
|
144
|
+
oidcClientId: "",
|
|
145
|
+
oidcAudience: "",
|
|
146
|
+
};
|
|
147
|
+
case "oidc":
|
|
148
|
+
return {
|
|
149
|
+
apiUrl: "",
|
|
150
|
+
appUrl: "",
|
|
151
|
+
authMode: "oidc",
|
|
152
|
+
oidcIssuer: signIn.issuer,
|
|
153
|
+
oidcClientId: signIn.consoleClientId,
|
|
154
|
+
oidcAudience: signIn.audience,
|
|
155
|
+
};
|
|
156
|
+
default: {
|
|
157
|
+
const exhaustive = signIn;
|
|
158
|
+
throw new Error(`unhandled sign-in posture ${String(exhaustive)}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function serveConfigJson(request, response, body) {
|
|
134
163
|
response.statusCode = 200;
|
|
135
164
|
response.setHeader("Content-Type", "application/json");
|
|
136
165
|
response.setHeader("Cache-Control", CONFIG_JSON_CACHE_CONTROL);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/transport/console/handler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/transport/console/handler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/server",
|
|
3
|
-
"version": "3.15.
|
|
3
|
+
"version": "3.15.2-dev.20260913223433",
|
|
4
4
|
"description": "The Stigmer OSS control plane as a composable library: composeServer, the extension registry and the driver seams a composition builds on. The self-contained deployable of the same server is @stigmer/server-slim.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"@connectrpc/connect-node": "^2.0.0",
|
|
63
63
|
"@kubernetes/client-node": "2.0.0",
|
|
64
64
|
"@opentelemetry/api": "^1.9.0",
|
|
65
|
-
"@stigmer/protos": "3.15.
|
|
66
|
-
"@stigmer/temporal-codecs": "3.15.
|
|
67
|
-
"@stigmer/zip-structure": "3.15.
|
|
65
|
+
"@stigmer/protos": "3.15.2-dev.20260913223433",
|
|
66
|
+
"@stigmer/temporal-codecs": "3.15.2-dev.20260913223433",
|
|
67
|
+
"@stigmer/zip-structure": "3.15.2-dev.20260913223433",
|
|
68
68
|
"@temporalio/activity": "1.16.2",
|
|
69
69
|
"@temporalio/client": "1.16.2",
|
|
70
70
|
"@temporalio/common": "1.16.2",
|
|
@@ -21,9 +21,17 @@
|
|
|
21
21
|
* the issuer's userinfo profile; from then on the verifier resolves
|
|
22
22
|
* the subject to the account id and API keys minted before OR after
|
|
23
23
|
* provisioning answer whoAmI with the owner's account; no operator
|
|
24
|
-
* account exists under the posture
|
|
24
|
+
* account exists under the posture;
|
|
25
|
+
* 7. (20260913.02, sp.console-login) the console the server serves is
|
|
26
|
+
* told the posture through /config.json — the issuer and audience
|
|
27
|
+
* this composition runs under, with the console client id the
|
|
28
|
+
* operator did NOT register here left empty — and the composition
|
|
29
|
+
* root WARNs at wiring time that the served console cannot sign in
|
|
30
|
+
* (Q-CL-2), the STIGMER_OAUTH_REDIRECT_URI precedent. Proven through
|
|
31
|
+
* compose.ts with STIGMER_CONSOLE_DIR at a fixture export, not
|
|
32
|
+
* through the lane alone (handler.test.ts covers that).
|
|
25
33
|
*/
|
|
26
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
34
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
27
35
|
import { tmpdir } from "node:os";
|
|
28
36
|
import path from "node:path";
|
|
29
37
|
import { createServer } from "node:http";
|
|
@@ -75,6 +83,9 @@ let port: number;
|
|
|
75
83
|
// the raw sub. The identity-account arms prove that stamp resolves to the
|
|
76
84
|
// owner's account once one exists (20260911.11 A1's derived id).
|
|
77
85
|
let keyMintedBeforeProvisioning: string;
|
|
86
|
+
// Every WARN the composition root logged while wiring — the console
|
|
87
|
+
// sign-in arm (7) reads it.
|
|
88
|
+
const warnings: string[] = [];
|
|
78
89
|
|
|
79
90
|
function bearer(token: string): Interceptor {
|
|
80
91
|
return (next) => (request) => {
|
|
@@ -177,6 +188,10 @@ beforeAll(async () => {
|
|
|
177
188
|
issuer = `http://127.0.0.1:${address.port}`;
|
|
178
189
|
|
|
179
190
|
dir = mkdtempSync(path.join(tmpdir(), "auth-enabled-test-"));
|
|
191
|
+
// The smallest export the console lane discovers: the app shell alone.
|
|
192
|
+
const consoleDir = path.join(dir, "console");
|
|
193
|
+
mkdirSync(consoleDir, { recursive: true });
|
|
194
|
+
writeFileSync(path.join(consoleDir, "index.html"), "<html>app shell</html>");
|
|
180
195
|
server = await composeServer({
|
|
181
196
|
config: loadConfig({
|
|
182
197
|
STIGMER_MODEL_REGISTRY_REFRESH: "off",
|
|
@@ -186,8 +201,18 @@ beforeAll(async () => {
|
|
|
186
201
|
ARTIFACT_LOCAL_BASE_PATH: path.join(dir, "artifacts"),
|
|
187
202
|
STIGMER_OIDC_ISSUER: issuer,
|
|
188
203
|
STIGMER_OIDC_AUDIENCE: AUDIENCE,
|
|
204
|
+
STIGMER_CONSOLE_DIR: consoleDir,
|
|
205
|
+
}),
|
|
206
|
+
logger: createLogger({
|
|
207
|
+
level: "warn",
|
|
208
|
+
pretty: false,
|
|
209
|
+
write: (line) => {
|
|
210
|
+
const entry = JSON.parse(line) as { level?: string; message?: string };
|
|
211
|
+
if (entry.level === "warn" && entry.message !== undefined) {
|
|
212
|
+
warnings.push(entry.message);
|
|
213
|
+
}
|
|
214
|
+
},
|
|
189
215
|
}),
|
|
190
|
-
logger: createLogger({ level: "error", pretty: false, write: () => {} }),
|
|
191
216
|
portOverride: 0,
|
|
192
217
|
host: "127.0.0.1",
|
|
193
218
|
});
|
|
@@ -236,6 +261,27 @@ describe("the require-authentication posture on the wire", () => {
|
|
|
236
261
|
});
|
|
237
262
|
});
|
|
238
263
|
|
|
264
|
+
describe("the console the server serves is told the posture (20260913.02, sp.console-login)", () => {
|
|
265
|
+
it("/config.json carries the issuer and audience this composition verifies against, with the unregistered console client id empty", async () => {
|
|
266
|
+
const response = await fetch(`http://127.0.0.1:${port}/config.json`);
|
|
267
|
+
expect(response.status).toBe(200);
|
|
268
|
+
expect(await response.json()).toEqual({
|
|
269
|
+
apiUrl: "",
|
|
270
|
+
appUrl: "",
|
|
271
|
+
authMode: "oidc",
|
|
272
|
+
oidcIssuer: issuer,
|
|
273
|
+
oidcClientId: "",
|
|
274
|
+
oidcAudience: AUDIENCE,
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("the composition root WARNs at wiring time that the served console cannot sign in without STIGMER_OIDC_CONSOLE_CLIENT_ID (Q-CL-2)", () => {
|
|
279
|
+
expect(warnings).toContainEqual(
|
|
280
|
+
expect.stringContaining("STIGMER_OIDC_CONSOLE_CLIENT_ID"),
|
|
281
|
+
);
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
239
285
|
describe("the full credential loop (OIDC login → API key → revocation)", () => {
|
|
240
286
|
let apiKeyPlaintext: string;
|
|
241
287
|
let apiKeyId: string;
|
|
@@ -59,15 +59,53 @@ describe("loadConfig", () => {
|
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
it("reads an explicit ARTIFACT_HTTP_HOST (the container override)", () => {
|
|
62
|
-
expect(
|
|
63
|
-
|
|
64
|
-
)
|
|
62
|
+
expect(loadConfig({ ARTIFACT_HTTP_HOST: "0.0.0.0" }).artifactHttpHost).toBe(
|
|
63
|
+
"0.0.0.0",
|
|
64
|
+
);
|
|
65
65
|
// Empty string is absent, per the Go getEnvString leniency.
|
|
66
66
|
expect(loadConfig({ ARTIFACT_HTTP_HOST: "" }).artifactHttpHost).toBe(
|
|
67
67
|
"127.0.0.1",
|
|
68
68
|
);
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
+
// 20260913.02 (sp.console-login, Q-CL-1): the console's public PKCE client
|
|
72
|
+
// id is lenient on purpose — a CLI-only self-host that set the issuer
|
|
73
|
+
// before this knob existed must keep booting on upgrade, and the served
|
|
74
|
+
// console reports the gap itself (Q-CL-2).
|
|
75
|
+
describe("STIGMER_OIDC_CONSOLE_CLIENT_ID (the console's sign-in client)", () => {
|
|
76
|
+
const OIDC = {
|
|
77
|
+
STIGMER_OIDC_ISSUER: "https://auth.example.com/realms/main",
|
|
78
|
+
STIGMER_OIDC_AUDIENCE: "https://stigmer.example.com/",
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
it("is empty when absent, and the issuer alone still boots", () => {
|
|
82
|
+
expect(loadConfig(OIDC).oidcConsoleClientId).toBe("");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("reads the explicit value", () => {
|
|
86
|
+
expect(
|
|
87
|
+
loadConfig({
|
|
88
|
+
...OIDC,
|
|
89
|
+
STIGMER_OIDC_CONSOLE_CLIENT_ID: "stigmer-console",
|
|
90
|
+
}).oidcConsoleClientId,
|
|
91
|
+
).toBe("stigmer-console");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("treats an empty string as absent (Go's getEnvString)", () => {
|
|
95
|
+
expect(
|
|
96
|
+
loadConfig({ ...OIDC, STIGMER_OIDC_CONSOLE_CLIENT_ID: "" })
|
|
97
|
+
.oidcConsoleClientId,
|
|
98
|
+
).toBe("");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("is carried even without an issuer — the posture, not this knob, decides whether it is used", () => {
|
|
102
|
+
expect(
|
|
103
|
+
loadConfig({ STIGMER_OIDC_CONSOLE_CLIENT_ID: "stigmer-console" })
|
|
104
|
+
.oidcConsoleClientId,
|
|
105
|
+
).toBe("stigmer-console");
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
71
109
|
it("disables the model-registry refresh only for the literal 'off'", () => {
|
|
72
110
|
expect(
|
|
73
111
|
loadConfig({ STIGMER_MODEL_REGISTRY_REFRESH: "off" })
|
package/src/boot/compose.ts
CHANGED
|
@@ -161,7 +161,10 @@ import { newWorkflowExecutionEngineStateProvider } from "../temporal/workflowexe
|
|
|
161
161
|
import { newWorkflowExecutionWorkerFactory } from "../temporal/workflowexecution/worker.js";
|
|
162
162
|
import { HealthState, registerHealthService } from "../transport/health.js";
|
|
163
163
|
import { resolveConsoleAssets } from "../transport/console/assets.js";
|
|
164
|
-
import {
|
|
164
|
+
import {
|
|
165
|
+
createConsoleLane,
|
|
166
|
+
type ConsoleSignInPosture,
|
|
167
|
+
} from "../transport/console/handler.js";
|
|
165
168
|
import { createRegistryLanes } from "../transport/registry/lanes.js";
|
|
166
169
|
import { createUnifiedPortServer } from "../transport/server.js";
|
|
167
170
|
import type { ServerConfig } from "./config.js";
|
|
@@ -762,11 +765,36 @@ export async function composeServer(
|
|
|
762
765
|
} else {
|
|
763
766
|
logger.debug("no web console export bundled; console lane disabled");
|
|
764
767
|
}
|
|
768
|
+
// The console is told how to sign in (20260913.02 sp.console-login): the
|
|
769
|
+
// OSS issuer arm of the posture, in the console's vocabulary. A composed
|
|
770
|
+
// unit's own `requireAuthentication` is NOT expressed here — a
|
|
771
|
+
// composition whose verifiers resolve its users serves its console its
|
|
772
|
+
// own way (the cloud's container does); the Enterprise console story is
|
|
773
|
+
// P4's. Issuer set but no console client registered is WARN-degrade, the
|
|
774
|
+
// STIGMER_OAUTH_REDIRECT_URI posture: the CLI and SDKs keep working with
|
|
775
|
+
// API keys, and the served console refuses with copy naming the knob.
|
|
776
|
+
const consoleSignIn: ConsoleSignInPosture = authEnabled
|
|
777
|
+
? {
|
|
778
|
+
posture: "oidc",
|
|
779
|
+
issuer: config.oidcIssuer,
|
|
780
|
+
audience: config.oidcAudience,
|
|
781
|
+
consoleClientId: config.oidcConsoleClientId,
|
|
782
|
+
}
|
|
783
|
+
: { posture: "trusted-local" };
|
|
784
|
+
if (
|
|
785
|
+
consoleAssets !== undefined &&
|
|
786
|
+
consoleSignIn.posture === "oidc" &&
|
|
787
|
+
consoleSignIn.consoleClientId === ""
|
|
788
|
+
) {
|
|
789
|
+
logger.warn(
|
|
790
|
+
"STIGMER_OIDC_ISSUER is set but STIGMER_OIDC_CONSOLE_CLIENT_ID is not — the web console this server serves cannot sign in; register a public PKCE client for the console at the issuer and set it",
|
|
791
|
+
);
|
|
792
|
+
}
|
|
765
793
|
const consoleLane =
|
|
766
794
|
consoleAssets !== undefined
|
|
767
795
|
? createConsoleLane({
|
|
768
796
|
assets: consoleAssets,
|
|
769
|
-
|
|
797
|
+
signIn: consoleSignIn,
|
|
770
798
|
logger,
|
|
771
799
|
})
|
|
772
800
|
: undefined;
|
package/src/boot/config.ts
CHANGED
|
@@ -170,6 +170,20 @@ export interface ServerConfig {
|
|
|
170
170
|
* OIDC is boot-fatal, the R2/operator-identity loud-fail precedent.
|
|
171
171
|
*/
|
|
172
172
|
readonly oidcAudience: string;
|
|
173
|
+
/**
|
|
174
|
+
* The OAuth client the served web console signs in with
|
|
175
|
+
* (STIGMER_OIDC_CONSOLE_CLIENT_ID; 20260913.02 sp.console-login, Q-CL-1):
|
|
176
|
+
* a PUBLIC client the operator registers at the issuer for the browser's
|
|
177
|
+
* Authorization Code + PKCE flow — a public identifier, never a secret.
|
|
178
|
+
* Deliberately lenient beside the two boot-fatal OIDC fields: a
|
|
179
|
+
* self-host that set the issuer before this knob existed, and uses the
|
|
180
|
+
* CLI and SDKs with API keys, must keep booting on upgrade. Empty means
|
|
181
|
+
* the console cannot sign in; the composition root WARNs and the served
|
|
182
|
+
* console says so itself (Q-CL-2). Named for the console on purpose — a
|
|
183
|
+
* future CLI or desktop sign-in against a self-host is a different
|
|
184
|
+
* client type (loopback/native) and should not be tempted to reuse it.
|
|
185
|
+
*/
|
|
186
|
+
readonly oidcConsoleClientId: string;
|
|
173
187
|
/**
|
|
174
188
|
* Sandbox provisioner driver (SANDBOX_PROVISIONER_TYPE; §6d, O6). ""
|
|
175
189
|
* — the default — is the external-runner posture: no provisioner is
|
|
@@ -329,6 +343,7 @@ export function loadConfig(env: NodeJS.ProcessEnv = process.env): ServerConfig {
|
|
|
329
343
|
oauthRedirectUri: envString(env, "STIGMER_OAUTH_REDIRECT_URI", ""),
|
|
330
344
|
consoleDir: envString(env, "STIGMER_CONSOLE_DIR", ""),
|
|
331
345
|
...loadOidcConfig(env),
|
|
346
|
+
oidcConsoleClientId: envString(env, "STIGMER_OIDC_CONSOLE_CLIENT_ID", ""),
|
|
332
347
|
sandboxProvisionerType: envString(env, "SANDBOX_PROVISIONER_TYPE", ""),
|
|
333
348
|
sandboxBackendEndpoint: envString(
|
|
334
349
|
env,
|
|
@@ -599,28 +599,25 @@ function newLoadChannelsByAgentStep(
|
|
|
599
599
|
continue;
|
|
600
600
|
}
|
|
601
601
|
}
|
|
602
|
-
// 20260830.01 census lane 19: the
|
|
603
|
-
//
|
|
604
|
-
|
|
602
|
+
// 20260830.01 census lane 19: the org/agent filters are contract
|
|
603
|
+
// parity in both editions and run FIRST; the scope narrows the
|
|
604
|
+
// agent's channels last (the scope is the last per-row predicate,
|
|
605
|
+
// stigmer-cloud 20260913.04 T02).
|
|
606
|
+
const channels = await restrictListByReadScope(
|
|
605
607
|
listReadScope,
|
|
606
608
|
ctx.callerIdentity,
|
|
607
609
|
ApiResourceKind.agent_channel,
|
|
608
|
-
decoded
|
|
610
|
+
decoded.filter((channel) => {
|
|
611
|
+
const ref = channel.spec?.agentRef;
|
|
612
|
+
return (
|
|
613
|
+
(ref?.org ?? "") === agentOrg &&
|
|
614
|
+
(ref?.slug ?? "") === agentSlug &&
|
|
615
|
+
(req.org === "" || (channel.metadata?.org ?? "") === req.org)
|
|
616
|
+
);
|
|
617
|
+
}),
|
|
609
618
|
"",
|
|
610
619
|
);
|
|
611
620
|
|
|
612
|
-
const channels: AgentChannel[] = [];
|
|
613
|
-
for (const channel of visible) {
|
|
614
|
-
const ref = channel.spec?.agentRef;
|
|
615
|
-
if ((ref?.org ?? "") !== agentOrg || (ref?.slug ?? "") !== agentSlug) {
|
|
616
|
-
continue;
|
|
617
|
-
}
|
|
618
|
-
if (req.org !== "" && (channel.metadata?.org ?? "") !== req.org) {
|
|
619
|
-
continue;
|
|
620
|
-
}
|
|
621
|
-
channels.push(channel);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
621
|
ctx.set(
|
|
625
622
|
CHANNEL_LIST_KEY,
|
|
626
623
|
create(AgentChannelListSchema, {
|
|
@@ -702,27 +699,22 @@ function newListByOrgAndLabelsStep(
|
|
|
702
699
|
continue;
|
|
703
700
|
}
|
|
704
701
|
}
|
|
705
|
-
// 20260830.01 census lane 18: the
|
|
706
|
-
//
|
|
707
|
-
|
|
702
|
+
// 20260830.01 census lane 18: the org and label filters serve the
|
|
703
|
+
// Java handler's arms in both editions and run FIRST; the scope
|
|
704
|
+
// narrows the org's rows last (the scope is the last per-row
|
|
705
|
+
// predicate, stigmer-cloud 20260913.04 T02).
|
|
706
|
+
const channels = await restrictListByReadScope(
|
|
708
707
|
listReadScope,
|
|
709
708
|
ctx.callerIdentity,
|
|
710
709
|
ApiResourceKind.agent_channel,
|
|
711
|
-
decoded
|
|
710
|
+
decoded.filter(
|
|
711
|
+
(channel) =>
|
|
712
|
+
(channel.metadata?.org ?? "") === org &&
|
|
713
|
+
matchesAllLabels(channel.metadata?.labels ?? {}, filterLabels),
|
|
714
|
+
),
|
|
712
715
|
"",
|
|
713
716
|
);
|
|
714
717
|
|
|
715
|
-
const channels: AgentChannel[] = [];
|
|
716
|
-
for (const channel of visible) {
|
|
717
|
-
if ((channel.metadata?.org ?? "") !== org) {
|
|
718
|
-
continue;
|
|
719
|
-
}
|
|
720
|
-
if (!matchesAllLabels(channel.metadata?.labels ?? {}, filterLabels)) {
|
|
721
|
-
continue;
|
|
722
|
-
}
|
|
723
|
-
channels.push(channel);
|
|
724
|
-
}
|
|
725
|
-
|
|
726
718
|
channels.sort((a, b) =>
|
|
727
719
|
compareCreatedAtDesc(
|
|
728
720
|
a.status?.audit?.specAudit?.createdAt,
|
|
@@ -130,6 +130,7 @@ import {
|
|
|
130
130
|
newApplyPhaseFilterStep,
|
|
131
131
|
newBuildExecutionListResponseStep,
|
|
132
132
|
newQueryAllExecutionsStep,
|
|
133
|
+
newRestrictByReadScopeStep,
|
|
133
134
|
newQueryExecutionsBySessionStep,
|
|
134
135
|
newValidateListBySessionRequestStep,
|
|
135
136
|
newValidateListRequestStep,
|
|
@@ -320,7 +321,9 @@ async function createExecution(
|
|
|
320
321
|
.addStep(newValidateThinkingModeStep(deps.modelRegistry))
|
|
321
322
|
.addStep(newResolveDefaultAgentStep(deps.store, deps.logger))
|
|
322
323
|
.addStep(newEnsureSessionOrAgentResolvedStep(deps.logger))
|
|
323
|
-
.addStep(
|
|
324
|
+
.addStep(
|
|
325
|
+
newAuthorizeRunTargetStep(deps.authorizer, agentExecutionRunTarget),
|
|
326
|
+
)
|
|
324
327
|
.addStep(newResolveSlugStep())
|
|
325
328
|
.addStep(newBuildNewStateStep())
|
|
326
329
|
// Vouches the runner-stamped workflow lineage labels (or refuses a
|
|
@@ -549,10 +552,9 @@ async function list(
|
|
|
549
552
|
),
|
|
550
553
|
)
|
|
551
554
|
.addStep(newValidateListRequestStep())
|
|
552
|
-
.addStep(
|
|
553
|
-
newQueryAllExecutionsStep(deps.store, deps.logger, deps.listReadScope),
|
|
554
|
-
)
|
|
555
|
+
.addStep(newQueryAllExecutionsStep(deps.store, deps.logger))
|
|
555
556
|
.addStep(newApplyPhaseFilterStep(deps.logger))
|
|
557
|
+
.addStep(newRestrictByReadScopeStep(deps.listReadScope))
|
|
556
558
|
.addStep(newBuildExecutionListResponseStep())
|
|
557
559
|
.build()
|
|
558
560
|
.execute(reqCtx);
|
|
@@ -582,7 +584,11 @@ async function listBySession(
|
|
|
582
584
|
)
|
|
583
585
|
.addStep(newValidateListBySessionRequestStep())
|
|
584
586
|
.addStep(
|
|
585
|
-
newQueryExecutionsBySessionStep(
|
|
587
|
+
newQueryExecutionsBySessionStep(
|
|
588
|
+
deps.store,
|
|
589
|
+
deps.logger,
|
|
590
|
+
deps.listReadScope,
|
|
591
|
+
),
|
|
586
592
|
)
|
|
587
593
|
.addStep(newBuildExecutionListResponseStep())
|
|
588
594
|
.build()
|