@sema-agent/server 1.313.0 → 1.315.0
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/approval-hmac.d.ts +17 -0
- package/dist/approval-hmac.js +27 -0
- package/dist/auth-bridge.d.ts +3 -2
- package/dist/bench/s1/live-deps.js +2 -2
- package/dist/budget.d.ts +4 -76
- package/dist/budget.js +4 -83
- package/dist/capabilities/sandbox-file-send.d.ts +2 -1
- package/dist/config-center/apply-effective.d.ts +22 -0
- package/dist/config-center/apply-effective.js +283 -0
- package/dist/config-center/http-client.d.ts +23 -0
- package/dist/config-center/http-client.js +109 -0
- package/dist/config-center/restart-signal.d.ts +12 -0
- package/dist/config-center/restart-signal.js +70 -0
- package/dist/config-center/skills-mcp.d.ts +13 -0
- package/dist/config-center/skills-mcp.js +113 -0
- package/dist/config-center/types.d.ts +143 -0
- package/dist/config-center/types.js +2 -0
- package/dist/config-types.d.ts +1 -1
- package/dist/elicitation.d.ts +5 -3
- package/dist/elicitation.js +3 -2
- package/dist/fleet/fleet-bus.js +92 -83
- package/dist/fleet-lease.d.ts +1 -1
- package/dist/fleet-lease.js +1 -1
- package/dist/hooks/hook-llm.d.ts +5 -4
- package/dist/hooks/hook-runner.d.ts +1 -1
- package/dist/hooks/hook-runner.js +19 -10
- package/dist/http/server.d.ts +95 -69
- package/dist/http/server.js +75 -86
- package/dist/index.d.ts +1 -1
- package/dist/key-resolver.d.ts +1 -1
- package/dist/key-resolver.js +1 -1
- package/dist/leader/grader-env-factory.d.ts +1 -1
- package/dist/leader/grader-env-factory.js +2 -2
- package/dist/leader/leader.js +5 -2
- package/dist/leader/wire.d.ts +1 -1
- package/dist/leader/wire.js +170 -166
- package/dist/main.js +487 -476
- package/dist/memory-scope.d.ts +18 -0
- package/dist/memory-scope.js +38 -0
- package/dist/observability/cost-taxonomy.d.ts +34 -0
- package/dist/observability/cost-taxonomy.js +26 -0
- package/dist/observability/prompt-manifest.d.ts +75 -0
- package/dist/observability/prompt-manifest.js +82 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +67 -0
- package/dist/plugins/checkpoint-store-sql.js +224 -0
- package/dist/plugins/image-bake-store-sql.d.ts +53 -0
- package/dist/plugins/image-bake-store-sql.js +463 -0
- package/dist/plugins/k8s-bg-scripts.d.ts +19 -0
- package/dist/plugins/k8s-bg-scripts.js +129 -0
- package/dist/plugins/k8s-exec-protocol.d.ts +20 -0
- package/dist/plugins/k8s-exec-protocol.js +87 -0
- package/dist/plugins/pg-checkpoint-store.d.ts +1 -33
- package/dist/plugins/pg-checkpoint-store.js +1 -189
- package/dist/plugins/pg-cost-quota.js +3 -143
- package/dist/plugins/pg-image-bake.d.ts +1 -40
- package/dist/plugins/pg-image-bake.js +1 -420
- package/dist/plugins/pg-rate-limiter.d.ts +2 -32
- package/dist/plugins/pg-rate-limiter.js +4 -147
- package/dist/plugins/remote-env-k8s.d.ts +5 -38
- package/dist/plugins/remote-env-k8s.js +7 -213
- package/dist/plugins/sql-driver.d.ts +25 -0
- package/dist/plugins/sql-driver.js +59 -0
- package/dist/plugins/tidb-checkpoint-store.d.ts +1 -49
- package/dist/plugins/tidb-checkpoint-store.js +1 -191
- package/dist/plugins/tidb-image-bake.d.ts +1 -38
- package/dist/plugins/tidb-image-bake.js +1 -348
- package/dist/plugins/web-search.d.ts +4 -3
- package/dist/plugins/write-behind-counter.d.ts +14 -3
- package/dist/plugins/write-behind-counter.js +39 -12
- package/dist/principal-jwt.d.ts +44 -0
- package/dist/principal-jwt.js +95 -0
- package/dist/question.d.ts +2 -1
- package/dist/question.js +3 -2
- package/dist/run-local.js +2 -2
- package/dist/runtime-caps-resolver.d.ts +7 -7
- package/dist/runtime-caps-resolver.js +3 -3
- package/dist/security.d.ts +4 -74
- package/dist/security.js +6 -155
- package/dist/sema-registry.d.ts +5 -200
- package/dist/sema-registry.js +4 -567
- package/dist/tool-approval.d.ts +2 -1
- package/dist/tool-approval.js +3 -2
- package/package.json +1 -1
package/dist/question.js
CHANGED
|
@@ -8,7 +8,7 @@ export const DEFAULT_QUESTION_THROTTLE = {
|
|
|
8
8
|
ttlMs: 5 * 60_000,
|
|
9
9
|
};
|
|
10
10
|
const NO_HUMAN = { answers: [] };
|
|
11
|
-
export function
|
|
11
|
+
export function parseQuestionResponse(body) {
|
|
12
12
|
if (body === null || typeof body !== "object" || Array.isArray(body))
|
|
13
13
|
return { ok: false, error: "body must be an object" };
|
|
14
14
|
const answers = body.answers;
|
|
@@ -30,6 +30,7 @@ export function parseQuestionAnswer(body) {
|
|
|
30
30
|
}
|
|
31
31
|
return { ok: true, value: { answers: out } };
|
|
32
32
|
}
|
|
33
|
+
export const parseQuestionAnswer = parseQuestionResponse;
|
|
33
34
|
function boundQuestions(questions) {
|
|
34
35
|
const redacted = redactDeep(questions);
|
|
35
36
|
try {
|
|
@@ -115,7 +116,7 @@ export class QuestionCoordinator {
|
|
|
115
116
|
return answer;
|
|
116
117
|
};
|
|
117
118
|
respond(id, principal, body) {
|
|
118
|
-
const parsed =
|
|
119
|
+
const parsed = parseQuestionResponse(body);
|
|
119
120
|
if (!parsed.ok)
|
|
120
121
|
return { status: 400, body: { error: parsed.error } };
|
|
121
122
|
const entry = this.pending.get(id);
|
package/dist/run-local.js
CHANGED
|
@@ -21,7 +21,7 @@ import { buildScenarios, selectScenario, centerScenarios } from "./capabilities/
|
|
|
21
21
|
import { HttpError, memoryEngineBackendFor, memorySpecForRequest } from "./security.js";
|
|
22
22
|
import { createMemorySyncRunner, createMemorySyncTransport } from "./memory-sync-client.js";
|
|
23
23
|
import { buildPricing } from "./budget.js";
|
|
24
|
-
import {
|
|
24
|
+
import { createKeyResolver } from "./key-resolver.js";
|
|
25
25
|
import { createLogger } from "./observability/logger.js";
|
|
26
26
|
import { createMetrics } from "./observability/metrics.js";
|
|
27
27
|
export function parseArgs(argv) {
|
|
@@ -183,7 +183,7 @@ export async function runLocal(argv, deps = {}) {
|
|
|
183
183
|
return 2;
|
|
184
184
|
}
|
|
185
185
|
const sessionStore = fileBackend.sessionStore;
|
|
186
|
-
const keyResolver =
|
|
186
|
+
const keyResolver = createKeyResolver(config.modelApiKeyEnv);
|
|
187
187
|
const hostRx = config.remoteExec?.provider === "host" ? config.remoteExec : undefined;
|
|
188
188
|
const workspaceDir = args.workspace ?? hostRx?.workspaceBase ?? process.cwd();
|
|
189
189
|
const executionEnvFactory = hostRx
|
|
@@ -2,7 +2,7 @@ import type { RuntimeCaps } from "@sema-agent/core";
|
|
|
2
2
|
import type { EntitlementRuntimeCaps } from "@sema-agent/registry-core";
|
|
3
3
|
import { fetchPrincipalCaps, type ExecutionRuling } from "./sema-registry.js";
|
|
4
4
|
import type { ScenarioRuling } from "./capabilities/scenarios.js";
|
|
5
|
-
export interface
|
|
5
|
+
export interface EntitlementsResolverOpts {
|
|
6
6
|
baseUrl: string;
|
|
7
7
|
token: string;
|
|
8
8
|
worker?: string;
|
|
@@ -15,18 +15,18 @@ export interface RuntimeCapsResolverOpts {
|
|
|
15
15
|
}
|
|
16
16
|
export declare function toCoreRuntimeCaps(ent: EntitlementRuntimeCaps | null | undefined): RuntimeCaps | undefined;
|
|
17
17
|
export declare function scopedTokenNeedsWorker(token: string, worker: string | undefined): boolean;
|
|
18
|
-
export interface
|
|
18
|
+
export interface PrincipalEntitlementsClient {
|
|
19
19
|
resolveRuntimeCaps: (principal: string | undefined) => Promise<RuntimeCaps | undefined>;
|
|
20
20
|
scenarioRuling: (principal: string | undefined) => Promise<ScenarioRuling | undefined>;
|
|
21
21
|
executionRuling: (principal: string | undefined) => Promise<ExecutionRuling | undefined>;
|
|
22
22
|
}
|
|
23
23
|
export declare function gateExecutionLane(ruling: ExecutionRuling | undefined, ownLane: string): void;
|
|
24
|
-
export declare function
|
|
25
|
-
export declare function
|
|
26
|
-
export type
|
|
27
|
-
export declare function applyObserverEnvOptIn(centerResolver:
|
|
24
|
+
export declare function createPrincipalEntitlementsClient(opts: EntitlementsResolverOpts): PrincipalEntitlementsClient;
|
|
25
|
+
export declare function createEntitlementsResolver(opts: EntitlementsResolverOpts): (principal: string | undefined) => Promise<RuntimeCaps | undefined>;
|
|
26
|
+
export type EntitlementsResolverFn = (principal: string | undefined) => RuntimeCaps | undefined | Promise<RuntimeCaps | undefined>;
|
|
27
|
+
export declare function applyObserverEnvOptIn(centerResolver: EntitlementsResolverFn | undefined, opts: {
|
|
28
28
|
experimentalObserverAgents: boolean;
|
|
29
29
|
requirePrincipal: boolean;
|
|
30
30
|
warn?: (msg: string, fields?: Record<string, unknown>) => void;
|
|
31
|
-
}):
|
|
31
|
+
}): EntitlementsResolverFn | undefined;
|
|
32
32
|
//# sourceMappingURL=runtime-caps-resolver.d.ts.map
|
|
@@ -36,7 +36,7 @@ export function gateExecutionLane(ruling, ownLane) {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
export function
|
|
39
|
+
export function createPrincipalEntitlementsClient(opts) {
|
|
40
40
|
const ttlMs = opts.ttlMs ?? 60_000;
|
|
41
41
|
const denyTtlMs = opts.denyTtlMs ?? Math.min(ttlMs, 10_000);
|
|
42
42
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
@@ -115,8 +115,8 @@ export function createPrincipalCapsClient(opts) {
|
|
|
115
115
|
executionRuling: async (principal) => (principal ? (await load(principal)).execution : undefined),
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
-
export function
|
|
119
|
-
return
|
|
118
|
+
export function createEntitlementsResolver(opts) {
|
|
119
|
+
return createPrincipalEntitlementsClient(opts).resolveRuntimeCaps;
|
|
120
120
|
}
|
|
121
121
|
export function applyObserverEnvOptIn(centerResolver, opts) {
|
|
122
122
|
if (!opts.experimentalObserverAgents)
|
package/dist/security.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { IncomingMessage } from "node:http";
|
|
2
|
-
import {
|
|
2
|
+
import { type SessionStore, type SessionTreeEntry } from "@sema-agent/core";
|
|
3
3
|
import type { ServiceConfig } from "./config-types.js";
|
|
4
4
|
import type { TaskRequestBody } from "./http/wire-types.js";
|
|
5
5
|
import type { StagingHandle } from "./session-sync-kernel.js";
|
|
6
|
-
import type { ApprovalHmacKey, PrincipalJwtKey } from "./auth-keys.js";
|
|
7
6
|
export { parseApprovalHmacKeys, parsePrincipalJwks } from "./auth-keys.js";
|
|
8
7
|
export type { ApprovalHmacKey, PrincipalJwtKey } from "./auth-keys.js";
|
|
9
8
|
export interface SessionListItem {
|
|
@@ -80,76 +79,7 @@ export declare function ssoVerifiedPrincipal(req: IncomingMessage): string | und
|
|
|
80
79
|
export declare function setSsoScope(req: IncomingMessage, scope: string): void;
|
|
81
80
|
export declare function ssoVerifiedScope(req: IncomingMessage): string | undefined;
|
|
82
81
|
export declare function verifiedPrincipal(req: IncomingMessage, config: ServiceConfig): string | undefined;
|
|
83
|
-
export
|
|
84
|
-
export
|
|
85
|
-
|
|
86
|
-
posture: "dark" | "forced";
|
|
87
|
-
} | undefined;
|
|
88
|
-
export declare function memoryEngineBackendFor(config: ServiceConfig, fallbackRoot?: string): {
|
|
89
|
-
backend: FileMemoryEngineBackend;
|
|
90
|
-
root: string;
|
|
91
|
-
} | undefined;
|
|
92
|
-
export declare function memorySpecForRequest(scope: string | undefined, memoryWrite: boolean | undefined, defaultScopes?: string[]): {
|
|
93
|
-
scope: string;
|
|
94
|
-
scopes?: string[];
|
|
95
|
-
writeScope?: string | null;
|
|
96
|
-
scopeContract?: "v2";
|
|
97
|
-
} | undefined;
|
|
98
|
-
export declare function approvalHmacMessage(env: {
|
|
99
|
-
sessionId: string;
|
|
100
|
-
boundCallId?: string | null;
|
|
101
|
-
boundInputHash?: string | null;
|
|
102
|
-
decision: string;
|
|
103
|
-
reason?: string | null;
|
|
104
|
-
}): string;
|
|
105
|
-
export declare const MAX_APPROVAL_REASON_CHARS = 4096;
|
|
106
|
-
export declare function verifyApprovalHmac(env: {
|
|
107
|
-
sessionId: string;
|
|
108
|
-
boundCallId?: string | null;
|
|
109
|
-
boundInputHash?: string | null;
|
|
110
|
-
decision: string;
|
|
111
|
-
reason?: string | null;
|
|
112
|
-
}, mac: string, kid: string | undefined, keys: ApprovalHmacKey[]): boolean;
|
|
113
|
-
export declare function verifyPrincipalJwt(token: string, keys: PrincipalJwtKey[], expect: {
|
|
114
|
-
iss: string;
|
|
115
|
-
aud: string;
|
|
116
|
-
nowSec?: number;
|
|
117
|
-
skewSec?: number;
|
|
118
|
-
maxTtlSec?: number;
|
|
119
|
-
}): {
|
|
120
|
-
sub: string;
|
|
121
|
-
bnd?: string;
|
|
122
|
-
} | null;
|
|
123
|
-
export declare function approvalBnd(env: {
|
|
124
|
-
sessionId: string;
|
|
125
|
-
boundCallId?: string | null;
|
|
126
|
-
boundInputHash?: string | null;
|
|
127
|
-
}): string;
|
|
128
|
-
export declare function verifyDirectDoorProof(proof: {
|
|
129
|
-
jwt?: string;
|
|
130
|
-
mac?: string;
|
|
131
|
-
kid?: string;
|
|
132
|
-
}, envelope: {
|
|
133
|
-
sessionId: string;
|
|
134
|
-
boundCallId?: string | null;
|
|
135
|
-
boundInputHash?: string | null;
|
|
136
|
-
decision: string;
|
|
137
|
-
reason?: string | null;
|
|
138
|
-
}, config: {
|
|
139
|
-
principalJwtPubkeys: PrincipalJwtKey[];
|
|
140
|
-
principalJwtIss?: string;
|
|
141
|
-
principalJwtAud?: string;
|
|
142
|
-
principalJwtMaxTtlSec?: number;
|
|
143
|
-
approvalHmacKeys: ApprovalHmacKey[];
|
|
144
|
-
}, opts?: {
|
|
145
|
-
actionBinding?: boolean;
|
|
146
|
-
}): {
|
|
147
|
-
ok: true;
|
|
148
|
-
principal: string;
|
|
149
|
-
} | {
|
|
150
|
-
ok: false;
|
|
151
|
-
status: number;
|
|
152
|
-
errorCode: string;
|
|
153
|
-
error: string;
|
|
154
|
-
};
|
|
82
|
+
export { memoryScopeFor, memoryEngineRemoteLanePosture, memoryEngineBackendFor, memorySpecForRequest } from "./memory-scope.js";
|
|
83
|
+
export { approvalHmacMessage, MAX_APPROVAL_REASON_CHARS, verifyApprovalHmac } from "./approval-hmac.js";
|
|
84
|
+
export { verifyPrincipalJwt, approvalBnd, verifyDirectDoorProof } from "./principal-jwt.js";
|
|
155
85
|
//# sourceMappingURL=security.d.ts.map
|
package/dist/security.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { uuidv7, FileMemoryEngineBackend, resolveMemoryEngineRoot, deriveControlPlaneDir, formatUserScope, formatProjScope } from "@sema-agent/core";
|
|
1
|
+
import { uuidv7 } from "@sema-agent/core";
|
|
4
2
|
import { PROJECT_ID_REGEX } from "@sema-agent/registry-core";
|
|
5
3
|
export { parseApprovalHmacKeys, parsePrincipalJwks } from "./auth-keys.js";
|
|
4
|
+
import { memoryScopeFor } from "./memory-scope.js";
|
|
5
|
+
import { verifyPrincipalJwt } from "./principal-jwt.js";
|
|
6
6
|
const UUIDV7_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
7
7
|
export function isUuidV7(s) {
|
|
8
8
|
return UUIDV7_RE.test(s);
|
|
@@ -128,156 +128,7 @@ export function verifiedPrincipal(req, config) {
|
|
|
128
128
|
assertPrincipalShape(sub);
|
|
129
129
|
return sub;
|
|
130
130
|
}
|
|
131
|
-
export
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (!principal)
|
|
135
|
-
return undefined;
|
|
136
|
-
return projectId ? formatProjScope(principal, projectId) : formatUserScope(principal);
|
|
137
|
-
}
|
|
138
|
-
return undefined;
|
|
139
|
-
}
|
|
140
|
-
return config.memoryScope;
|
|
141
|
-
}
|
|
142
|
-
export function memoryEngineRemoteLanePosture(config) {
|
|
143
|
-
const lane = config.remoteExec?.provider;
|
|
144
|
-
if (lane === undefined || lane === "host")
|
|
145
|
-
return undefined;
|
|
146
|
-
return { lane, posture: config.memoryEngineRemoteLaneAllowed === true ? "forced" : "dark" };
|
|
147
|
-
}
|
|
148
|
-
export function memoryEngineBackendFor(config, fallbackRoot) {
|
|
149
|
-
if (config.requirePrincipal === true || !config.memoryEngineEnabled)
|
|
150
|
-
return undefined;
|
|
151
|
-
if (memoryEngineRemoteLanePosture(config)?.posture === "dark")
|
|
152
|
-
return undefined;
|
|
153
|
-
const root = resolveMemoryEngineRoot(config.memoryEngineDir ?? fallbackRoot);
|
|
154
|
-
const dir = join(root, "memory");
|
|
155
|
-
return { backend: new FileMemoryEngineBackend(dir, { controlDir: deriveControlPlaneDir(root, dir) }), root };
|
|
156
|
-
}
|
|
157
|
-
export function memorySpecForRequest(scope, memoryWrite, defaultScopes) {
|
|
158
|
-
if (!scope)
|
|
159
|
-
return undefined;
|
|
160
|
-
const isV2 = (k) => k.startsWith("user:") || k.startsWith("org:") || k.startsWith("proj:") || k.startsWith("userproj:");
|
|
161
|
-
const extras = (defaultScopes ?? []).filter((s, i, arr) => typeof s === "string" && s.length > 0 && s !== scope && arr.indexOf(s) === i);
|
|
162
|
-
const layered = extras.length > 0 ? { scopes: [scope, ...extras], writeScope: scope } : {};
|
|
163
|
-
const v2 = isV2(scope) || extras.some(isV2) ? { scopeContract: "v2" } : {};
|
|
164
|
-
return memoryWrite === false ? { scope, ...layered, writeScope: null, ...v2 } : { scope, ...layered, ...v2 };
|
|
165
|
-
}
|
|
166
|
-
export function approvalHmacMessage(env) {
|
|
167
|
-
return JSON.stringify([env.sessionId, env.boundCallId ?? null, env.boundInputHash ?? null, env.decision, env.reason ?? null]);
|
|
168
|
-
}
|
|
169
|
-
export const MAX_APPROVAL_REASON_CHARS = 4_096;
|
|
170
|
-
export function verifyApprovalHmac(env, mac, kid, keys) {
|
|
171
|
-
if (keys.length === 0)
|
|
172
|
-
return false;
|
|
173
|
-
let supplied;
|
|
174
|
-
try {
|
|
175
|
-
supplied = Buffer.from(mac, "hex");
|
|
176
|
-
}
|
|
177
|
-
catch {
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
if (supplied.length === 0)
|
|
181
|
-
return false;
|
|
182
|
-
const ordered = kid ? [...keys.filter((k) => k.kid === kid), ...keys.filter((k) => k.kid !== kid)] : keys;
|
|
183
|
-
const msg = approvalHmacMessage(env);
|
|
184
|
-
for (const k of ordered) {
|
|
185
|
-
const expected = createHmac("sha256", k.key).update(msg).digest();
|
|
186
|
-
if (expected.length === supplied.length && timingSafeEqual(expected, supplied))
|
|
187
|
-
return true;
|
|
188
|
-
}
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
function b64urlToBuf(s) {
|
|
192
|
-
return Buffer.from(s, "base64url");
|
|
193
|
-
}
|
|
194
|
-
function verifyJwsSignature(alg, signingInput, sig, pub) {
|
|
195
|
-
try {
|
|
196
|
-
if (alg === "EdDSA")
|
|
197
|
-
return cryptoVerify(null, signingInput, pub, sig);
|
|
198
|
-
if (alg === "RS256")
|
|
199
|
-
return cryptoVerify("sha256", signingInput, pub, sig);
|
|
200
|
-
if (alg === "ES256")
|
|
201
|
-
return cryptoVerify("sha256", signingInput, { key: pub, dsaEncoding: "ieee-p1363" }, sig);
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
catch {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
export function verifyPrincipalJwt(token, keys, expect) {
|
|
209
|
-
if (keys.length === 0)
|
|
210
|
-
return null;
|
|
211
|
-
const parts = token.split(".");
|
|
212
|
-
if (parts.length !== 3)
|
|
213
|
-
return null;
|
|
214
|
-
const [h, p, s] = parts;
|
|
215
|
-
let header;
|
|
216
|
-
let payload;
|
|
217
|
-
let sig;
|
|
218
|
-
try {
|
|
219
|
-
header = JSON.parse(b64urlToBuf(h).toString("utf8"));
|
|
220
|
-
payload = JSON.parse(b64urlToBuf(p).toString("utf8"));
|
|
221
|
-
sig = b64urlToBuf(s);
|
|
222
|
-
}
|
|
223
|
-
catch {
|
|
224
|
-
return null;
|
|
225
|
-
}
|
|
226
|
-
if (typeof header !== "object" || header === null || typeof payload !== "object" || payload === null)
|
|
227
|
-
return null;
|
|
228
|
-
if (typeof header.alg !== "string" || typeof header.kid !== "string" || sig.length === 0)
|
|
229
|
-
return null;
|
|
230
|
-
const key = keys.find((k) => k.kid === header.kid);
|
|
231
|
-
if (!key || key.alg !== header.alg)
|
|
232
|
-
return null;
|
|
233
|
-
let pub;
|
|
234
|
-
try {
|
|
235
|
-
pub = createPublicKey(key.key);
|
|
236
|
-
}
|
|
237
|
-
catch {
|
|
238
|
-
return null;
|
|
239
|
-
}
|
|
240
|
-
const signingInput = Buffer.from(`${h}.${p}`, "utf8");
|
|
241
|
-
if (!verifyJwsSignature(key.alg, signingInput, sig, pub))
|
|
242
|
-
return null;
|
|
243
|
-
if (payload.iss !== expect.iss)
|
|
244
|
-
return null;
|
|
245
|
-
const aud = payload.aud;
|
|
246
|
-
const audOk = aud === expect.aud || (Array.isArray(aud) && aud.includes(expect.aud));
|
|
247
|
-
if (!audOk)
|
|
248
|
-
return null;
|
|
249
|
-
if (typeof payload.sub !== "string" || payload.sub.length === 0)
|
|
250
|
-
return null;
|
|
251
|
-
const now = expect.nowSec ?? Math.floor(Date.now() / 1000);
|
|
252
|
-
const skew = expect.skewSec ?? 30;
|
|
253
|
-
if (typeof payload.exp !== "number" || payload.exp + skew < now)
|
|
254
|
-
return null;
|
|
255
|
-
if (payload.nbf !== undefined && (typeof payload.nbf !== "number" || payload.nbf - skew > now))
|
|
256
|
-
return null;
|
|
257
|
-
if (expect.maxTtlSec && payload.exp - now > expect.maxTtlSec + skew)
|
|
258
|
-
return null;
|
|
259
|
-
const bnd = typeof payload.cnf?.bnd === "string" ? payload.cnf.bnd : undefined;
|
|
260
|
-
return { sub: payload.sub, bnd };
|
|
261
|
-
}
|
|
262
|
-
export function approvalBnd(env) {
|
|
263
|
-
return createHash("sha256").update(JSON.stringify([env.sessionId, env.boundCallId ?? null, env.boundInputHash ?? null])).digest("hex");
|
|
264
|
-
}
|
|
265
|
-
export function verifyDirectDoorProof(proof, envelope, config, opts) {
|
|
266
|
-
const actionBinding = opts?.actionBinding ?? true;
|
|
267
|
-
if (!proof.jwt)
|
|
268
|
-
return { ok: false, status: 401, errorCode: "principal_unverified", error: "direct door requires a signed principal token (X-Approval-Principal-Token)" };
|
|
269
|
-
const verified = verifyPrincipalJwt(proof.jwt, config.principalJwtPubkeys, { iss: config.principalJwtIss ?? "\0", aud: config.principalJwtAud ?? "\0", maxTtlSec: config.principalJwtMaxTtlSec });
|
|
270
|
-
if (!verified)
|
|
271
|
-
return { ok: false, status: 401, errorCode: "principal_unverified", error: "principal token failed verification" };
|
|
272
|
-
if (actionBinding && !envelope.boundInputHash)
|
|
273
|
-
return { ok: false, status: 400, errorCode: "approval_mac_required", error: "direct door requires boundInputHash (the bound action) in the body" };
|
|
274
|
-
if (verified.bnd !== approvalBnd(envelope))
|
|
275
|
-
return { ok: false, status: 401, errorCode: "principal_unbound", error: "principal token is not bound to this decision (cnf.bnd mismatch)" };
|
|
276
|
-
if (!proof.mac)
|
|
277
|
-
return { ok: false, status: 401, errorCode: "approval_mac_required", error: "direct door requires an approval MAC (X-Approval-Mac)" };
|
|
278
|
-
const ok = verifyApprovalHmac({ sessionId: envelope.sessionId, boundCallId: envelope.boundCallId ?? null, boundInputHash: envelope.boundInputHash ?? null, decision: envelope.decision, reason: envelope.reason ?? null }, proof.mac, proof.kid, config.approvalHmacKeys);
|
|
279
|
-
if (!ok)
|
|
280
|
-
return { ok: false, status: 401, errorCode: "approval_mac_invalid", error: "approval envelope MAC invalid" };
|
|
281
|
-
return { ok: true, principal: verified.sub };
|
|
282
|
-
}
|
|
131
|
+
export { memoryScopeFor, memoryEngineRemoteLanePosture, memoryEngineBackendFor, memorySpecForRequest } from "./memory-scope.js";
|
|
132
|
+
export { approvalHmacMessage, MAX_APPROVAL_REASON_CHARS, verifyApprovalHmac } from "./approval-hmac.js";
|
|
133
|
+
export { verifyPrincipalJwt, approvalBnd, verifyDirectDoorProof } from "./principal-jwt.js";
|
|
283
134
|
//# sourceMappingURL=security.js.map
|
package/dist/sema-registry.d.ts
CHANGED
|
@@ -1,201 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import type { Logger } from "./observability/logger.js";
|
|
7
|
-
import type { LoadedSkill } from "./capabilities/skills.js";
|
|
8
|
-
import type { ScenarioRuling } from "./capabilities/scenarios.js";
|
|
9
|
-
import type { CollabTemplateWire } from "./capabilities/collab-wire.js";
|
|
10
|
-
interface CenterModel {
|
|
11
|
-
name: string;
|
|
12
|
-
id: string;
|
|
13
|
-
provider: string;
|
|
14
|
-
api: "openai-completions" | "anthropic-messages";
|
|
15
|
-
baseUrl?: string;
|
|
16
|
-
apiKeyEnv?: string;
|
|
17
|
-
sealedApiKey?: {
|
|
18
|
-
ciphertext: string;
|
|
19
|
-
publicKeyId: string;
|
|
20
|
-
alg: string;
|
|
21
|
-
setAt?: string;
|
|
22
|
-
};
|
|
23
|
-
tier?: string;
|
|
24
|
-
reasoning?: boolean;
|
|
25
|
-
vision?: boolean;
|
|
26
|
-
contextWindow?: number;
|
|
27
|
-
maxTokens?: number;
|
|
28
|
-
autoCompactTokens?: number;
|
|
29
|
-
charsPerToken?: number;
|
|
30
|
-
cost?: {
|
|
31
|
-
input: number;
|
|
32
|
-
output: number;
|
|
33
|
-
cacheRead?: number;
|
|
34
|
-
cacheWrite?: number;
|
|
35
|
-
};
|
|
36
|
-
quotaWeight?: number;
|
|
37
|
-
defaultThinking?: string;
|
|
38
|
-
reasoningEffortLevels?: string[];
|
|
39
|
-
extraBody?: Record<string, unknown>;
|
|
40
|
-
promptGuidance?: string[];
|
|
41
|
-
enabled?: boolean;
|
|
42
|
-
}
|
|
43
|
-
type CenterRoleTarget = {
|
|
44
|
-
model: string;
|
|
45
|
-
} | {
|
|
46
|
-
select: unknown;
|
|
47
|
-
};
|
|
48
|
-
interface CenterTeam {
|
|
49
|
-
name: string;
|
|
50
|
-
members: {
|
|
51
|
-
role: string;
|
|
52
|
-
modelRole?: string;
|
|
53
|
-
model?: string;
|
|
54
|
-
systemPrompt?: string;
|
|
55
|
-
}[];
|
|
56
|
-
rounds: number;
|
|
57
|
-
synthesizer?: {
|
|
58
|
-
role: string;
|
|
59
|
-
modelRole?: string;
|
|
60
|
-
systemPrompt?: string;
|
|
61
|
-
};
|
|
62
|
-
scenario?: string;
|
|
63
|
-
maxTranscriptTokens?: number;
|
|
64
|
-
enabled?: boolean;
|
|
65
|
-
}
|
|
66
|
-
export interface CenterSkillManifest {
|
|
67
|
-
name: string;
|
|
68
|
-
description: string;
|
|
69
|
-
scenarios: string[];
|
|
70
|
-
contentHash: string;
|
|
71
|
-
enabled?: boolean;
|
|
72
|
-
}
|
|
73
|
-
export interface CenterMcpServer {
|
|
74
|
-
name: string;
|
|
75
|
-
scenarios: string[];
|
|
76
|
-
enabled?: boolean;
|
|
77
|
-
allowTools?: string[];
|
|
78
|
-
elicitation?: boolean;
|
|
79
|
-
transport: {
|
|
80
|
-
kind: "stdio";
|
|
81
|
-
command: string;
|
|
82
|
-
args?: string[];
|
|
83
|
-
envRefs?: Record<string, string>;
|
|
84
|
-
} | {
|
|
85
|
-
kind: "http";
|
|
86
|
-
url: string;
|
|
87
|
-
headerRefs?: Record<string, string>;
|
|
88
|
-
principalHeader?: string;
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
export interface EffectiveConfig {
|
|
92
|
-
version: number;
|
|
93
|
-
updatedAt: string;
|
|
94
|
-
models: {
|
|
95
|
-
models: CenterModel[];
|
|
96
|
-
roles: Record<string, CenterRoleTarget>;
|
|
97
|
-
atModelAllowlist?: string[];
|
|
98
|
-
};
|
|
99
|
-
teams?: {
|
|
100
|
-
teams: CenterTeam[];
|
|
101
|
-
};
|
|
102
|
-
collab?: {
|
|
103
|
-
templates: CollabTemplateWire[];
|
|
104
|
-
};
|
|
105
|
-
skills?: {
|
|
106
|
-
skills: CenterSkillManifest[];
|
|
107
|
-
};
|
|
108
|
-
mcp?: {
|
|
109
|
-
servers: CenterMcpServer[];
|
|
110
|
-
};
|
|
111
|
-
scenarios?: {
|
|
112
|
-
scenarios: Array<{
|
|
113
|
-
name: string;
|
|
114
|
-
toolset: string;
|
|
115
|
-
enabled?: boolean;
|
|
116
|
-
}>;
|
|
117
|
-
};
|
|
118
|
-
runtime?: {
|
|
119
|
-
rateLimitPerMin?: number;
|
|
120
|
-
approvalRequire?: string[];
|
|
121
|
-
maxTaskCostUsd?: number;
|
|
122
|
-
maxTaskTokens?: number;
|
|
123
|
-
maxPrincipalCostUsd?: number;
|
|
124
|
-
costQuotaWindowSec?: number;
|
|
125
|
-
autonomy?: Autonomy;
|
|
126
|
-
commandPolicy?: CommandRule[];
|
|
127
|
-
};
|
|
128
|
-
projects?: {
|
|
129
|
-
projects?: Record<string, unknown>;
|
|
130
|
-
} | Record<string, unknown>;
|
|
131
|
-
governance?: {
|
|
132
|
-
autonomy?: Autonomy;
|
|
133
|
-
commandPolicy?: CommandRule[];
|
|
134
|
-
approvalRequire?: string[];
|
|
135
|
-
};
|
|
136
|
-
plugins?: {
|
|
137
|
-
plugins?: unknown[];
|
|
138
|
-
};
|
|
139
|
-
prompts?: unknown;
|
|
140
|
-
}
|
|
141
|
-
export interface ExecutionRuling {
|
|
142
|
-
required: boolean;
|
|
143
|
-
allowedLanes: string[];
|
|
144
|
-
sessionMirror?: SessionMirrorRuling;
|
|
145
|
-
}
|
|
146
|
-
export interface SessionMirrorRuling {
|
|
147
|
-
engineUrl: string;
|
|
148
|
-
required: boolean;
|
|
149
|
-
}
|
|
150
|
-
export declare function fetchEffective(baseUrl: string, token: string, etag: string | undefined, fetchImpl?: typeof fetch, worker?: string): Promise<{
|
|
151
|
-
effective: EffectiveConfig;
|
|
152
|
-
etag?: string;
|
|
153
|
-
} | null>;
|
|
154
|
-
export declare function fetchPrincipalCaps(baseUrl: string, token: string, principal: string, etag: string | undefined, fetchImpl?: typeof fetch, worker?: string): Promise<{
|
|
155
|
-
runtimeCaps: EntitlementRuntimeCaps | null;
|
|
156
|
-
configured: boolean;
|
|
157
|
-
scenario?: ScenarioRuling;
|
|
158
|
-
execution?: ExecutionRuling;
|
|
159
|
-
executionDrift?: string;
|
|
160
|
-
etag?: string;
|
|
161
|
-
} | null>;
|
|
162
|
-
export declare function mutateInPlace<V>(target: Record<string, V>, source: Record<string, V>): void;
|
|
163
|
-
export declare function applyEffective(config: ServiceConfig, eff: EffectiveConfig, logger?: Logger, opts?: {
|
|
164
|
-
teamsOnly?: boolean;
|
|
165
|
-
sealedKeys?: SealedKeyOpener;
|
|
166
|
-
deferModelPlane?: boolean;
|
|
167
|
-
}): void;
|
|
168
|
-
export declare function applyRuntimeGates(config: ServiceConfig, rt: EffectiveConfig["runtime"], logger?: Logger): void;
|
|
169
|
-
export declare function applyRuntimeHot(config: ServiceConfig, rt: EffectiveConfig["runtime"], logger?: Logger): void;
|
|
170
|
-
export declare function resolveDefaultModelName(eff: EffectiveConfig, has: (name: string) => boolean, fallback: string, onDangling?: (source: string, name: string) => void): {
|
|
171
|
-
name: string;
|
|
172
|
-
source: string;
|
|
173
|
-
};
|
|
174
|
-
export declare function logEffectiveDiff(config: ServiceConfig, eff: EffectiveConfig, logger?: Logger): void;
|
|
175
|
-
export declare function runtimeHasActiveGate(rt: EffectiveConfig["runtime"]): boolean;
|
|
176
|
-
export type RestartSlice = "skills" | "mcp" | "scenarios" | "runtime-gates" | "models-tiers";
|
|
177
|
-
export interface RestartSignal {
|
|
178
|
-
restartRequired: true;
|
|
179
|
-
reasons: RestartSlice[];
|
|
180
|
-
version: number;
|
|
181
|
-
since: number;
|
|
182
|
-
}
|
|
183
|
-
export declare function restartReasons(boot: EffectiveConfig | undefined, current: EffectiveConfig): RestartSlice[];
|
|
184
|
-
export declare function planeHasActiveTiers(eff: EffectiveConfig): boolean;
|
|
185
|
-
export declare function modelPlaneChanged(prev: EffectiveConfig | undefined, next: EffectiveConfig): boolean;
|
|
186
|
-
export declare class ConfigCenterHttpError extends Error {
|
|
187
|
-
readonly status: number;
|
|
188
|
-
constructor(message: string, status: number);
|
|
189
|
-
}
|
|
190
|
-
export declare function fetchSkillContent(baseUrl: string, token: string, contentHash: string, fetchImpl?: typeof fetch): Promise<string>;
|
|
191
|
-
export declare function fetchPromptArtifact(baseUrl: string, token: string, artifactDigest: string, fetchImpl?: typeof fetch): Promise<unknown>;
|
|
192
|
-
export declare function fetchPromptBlob(baseUrl: string, token: string, contentDigest: string, fetchImpl?: typeof fetch): Promise<string>;
|
|
193
|
-
export declare function applyCenterSkills(baseline: LoadedSkill[], manifest: {
|
|
194
|
-
skills: CenterSkillManifest[];
|
|
195
|
-
}, baseUrl: string, token: string, logger?: Logger, fetchImpl?: typeof fetch, diskCacheDir?: string): Promise<LoadedSkill[]>;
|
|
196
|
-
export declare function resolveMcpServers(mcp: {
|
|
197
|
-
servers: CenterMcpServer[];
|
|
198
|
-
}, logger?: Logger): ScopedMcpServer[];
|
|
199
|
-
export declare function mcpForScenario(servers: ScopedMcpServer[] | undefined, scenario: string): McpServerSpec[] | undefined;
|
|
200
|
-
export {};
|
|
1
|
+
export { fetchEffective, fetchPrincipalCaps, ConfigCenterHttpError, fetchSkillContent, fetchPromptArtifact, fetchPromptBlob, } from "./config-center/http-client.js";
|
|
2
|
+
export { mutateInPlace, applyEffective, applyRuntimeGates, applyRuntimeHot, resolveDefaultModelName, logEffectiveDiff, runtimeHasActiveGate, } from "./config-center/apply-effective.js";
|
|
3
|
+
export { restartReasons, planeHasActiveTiers, modelPlaneChanged, type RestartSlice, type RestartSignal, } from "./config-center/restart-signal.js";
|
|
4
|
+
export { applyCenterSkills, resolveMcpServers, mcpForScenario } from "./config-center/skills-mcp.js";
|
|
5
|
+
export type { CenterSkillManifest, CenterMcpServer, EffectiveConfig, ExecutionRuling, SessionMirrorRuling, } from "./config-center/types.js";
|
|
201
6
|
//# sourceMappingURL=sema-registry.d.ts.map
|