@astrasyncai/verification-gateway 2.4.6 → 2.4.7
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/adapters/express.js +1 -1
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +1 -1
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.js +1 -1
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +1 -1
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.js +1 -1
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +1 -1
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.js +1 -1
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +1 -1
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/browser/background.js +1 -1
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +1 -1
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cursor/extension.js +1 -1
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +1 -1
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/gateway/gateway.js +1 -1
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +1 -1
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/{index-Bstl43HI.d.ts → index-WL4d9e9_.d.ts} +1 -1
- package/dist/{index-TS4SGvf4.d.mts → index-ZkHvXsMo.d.mts} +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +716 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +706 -1
- package/dist/index.mjs.map +1 -1
- package/dist/transport/index.d.mts +1 -1
- package/dist/transport/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33,15 +33,24 @@ __export(src_exports, {
|
|
|
33
33
|
ACCESS_LEVEL_DESCRIPTIONS: () => ACCESS_LEVEL_DESCRIPTIONS,
|
|
34
34
|
ACCESS_LEVEL_HIERARCHY: () => ACCESS_LEVEL_HIERARCHY,
|
|
35
35
|
AgentClient: () => AgentClient,
|
|
36
|
+
AstraSync: () => AstraSync,
|
|
37
|
+
AstraSyncError: () => AstraSyncError,
|
|
38
|
+
AuthenticationError: () => AuthenticationError,
|
|
36
39
|
ChallengeHandler: () => ChallengeHandler,
|
|
37
40
|
DEFAULT_TRUST_THRESHOLDS: () => DEFAULT_TRUST_THRESHOLDS,
|
|
41
|
+
KYDRequiredError: () => KYDRequiredError,
|
|
42
|
+
RegistrationDeniedError: () => RegistrationDeniedError,
|
|
43
|
+
RegistrationExpiredError: () => RegistrationExpiredError,
|
|
44
|
+
RegistrationTimeoutError: () => RegistrationTimeoutError,
|
|
38
45
|
TRUST_LEVEL_RANGES: () => TRUST_LEVEL_RANGES,
|
|
39
46
|
VERSION: () => VERSION,
|
|
40
47
|
agent: () => agent_exports,
|
|
41
48
|
clearCache: () => clearCache,
|
|
49
|
+
createMcpMiddleware: () => createMcpMiddleware,
|
|
42
50
|
determineAccessLevel: () => determineAccessLevel,
|
|
43
51
|
express: () => express_exports,
|
|
44
52
|
extractCredentials: () => extractCredentials,
|
|
53
|
+
extractMcpCredentials: () => extractMcpCredentials,
|
|
45
54
|
getAccessLevelForScore: () => getAccessLevelForScore,
|
|
46
55
|
getCapabilities: () => getCapabilities,
|
|
47
56
|
getTrustLevel: () => getTrustLevel,
|
|
@@ -51,6 +60,7 @@ __export(src_exports, {
|
|
|
51
60
|
quickVerify: () => quickVerify,
|
|
52
61
|
recordDecision: () => recordDecision2,
|
|
53
62
|
sdk: () => sdk_exports,
|
|
63
|
+
setMcpMeta: () => setMcpMeta,
|
|
54
64
|
transport: () => transport_exports,
|
|
55
65
|
verify: () => verify
|
|
56
66
|
});
|
|
@@ -178,7 +188,7 @@ function getCapabilities(accessLevel) {
|
|
|
178
188
|
}
|
|
179
189
|
|
|
180
190
|
// src/version.ts
|
|
181
|
-
var SDK_VERSION = "2.4.
|
|
191
|
+
var SDK_VERSION = "2.4.7";
|
|
182
192
|
|
|
183
193
|
// src/verify.ts
|
|
184
194
|
var DEFAULT_CONFIG = {
|
|
@@ -565,6 +575,26 @@ async function recordDecision(config, sessionId, decision, reason, override) {
|
|
|
565
575
|
}).catch(() => {
|
|
566
576
|
});
|
|
567
577
|
}
|
|
578
|
+
async function recordAnonymousLocalOverride(config, correlationId, override, reason) {
|
|
579
|
+
const headers = { "Content-Type": "application/json" };
|
|
580
|
+
if (config.apiKey) {
|
|
581
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
582
|
+
headers["X-API-Key"] = config.apiKey;
|
|
583
|
+
}
|
|
584
|
+
await fetch(`${config.apiBaseUrl}/agents/verify-access/local-override`, {
|
|
585
|
+
method: "POST",
|
|
586
|
+
headers,
|
|
587
|
+
body: JSON.stringify({
|
|
588
|
+
correlationId,
|
|
589
|
+
reason,
|
|
590
|
+
overriddenBy: override.overriddenBy,
|
|
591
|
+
toolName: override.toolName,
|
|
592
|
+
requestedLevel: override.requestedLevel,
|
|
593
|
+
grantedLevel: override.grantedLevel
|
|
594
|
+
})
|
|
595
|
+
}).catch(() => {
|
|
596
|
+
});
|
|
597
|
+
}
|
|
568
598
|
async function fetchRoutes(config, counterpartyId) {
|
|
569
599
|
if (!counterpartyId) return null;
|
|
570
600
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -3949,6 +3979,681 @@ function extractCredentialsFromProtocol(protocol, context) {
|
|
|
3949
3979
|
}
|
|
3950
3980
|
}
|
|
3951
3981
|
|
|
3982
|
+
// src/transport/mcp-server.ts
|
|
3983
|
+
var MCP_VERIFIED_HOP_HEADER = "X-Astra-Verified-Hop";
|
|
3984
|
+
var MCP_VERIFIED_HOP_MAX_AGE_MS = 6e4;
|
|
3985
|
+
function serializeVerifiedHop(marker) {
|
|
3986
|
+
return `${marker.astraId};${marker.sessionId ?? ""};${marker.checkedAt}`;
|
|
3987
|
+
}
|
|
3988
|
+
function parseVerifiedHop(value) {
|
|
3989
|
+
if (!value) return null;
|
|
3990
|
+
const parts = value.split(";");
|
|
3991
|
+
if (parts.length !== 3) return null;
|
|
3992
|
+
const [astraId, sessionId, checkedAtRaw] = parts;
|
|
3993
|
+
if (!astraId) return null;
|
|
3994
|
+
const checkedAt = Number(checkedAtRaw);
|
|
3995
|
+
if (!Number.isFinite(checkedAt) || checkedAt <= 0) return null;
|
|
3996
|
+
return {
|
|
3997
|
+
astraId,
|
|
3998
|
+
...sessionId ? { sessionId } : {},
|
|
3999
|
+
checkedAt
|
|
4000
|
+
};
|
|
4001
|
+
}
|
|
4002
|
+
function isVerifiedHopValidFor(marker, expectedAstraId, opts = {}) {
|
|
4003
|
+
if (!marker) return false;
|
|
4004
|
+
if (marker.astraId !== expectedAstraId) return false;
|
|
4005
|
+
const maxAge = opts.maxAgeMs ?? MCP_VERIFIED_HOP_MAX_AGE_MS;
|
|
4006
|
+
const now = opts.now ?? Date.now();
|
|
4007
|
+
return now - marker.checkedAt <= maxAge && now >= marker.checkedAt;
|
|
4008
|
+
}
|
|
4009
|
+
function parseMcpJsonRpc(body) {
|
|
4010
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) return null;
|
|
4011
|
+
const obj = body;
|
|
4012
|
+
if (obj.jsonrpc !== "2.0" && obj.jsonrpc !== "1.0") return null;
|
|
4013
|
+
const method = typeof obj.method === "string" ? obj.method : null;
|
|
4014
|
+
if (!method) return null;
|
|
4015
|
+
const params = obj.params;
|
|
4016
|
+
let toolName;
|
|
4017
|
+
if (method === "tools/call" && params && typeof params.name === "string") {
|
|
4018
|
+
toolName = params.name;
|
|
4019
|
+
}
|
|
4020
|
+
let protocolVersion;
|
|
4021
|
+
if (method === "initialize" && params && typeof params.protocolVersion === "string") {
|
|
4022
|
+
protocolVersion = params.protocolVersion;
|
|
4023
|
+
}
|
|
4024
|
+
const meta = params?._meta;
|
|
4025
|
+
const astrasyncMeta = meta?.astrasync;
|
|
4026
|
+
const args = params?.arguments;
|
|
4027
|
+
let agentIdFromBody;
|
|
4028
|
+
if (astrasyncMeta && typeof astrasyncMeta.agentId === "string") {
|
|
4029
|
+
agentIdFromBody = astrasyncMeta.agentId;
|
|
4030
|
+
} else if (args && typeof args.agent_id === "string") {
|
|
4031
|
+
agentIdFromBody = args.agent_id;
|
|
4032
|
+
}
|
|
4033
|
+
const purposeBodyResult = extractFromMcpBody(astrasyncMeta, args, "purpose");
|
|
4034
|
+
const actionBodyResult = extractFromMcpBody(astrasyncMeta, args, "action");
|
|
4035
|
+
const isInitialize = method === "initialize";
|
|
4036
|
+
const isToolCall = method === "tools/call";
|
|
4037
|
+
const isIntrospection = method === "tools/list" || method === "prompts/list" || method === "resources/list" || method === "ping" || method === "notifications/initialized";
|
|
4038
|
+
return {
|
|
4039
|
+
method,
|
|
4040
|
+
...toolName ? { toolName } : {},
|
|
4041
|
+
...protocolVersion ? { protocolVersion } : {},
|
|
4042
|
+
...agentIdFromBody ? { agentIdFromBody } : {},
|
|
4043
|
+
...purposeBodyResult.value ? { purposeFromBody: purposeBodyResult.value } : {},
|
|
4044
|
+
...purposeBodyResult.source ? { purposeSourceFromBody: purposeBodyResult.source } : {},
|
|
4045
|
+
...actionBodyResult.value ? { actionFromBody: actionBodyResult.value } : {},
|
|
4046
|
+
...actionBodyResult.source ? { actionSourceFromBody: actionBodyResult.source } : {},
|
|
4047
|
+
isInitialize,
|
|
4048
|
+
isToolCall,
|
|
4049
|
+
isIntrospection
|
|
4050
|
+
};
|
|
4051
|
+
}
|
|
4052
|
+
function extractFromMcpBody(astrasyncMeta, args, key) {
|
|
4053
|
+
if (astrasyncMeta && typeof astrasyncMeta[key] === "string") {
|
|
4054
|
+
return { value: astrasyncMeta[key], source: "meta" };
|
|
4055
|
+
}
|
|
4056
|
+
if (args && typeof args[key] === "string") {
|
|
4057
|
+
return { value: args[key], source: "tool_argument" };
|
|
4058
|
+
}
|
|
4059
|
+
return { value: void 0, source: void 0 };
|
|
4060
|
+
}
|
|
4061
|
+
function mcpToPdlss(parsed, headerPurpose, headerAction) {
|
|
4062
|
+
const resource = parsed.toolName ? `mcp:tool/${parsed.toolName}` : `mcp:method/${parsed.method}`;
|
|
4063
|
+
let purpose;
|
|
4064
|
+
let purposeSource;
|
|
4065
|
+
if (headerPurpose) {
|
|
4066
|
+
purpose = headerPurpose;
|
|
4067
|
+
purposeSource = "header";
|
|
4068
|
+
} else if (parsed.purposeFromBody && parsed.purposeSourceFromBody) {
|
|
4069
|
+
purpose = parsed.purposeFromBody;
|
|
4070
|
+
purposeSource = parsed.purposeSourceFromBody;
|
|
4071
|
+
} else {
|
|
4072
|
+
purpose = "mcp_invoke";
|
|
4073
|
+
purposeSource = "default_mcp_invoke";
|
|
4074
|
+
}
|
|
4075
|
+
let action;
|
|
4076
|
+
let actionSource;
|
|
4077
|
+
if (headerAction) {
|
|
4078
|
+
action = headerAction;
|
|
4079
|
+
actionSource = "header";
|
|
4080
|
+
} else if (parsed.actionFromBody && parsed.actionSourceFromBody) {
|
|
4081
|
+
action = parsed.actionFromBody;
|
|
4082
|
+
actionSource = parsed.actionSourceFromBody;
|
|
4083
|
+
} else {
|
|
4084
|
+
action = parsed.toolName ? `${parsed.method}:${parsed.toolName}` : parsed.method;
|
|
4085
|
+
actionSource = "transport_layer";
|
|
4086
|
+
}
|
|
4087
|
+
return { purpose, action, resource, purposeSource, actionSource };
|
|
4088
|
+
}
|
|
4089
|
+
function mcpRiskTier(parsed) {
|
|
4090
|
+
if (parsed.isInitialize || parsed.method === "notifications/initialized") return "none";
|
|
4091
|
+
if (parsed.isIntrospection) return "none";
|
|
4092
|
+
if (parsed.method === "resources/read") return "read-only";
|
|
4093
|
+
if (parsed.isToolCall) return "standard";
|
|
4094
|
+
return "standard";
|
|
4095
|
+
}
|
|
4096
|
+
|
|
4097
|
+
// src/adapters/mcp.ts
|
|
4098
|
+
function readSingleHeader(value) {
|
|
4099
|
+
if (typeof value === "string") return value;
|
|
4100
|
+
if (Array.isArray(value)) return value[0];
|
|
4101
|
+
return void 0;
|
|
4102
|
+
}
|
|
4103
|
+
function defaultMcpDenied(result, req, res) {
|
|
4104
|
+
const id = req.body?.id ?? null;
|
|
4105
|
+
const status = result.verified ? 403 : 401;
|
|
4106
|
+
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
4107
|
+
res.status(status).json({
|
|
4108
|
+
jsonrpc: "2.0",
|
|
4109
|
+
id,
|
|
4110
|
+
error: {
|
|
4111
|
+
code: result.verified ? -32001 : -32e3,
|
|
4112
|
+
message: result.denialReasons?.[0] ?? "Access denied",
|
|
4113
|
+
data: {
|
|
4114
|
+
accessLevel: result.accessLevel,
|
|
4115
|
+
guidance: result.guidance,
|
|
4116
|
+
// Round-10: aggregated per-dimension detail + correlation handle.
|
|
4117
|
+
failures: result.failures,
|
|
4118
|
+
correlationId: result.correlationId
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
});
|
|
4122
|
+
}
|
|
4123
|
+
function resolveMinAccessLevel(parsed, opts) {
|
|
4124
|
+
if (parsed.toolName && opts.toolGates && opts.toolGates[parsed.toolName] !== void 0) {
|
|
4125
|
+
return { level: opts.toolGates[parsed.toolName], source: "toolGate" };
|
|
4126
|
+
}
|
|
4127
|
+
if (opts.methodGates && opts.methodGates[parsed.method] !== void 0) {
|
|
4128
|
+
return { level: opts.methodGates[parsed.method], source: "methodGate" };
|
|
4129
|
+
}
|
|
4130
|
+
return { level: mcpRiskTier(parsed), source: "tier" };
|
|
4131
|
+
}
|
|
4132
|
+
function createMcpMiddleware(options) {
|
|
4133
|
+
const {
|
|
4134
|
+
toolGates,
|
|
4135
|
+
methodGates,
|
|
4136
|
+
onAgentIdMismatch = "reject",
|
|
4137
|
+
skip = false,
|
|
4138
|
+
onDenied = defaultMcpDenied,
|
|
4139
|
+
trustVerifiedHop = true,
|
|
4140
|
+
verifiedHopMaxAgeMs,
|
|
4141
|
+
recordDecisions,
|
|
4142
|
+
enableRuntimeChallenge = true,
|
|
4143
|
+
...config
|
|
4144
|
+
} = options;
|
|
4145
|
+
return async (req, res, next) => {
|
|
4146
|
+
try {
|
|
4147
|
+
if (skip) return next();
|
|
4148
|
+
const parsed = parseMcpJsonRpc(req.body);
|
|
4149
|
+
if (!parsed) {
|
|
4150
|
+
if (config.setPassThroughHeader) {
|
|
4151
|
+
res.setHeader("X-Astra-Gateway-Mode", "unenforced");
|
|
4152
|
+
res.setHeader("X-Astra-Gateway-Reason", "non-jsonrpc-body");
|
|
4153
|
+
}
|
|
4154
|
+
return next();
|
|
4155
|
+
}
|
|
4156
|
+
req.mcpRequest = parsed;
|
|
4157
|
+
const headerRaw = req.headers["x-astra-id"] ?? req.headers["x-astra-agentid"];
|
|
4158
|
+
const headerAstraId = typeof headerRaw === "string" ? headerRaw : Array.isArray(headerRaw) ? headerRaw[0] : void 0;
|
|
4159
|
+
const bodyAstraId = parsed.agentIdFromBody;
|
|
4160
|
+
let effectiveAstraId;
|
|
4161
|
+
if (headerAstraId && bodyAstraId && headerAstraId !== bodyAstraId) {
|
|
4162
|
+
if (onAgentIdMismatch === "reject") {
|
|
4163
|
+
const id = req.body?.id ?? null;
|
|
4164
|
+
res.status(400).json({
|
|
4165
|
+
jsonrpc: "2.0",
|
|
4166
|
+
id,
|
|
4167
|
+
error: {
|
|
4168
|
+
code: -32602,
|
|
4169
|
+
message: "AGENT_ID_MISMATCH",
|
|
4170
|
+
data: {
|
|
4171
|
+
detail: "The agent id in the X-Astra-Id header disagrees with params._meta.astrasync.agentId / params.arguments.agent_id. Reconcile before calling the tool \u2014 see https://astrasync.ai/docs/mcp-integration#identity-reconciliation.",
|
|
4172
|
+
headerAstraId,
|
|
4173
|
+
bodyAstraId
|
|
4174
|
+
}
|
|
4175
|
+
}
|
|
4176
|
+
});
|
|
4177
|
+
return;
|
|
4178
|
+
}
|
|
4179
|
+
effectiveAstraId = onAgentIdMismatch === "prefer-header" ? headerAstraId : bodyAstraId;
|
|
4180
|
+
} else {
|
|
4181
|
+
effectiveAstraId = headerAstraId ?? bodyAstraId;
|
|
4182
|
+
}
|
|
4183
|
+
if (trustVerifiedHop && effectiveAstraId) {
|
|
4184
|
+
const hopRaw = req.headers[MCP_VERIFIED_HOP_HEADER.toLowerCase()];
|
|
4185
|
+
const hopValue = typeof hopRaw === "string" ? hopRaw : Array.isArray(hopRaw) ? hopRaw[0] : void 0;
|
|
4186
|
+
const marker = parseVerifiedHop(hopValue);
|
|
4187
|
+
if (isVerifiedHopValidFor(marker, effectiveAstraId, {
|
|
4188
|
+
...verifiedHopMaxAgeMs !== void 0 ? { maxAgeMs: verifiedHopMaxAgeMs } : {}
|
|
4189
|
+
})) {
|
|
4190
|
+
return next();
|
|
4191
|
+
}
|
|
4192
|
+
}
|
|
4193
|
+
const { level: minAccessLevel, source: gateSource } = resolveMinAccessLevel(parsed, {
|
|
4194
|
+
toolGates,
|
|
4195
|
+
methodGates
|
|
4196
|
+
});
|
|
4197
|
+
const credentials = extractCredentials(
|
|
4198
|
+
req.headers,
|
|
4199
|
+
req.query
|
|
4200
|
+
);
|
|
4201
|
+
if (effectiveAstraId) credentials.astraId = effectiveAstraId;
|
|
4202
|
+
const shouldEnforce = minAccessLevel !== "none";
|
|
4203
|
+
if (minAccessLevel === "none" && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
|
|
4204
|
+
if (config.setPassThroughHeader) {
|
|
4205
|
+
res.setHeader("X-Astra-Gateway-Mode", "unenforced");
|
|
4206
|
+
res.setHeader("X-Astra-Gateway-Reason", "mcp-tier-none");
|
|
4207
|
+
}
|
|
4208
|
+
return next();
|
|
4209
|
+
}
|
|
4210
|
+
const headerPurpose = readSingleHeader(req.headers["x-astra-purpose"]);
|
|
4211
|
+
const headerAction = readSingleHeader(req.headers["x-astra-action"]);
|
|
4212
|
+
const pdlss = mcpToPdlss(parsed, headerPurpose, headerAction);
|
|
4213
|
+
if (config.debug) {
|
|
4214
|
+
console.debug("[mcp-middleware] pdlss resolved", {
|
|
4215
|
+
purpose_source: pdlss.purposeSource,
|
|
4216
|
+
resolved_purpose: pdlss.purpose,
|
|
4217
|
+
action_source: pdlss.actionSource,
|
|
4218
|
+
resolved_action: pdlss.action
|
|
4219
|
+
});
|
|
4220
|
+
}
|
|
4221
|
+
const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get("host")}${req.path}`;
|
|
4222
|
+
const shouldRecordDecisions = recordDecisions !== false;
|
|
4223
|
+
const result = await verify(config, {
|
|
4224
|
+
credentials,
|
|
4225
|
+
purpose: pdlss.purpose,
|
|
4226
|
+
action: pdlss.action,
|
|
4227
|
+
resource: pdlss.resource,
|
|
4228
|
+
// Round-12 (F19): mark transport protocol separately from intent.
|
|
4229
|
+
// The MCP middleware always sets this to 'mcp'; non-MCP callers
|
|
4230
|
+
// leave it unset (server-side default is 'rest').
|
|
4231
|
+
invocationProtocol: "mcp",
|
|
4232
|
+
createSession: shouldRecordDecisions,
|
|
4233
|
+
counterpartyUrl,
|
|
4234
|
+
counterpartyType: config.counterpartyType || "mcp_server",
|
|
4235
|
+
enableRuntimeChallenge,
|
|
4236
|
+
callerMetadata: {
|
|
4237
|
+
sourceIp: req.ip,
|
|
4238
|
+
userAgent: req.headers["user-agent"],
|
|
4239
|
+
host: req.headers.host
|
|
4240
|
+
}
|
|
4241
|
+
});
|
|
4242
|
+
req.agentVerification = result;
|
|
4243
|
+
const sessionId = result.sessionId;
|
|
4244
|
+
const correlationId = result.correlationId;
|
|
4245
|
+
if (!result.verified) {
|
|
4246
|
+
if (shouldRecordDecisions && sessionId) {
|
|
4247
|
+
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
4248
|
+
});
|
|
4249
|
+
}
|
|
4250
|
+
onDenied(result, req, res);
|
|
4251
|
+
return;
|
|
4252
|
+
}
|
|
4253
|
+
if (!shouldEnforce) {
|
|
4254
|
+
if (config.setPassThroughHeader) {
|
|
4255
|
+
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
4256
|
+
res.setHeader("X-Astra-Gateway-Reason", "evaluated-not-enforced");
|
|
4257
|
+
}
|
|
4258
|
+
if (shouldRecordDecisions && sessionId) {
|
|
4259
|
+
recordDecision(config, sessionId, "granted").catch(() => {
|
|
4260
|
+
});
|
|
4261
|
+
}
|
|
4262
|
+
return next();
|
|
4263
|
+
}
|
|
4264
|
+
if (!hasMinimumAccess(result.accessLevel, minAccessLevel)) {
|
|
4265
|
+
const insufficientFailure = {
|
|
4266
|
+
dimension: "access_level.insufficient",
|
|
4267
|
+
message: `Tool requires accessLevel '${minAccessLevel}'; agent has '${result.accessLevel}'.`,
|
|
4268
|
+
guidance: "Request elevated access via step-up verification (coming soon \u2014 ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score."
|
|
4269
|
+
};
|
|
4270
|
+
result.failures = [...result.failures ?? [], insufficientFailure];
|
|
4271
|
+
result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
|
|
4272
|
+
if (shouldRecordDecisions) {
|
|
4273
|
+
const overrideKind = gateSource === "toolGate" ? "toolGate" : gateSource === "methodGate" ? "methodGate" : "other";
|
|
4274
|
+
const override = {
|
|
4275
|
+
overriddenBy: overrideKind,
|
|
4276
|
+
...parsed.toolName && { toolName: parsed.toolName },
|
|
4277
|
+
requestedLevel: minAccessLevel,
|
|
4278
|
+
grantedLevel: result.accessLevel
|
|
4279
|
+
};
|
|
4280
|
+
if (sessionId) {
|
|
4281
|
+
recordDecision(config, sessionId, "denied", result.denialReasons?.[0], override).catch(
|
|
4282
|
+
() => {
|
|
4283
|
+
}
|
|
4284
|
+
);
|
|
4285
|
+
} else if (correlationId) {
|
|
4286
|
+
recordAnonymousLocalOverride(
|
|
4287
|
+
config,
|
|
4288
|
+
correlationId,
|
|
4289
|
+
override,
|
|
4290
|
+
result.denialReasons?.[0]
|
|
4291
|
+
).catch(() => {
|
|
4292
|
+
});
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
4295
|
+
onDenied(result, req, res);
|
|
4296
|
+
return;
|
|
4297
|
+
}
|
|
4298
|
+
if (effectiveAstraId) {
|
|
4299
|
+
res.setHeader(
|
|
4300
|
+
MCP_VERIFIED_HOP_HEADER,
|
|
4301
|
+
serializeVerifiedHop({
|
|
4302
|
+
astraId: effectiveAstraId,
|
|
4303
|
+
...sessionId ? { sessionId } : {},
|
|
4304
|
+
checkedAt: Date.now()
|
|
4305
|
+
})
|
|
4306
|
+
);
|
|
4307
|
+
}
|
|
4308
|
+
if (shouldRecordDecisions && sessionId) {
|
|
4309
|
+
recordDecision(config, sessionId, "granted").catch(() => {
|
|
4310
|
+
});
|
|
4311
|
+
}
|
|
4312
|
+
const enhancedResult = result;
|
|
4313
|
+
if (enhancedResult.warningHeader) {
|
|
4314
|
+
res.setHeader(enhancedResult.warningHeader.name, enhancedResult.warningHeader.value);
|
|
4315
|
+
}
|
|
4316
|
+
next();
|
|
4317
|
+
} catch (error) {
|
|
4318
|
+
console.error("[VerificationGateway/MCP] Middleware error:", error);
|
|
4319
|
+
next();
|
|
4320
|
+
}
|
|
4321
|
+
};
|
|
4322
|
+
}
|
|
4323
|
+
|
|
4324
|
+
// src/registration/errors.ts
|
|
4325
|
+
var AstraSyncError = class extends Error {
|
|
4326
|
+
constructor(message, statusCode, code) {
|
|
4327
|
+
super(message);
|
|
4328
|
+
this.name = "AstraSyncError";
|
|
4329
|
+
this.statusCode = statusCode;
|
|
4330
|
+
this.code = code;
|
|
4331
|
+
}
|
|
4332
|
+
};
|
|
4333
|
+
var KYDRequiredError = class extends AstraSyncError {
|
|
4334
|
+
constructor(response) {
|
|
4335
|
+
const kydUrl = response.kydUrl || "https://astrasync.ai/developer-profile";
|
|
4336
|
+
super(
|
|
4337
|
+
`KYD verification required before registering agents.
|
|
4338
|
+
Complete your KYD profile at: ${kydUrl}`,
|
|
4339
|
+
403,
|
|
4340
|
+
"KYD_REQUIRED"
|
|
4341
|
+
);
|
|
4342
|
+
this.name = "KYDRequiredError";
|
|
4343
|
+
this.kydUrl = kydUrl;
|
|
4344
|
+
this.ownerNotified = response.ownerNotified || false;
|
|
4345
|
+
}
|
|
4346
|
+
};
|
|
4347
|
+
var AuthenticationError = class extends AstraSyncError {
|
|
4348
|
+
constructor(message) {
|
|
4349
|
+
super(message, 401, "AUTH_FAILED");
|
|
4350
|
+
this.name = "AuthenticationError";
|
|
4351
|
+
}
|
|
4352
|
+
};
|
|
4353
|
+
var RegistrationDeniedError = class extends AstraSyncError {
|
|
4354
|
+
constructor(requestId, reason) {
|
|
4355
|
+
super(
|
|
4356
|
+
`Registration request ${requestId} was denied by the account owner.${reason ? ` Reason: ${reason}` : ""}`,
|
|
4357
|
+
403,
|
|
4358
|
+
"REGISTRATION_DENIED"
|
|
4359
|
+
);
|
|
4360
|
+
this.name = "RegistrationDeniedError";
|
|
4361
|
+
this.requestId = requestId;
|
|
4362
|
+
this.reason = reason;
|
|
4363
|
+
}
|
|
4364
|
+
};
|
|
4365
|
+
var RegistrationExpiredError = class extends AstraSyncError {
|
|
4366
|
+
constructor(requestId) {
|
|
4367
|
+
super(
|
|
4368
|
+
`Registration request ${requestId} expired before the owner approved it. Submit a new registration request.`,
|
|
4369
|
+
410,
|
|
4370
|
+
"REGISTRATION_EXPIRED"
|
|
4371
|
+
);
|
|
4372
|
+
this.name = "RegistrationExpiredError";
|
|
4373
|
+
this.requestId = requestId;
|
|
4374
|
+
}
|
|
4375
|
+
};
|
|
4376
|
+
var RegistrationTimeoutError = class extends AstraSyncError {
|
|
4377
|
+
constructor(requestId) {
|
|
4378
|
+
super(
|
|
4379
|
+
`Timed out waiting for owner approval of registration request ${requestId}. The request is still active server-side; poll the request to resume waiting.`,
|
|
4380
|
+
408,
|
|
4381
|
+
"REGISTRATION_TIMEOUT"
|
|
4382
|
+
);
|
|
4383
|
+
this.name = "RegistrationTimeoutError";
|
|
4384
|
+
this.requestId = requestId;
|
|
4385
|
+
}
|
|
4386
|
+
};
|
|
4387
|
+
|
|
4388
|
+
// src/registration/api.ts
|
|
4389
|
+
var DEFAULT_BASE_URL = "https://astrasync.ai";
|
|
4390
|
+
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
4391
|
+
var AstraSync = class {
|
|
4392
|
+
constructor(config = {}) {
|
|
4393
|
+
let raw = (config.baseUrl || process.env.ASTRASYNC_API_URL || DEFAULT_BASE_URL).replace(
|
|
4394
|
+
/\/+$/,
|
|
4395
|
+
""
|
|
4396
|
+
);
|
|
4397
|
+
if (raw.toLowerCase().endsWith("/api")) {
|
|
4398
|
+
raw = raw.slice(0, -"/api".length);
|
|
4399
|
+
if (config.baseUrl && !config.silent) {
|
|
4400
|
+
console.warn(
|
|
4401
|
+
`[AstraSync] baseUrl '${config.baseUrl}' had a trailing /api \u2014 stripped to '${raw}'. Pass the bare origin (e.g. 'https://astrasync.ai' or 'https://staging.astrasync.ai') to AstraSync(). The /api suffix is the verify-gateway (GatewayConfig.apiBaseUrl) convention.`
|
|
4402
|
+
);
|
|
4403
|
+
}
|
|
4404
|
+
}
|
|
4405
|
+
this.baseUrl = raw;
|
|
4406
|
+
this.apiKey = config.apiKey || process.env.ASTRASYNC_API_KEY;
|
|
4407
|
+
this.email = config.email;
|
|
4408
|
+
this.password = config.password;
|
|
4409
|
+
this.privateKey = config.privateKey;
|
|
4410
|
+
if (!this.apiKey && !this.email) {
|
|
4411
|
+
throw new AuthenticationError(
|
|
4412
|
+
"Authentication required. Provide apiKey, or email+password. Set ASTRASYNC_API_KEY env var or pass config to constructor."
|
|
4413
|
+
);
|
|
4414
|
+
}
|
|
4415
|
+
if (this.email && !this.password) {
|
|
4416
|
+
throw new AuthenticationError("Password is required when using email authentication.");
|
|
4417
|
+
}
|
|
4418
|
+
}
|
|
4419
|
+
/**
|
|
4420
|
+
* Register a new AI agent on the AstraSync KYA Platform.
|
|
4421
|
+
*
|
|
4422
|
+
* The backend response depends on auth context:
|
|
4423
|
+
* - **Crypto-keypair signed** (`privateKey` configured): synchronous 201,
|
|
4424
|
+
* returns `{ status: 'active', agent }`.
|
|
4425
|
+
* - **API-key only** (no signature): 202 pending, returns
|
|
4426
|
+
* `{ status: 'pending_approval', requestId, pollUrl, expiresAt }`. The
|
|
4427
|
+
* owner is notified by email and a dashboard alert is emitted; the agent
|
|
4428
|
+
* becomes active only after the owner approves.
|
|
4429
|
+
*
|
|
4430
|
+
* Blocking mode: pass `{ waitForApproval: true }` to have the SDK poll the
|
|
4431
|
+
* request until it resolves, then return the live agent record. The promise
|
|
4432
|
+
* rejects with `RegistrationDeniedError`, `RegistrationExpiredError`, or
|
|
4433
|
+
* `RegistrationTimeoutError` on the corresponding terminal states.
|
|
4434
|
+
*
|
|
4435
|
+
* @example Non-blocking (default — best for serverless / scheduled agents):
|
|
4436
|
+
* ```typescript
|
|
4437
|
+
* const result = await sdk.register({ name, pdlss });
|
|
4438
|
+
* if (result.status === 'pending_approval') {
|
|
4439
|
+
* storeRequestId(result.requestId);
|
|
4440
|
+
* return; // function exits; resume later via pollRegistration()
|
|
4441
|
+
* }
|
|
4442
|
+
* ```
|
|
4443
|
+
*
|
|
4444
|
+
* @example Blocking (best for long-running services + CLI):
|
|
4445
|
+
* ```typescript
|
|
4446
|
+
* const agent = await sdk.register({
|
|
4447
|
+
* name, pdlss, waitForApproval: true, timeoutMs: 600_000,
|
|
4448
|
+
* onPending: ({ ageMs }) => console.log(`waiting ${ageMs}ms`),
|
|
4449
|
+
* });
|
|
4450
|
+
* ```
|
|
4451
|
+
*/
|
|
4452
|
+
async register(options) {
|
|
4453
|
+
const body = {
|
|
4454
|
+
name: options.name,
|
|
4455
|
+
...options.description && { description: options.description },
|
|
4456
|
+
...options.agentType && { agentType: options.agentType },
|
|
4457
|
+
...options.apiEndpoint && { apiEndpoint: options.apiEndpoint },
|
|
4458
|
+
...options.model && { model: options.model },
|
|
4459
|
+
...options.framework && { framework: options.framework },
|
|
4460
|
+
...options.protocols && { protocols: options.protocols },
|
|
4461
|
+
...options.metadata && { metadata: options.metadata },
|
|
4462
|
+
...options.pdlss && { pdlss: options.pdlss }
|
|
4463
|
+
};
|
|
4464
|
+
const { status, body: raw } = await this.requestWithStatus("POST", "/api/agents/register", body);
|
|
4465
|
+
if (status === 201) {
|
|
4466
|
+
const activeBody = raw;
|
|
4467
|
+
const active = {
|
|
4468
|
+
status: "active",
|
|
4469
|
+
agent: activeBody.data.agent,
|
|
4470
|
+
// Round-12 (F16): pass backend advisories through verbatim.
|
|
4471
|
+
// Pre-fix the SDK whitelisted five fields and silently dropped
|
|
4472
|
+
// `warnings`, which left partners with no signal that
|
|
4473
|
+
// `no_callback_endpoint` (or future advisories) had fired.
|
|
4474
|
+
...activeBody.warnings && { warnings: activeBody.warnings }
|
|
4475
|
+
};
|
|
4476
|
+
return active;
|
|
4477
|
+
}
|
|
4478
|
+
const pendingBody = raw;
|
|
4479
|
+
const pending = {
|
|
4480
|
+
status: "pending_approval",
|
|
4481
|
+
requestId: pendingBody.requestId,
|
|
4482
|
+
expiresAt: pendingBody.expiresAt,
|
|
4483
|
+
pollUrl: pendingBody.pollUrl,
|
|
4484
|
+
message: pendingBody.message,
|
|
4485
|
+
// Round-12 (F16): same pass-through on the pending path.
|
|
4486
|
+
...pendingBody.warnings && { warnings: pendingBody.warnings }
|
|
4487
|
+
};
|
|
4488
|
+
if (!options.waitForApproval) return pending;
|
|
4489
|
+
return this.waitForApproval(pendingBody.requestId, options);
|
|
4490
|
+
}
|
|
4491
|
+
/**
|
|
4492
|
+
* Poll the current state of a pending-approval registration request.
|
|
4493
|
+
*
|
|
4494
|
+
* Useful for caller-driven polling when `waitForApproval: false` (the
|
|
4495
|
+
* default). The endpoint is unauthenticated — pass the `requestId` that
|
|
4496
|
+
* was returned from the 202 response.
|
|
4497
|
+
*
|
|
4498
|
+
* @returns `state: 'pending'` while awaiting; `'approved'` carries the
|
|
4499
|
+
* minted agent in `agent`; `'denied'` may carry the owner's
|
|
4500
|
+
* `reason`; `'expired'` is terminal after 14 days.
|
|
4501
|
+
*/
|
|
4502
|
+
async pollRegistration(requestId) {
|
|
4503
|
+
const url = `${this.baseUrl}/api/agents/request-registration/${requestId}`;
|
|
4504
|
+
const res = await fetch(url, { headers: { Accept: "application/json" } });
|
|
4505
|
+
if (!res.ok) {
|
|
4506
|
+
const errBody = await res.json().catch(() => ({}));
|
|
4507
|
+
throw new AstraSyncError(
|
|
4508
|
+
errBody.error || `pollRegistration failed: ${res.status}`,
|
|
4509
|
+
res.status,
|
|
4510
|
+
errBody.code
|
|
4511
|
+
);
|
|
4512
|
+
}
|
|
4513
|
+
return await res.json();
|
|
4514
|
+
}
|
|
4515
|
+
/**
|
|
4516
|
+
* Block until a pending registration request resolves to a terminal state.
|
|
4517
|
+
* Resolves to the live `AgentRecord` on approval; rejects with the matching
|
|
4518
|
+
* Registration*Error on deny/expire/timeout. Usually called via
|
|
4519
|
+
* `register({ waitForApproval: true })`, but exposed for callers that want
|
|
4520
|
+
* to fire-and-forget the initial register call and resume waiting later
|
|
4521
|
+
* (e.g. after restoring a stored `requestId` on cold start).
|
|
4522
|
+
*/
|
|
4523
|
+
async waitForApproval(requestId, options = {}) {
|
|
4524
|
+
const timeoutMs = options.timeoutMs ?? 10 * 60 * 1e3;
|
|
4525
|
+
const pollIntervalMs = options.pollIntervalMs ?? 5e3;
|
|
4526
|
+
const start = Date.now();
|
|
4527
|
+
const deadline = start + timeoutMs;
|
|
4528
|
+
while (Date.now() < deadline) {
|
|
4529
|
+
const result = await this.pollRegistration(requestId);
|
|
4530
|
+
const ageMs = Date.now() - start;
|
|
4531
|
+
options.onPending?.({ requestId, ageMs });
|
|
4532
|
+
if (result.state === "approved") {
|
|
4533
|
+
if (!result.agent) {
|
|
4534
|
+
throw new AstraSyncError(
|
|
4535
|
+
`Registration ${requestId} reported approved but no agent payload returned.`,
|
|
4536
|
+
500
|
|
4537
|
+
);
|
|
4538
|
+
}
|
|
4539
|
+
return result.agent;
|
|
4540
|
+
}
|
|
4541
|
+
if (result.state === "denied") {
|
|
4542
|
+
throw new RegistrationDeniedError(requestId, result.reason);
|
|
4543
|
+
}
|
|
4544
|
+
if (result.state === "expired") {
|
|
4545
|
+
throw new RegistrationExpiredError(requestId);
|
|
4546
|
+
}
|
|
4547
|
+
await sleep(pollIntervalMs);
|
|
4548
|
+
}
|
|
4549
|
+
throw new RegistrationTimeoutError(requestId);
|
|
4550
|
+
}
|
|
4551
|
+
/**
|
|
4552
|
+
* Look up an agent's public profile by ASTRA ID or UUID.
|
|
4553
|
+
*/
|
|
4554
|
+
async verify(agentId) {
|
|
4555
|
+
return this.request("GET", `/api/agents/verify/${agentId}`);
|
|
4556
|
+
}
|
|
4557
|
+
/**
|
|
4558
|
+
* Check API health.
|
|
4559
|
+
*/
|
|
4560
|
+
async health() {
|
|
4561
|
+
const res = await fetch(`${this.baseUrl}/api/health/`);
|
|
4562
|
+
if (!res.ok) {
|
|
4563
|
+
throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);
|
|
4564
|
+
}
|
|
4565
|
+
return res.json();
|
|
4566
|
+
}
|
|
4567
|
+
// ── Private helpers ──────────────────────────────────────────────
|
|
4568
|
+
async request(method, endpoint, body) {
|
|
4569
|
+
const { body: parsed } = await this.requestWithStatus(method, endpoint, body);
|
|
4570
|
+
return parsed;
|
|
4571
|
+
}
|
|
4572
|
+
/**
|
|
4573
|
+
* Variant of {@link request} that also returns the HTTP status code, so
|
|
4574
|
+
* callers can branch on 201 vs 202 (or other success codes) without losing
|
|
4575
|
+
* type information about the response body.
|
|
4576
|
+
*/
|
|
4577
|
+
async requestWithStatus(method, endpoint, body) {
|
|
4578
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
4579
|
+
const headers = {
|
|
4580
|
+
"Content-Type": "application/json"
|
|
4581
|
+
};
|
|
4582
|
+
const token = await this.getAuthToken();
|
|
4583
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
4584
|
+
if (this.privateKey) {
|
|
4585
|
+
const signature = await this.signRequest(method, endpoint, body || {});
|
|
4586
|
+
headers["X-AstraSync-Signature"] = signature;
|
|
4587
|
+
}
|
|
4588
|
+
const res = await fetch(url, {
|
|
4589
|
+
method,
|
|
4590
|
+
headers,
|
|
4591
|
+
...body ? { body: JSON.stringify(body) } : {}
|
|
4592
|
+
});
|
|
4593
|
+
if (!res.ok) {
|
|
4594
|
+
const errorBody = await res.json().catch(() => ({ error: res.statusText }));
|
|
4595
|
+
if (res.status === 403 && errorBody.code === "KYD_REQUIRED") {
|
|
4596
|
+
throw new KYDRequiredError(errorBody);
|
|
4597
|
+
}
|
|
4598
|
+
throw new AstraSyncError(
|
|
4599
|
+
errorBody.error || `Request failed: ${res.status}`,
|
|
4600
|
+
res.status,
|
|
4601
|
+
errorBody.code
|
|
4602
|
+
);
|
|
4603
|
+
}
|
|
4604
|
+
return { status: res.status, body: await res.json() };
|
|
4605
|
+
}
|
|
4606
|
+
async getAuthToken() {
|
|
4607
|
+
if (this.apiKey) {
|
|
4608
|
+
return this.apiKey;
|
|
4609
|
+
}
|
|
4610
|
+
if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {
|
|
4611
|
+
return this.cachedJwt;
|
|
4612
|
+
}
|
|
4613
|
+
const res = await fetch(`${this.baseUrl}/api/auth/login`, {
|
|
4614
|
+
method: "POST",
|
|
4615
|
+
headers: { "Content-Type": "application/json" },
|
|
4616
|
+
body: JSON.stringify({ email: this.email, password: this.password })
|
|
4617
|
+
});
|
|
4618
|
+
if (!res.ok) {
|
|
4619
|
+
const errorBody = await res.json().catch(() => ({}));
|
|
4620
|
+
throw new AuthenticationError(
|
|
4621
|
+
errorBody.message || errorBody.error || "Login failed"
|
|
4622
|
+
);
|
|
4623
|
+
}
|
|
4624
|
+
const data = await res.json();
|
|
4625
|
+
this.cachedJwt = data.data.token;
|
|
4626
|
+
this.jwtExpiresAt = Date.now() + 6 * 24 * 60 * 60 * 1e3;
|
|
4627
|
+
return this.cachedJwt;
|
|
4628
|
+
}
|
|
4629
|
+
/**
|
|
4630
|
+
* Sign a request using secp256k1 (ethers.js).
|
|
4631
|
+
* Canonical message format: METHOD:ENDPOINT:SORTED_JSON_BODY
|
|
4632
|
+
* Must match apps/backend/src/services/signature-verify.service.ts exactly.
|
|
4633
|
+
*/
|
|
4634
|
+
async signRequest(method, endpoint, body) {
|
|
4635
|
+
const { Wallet } = await import("ethers");
|
|
4636
|
+
const sorted = this.sortObjectKeys(body);
|
|
4637
|
+
const canonical = `${method}:${endpoint}:${JSON.stringify(sorted)}`;
|
|
4638
|
+
const wallet = new Wallet(this.privateKey);
|
|
4639
|
+
return wallet.signMessage(canonical);
|
|
4640
|
+
}
|
|
4641
|
+
/** Recursively sort object keys for canonical JSON representation. */
|
|
4642
|
+
sortObjectKeys(obj) {
|
|
4643
|
+
if (obj === null || typeof obj !== "object") {
|
|
4644
|
+
return obj;
|
|
4645
|
+
}
|
|
4646
|
+
if (Array.isArray(obj)) {
|
|
4647
|
+
return obj.map((item) => this.sortObjectKeys(item));
|
|
4648
|
+
}
|
|
4649
|
+
const sorted = {};
|
|
4650
|
+
for (const key of Object.keys(obj).sort()) {
|
|
4651
|
+
sorted[key] = this.sortObjectKeys(obj[key]);
|
|
4652
|
+
}
|
|
4653
|
+
return sorted;
|
|
4654
|
+
}
|
|
4655
|
+
};
|
|
4656
|
+
|
|
3952
4657
|
// src/agent/index.ts
|
|
3953
4658
|
var agent_exports = {};
|
|
3954
4659
|
__export(agent_exports, {
|
|
@@ -4270,15 +4975,24 @@ var VERSION = "2.0.0";
|
|
|
4270
4975
|
ACCESS_LEVEL_DESCRIPTIONS,
|
|
4271
4976
|
ACCESS_LEVEL_HIERARCHY,
|
|
4272
4977
|
AgentClient,
|
|
4978
|
+
AstraSync,
|
|
4979
|
+
AstraSyncError,
|
|
4980
|
+
AuthenticationError,
|
|
4273
4981
|
ChallengeHandler,
|
|
4274
4982
|
DEFAULT_TRUST_THRESHOLDS,
|
|
4983
|
+
KYDRequiredError,
|
|
4984
|
+
RegistrationDeniedError,
|
|
4985
|
+
RegistrationExpiredError,
|
|
4986
|
+
RegistrationTimeoutError,
|
|
4275
4987
|
TRUST_LEVEL_RANGES,
|
|
4276
4988
|
VERSION,
|
|
4277
4989
|
agent,
|
|
4278
4990
|
clearCache,
|
|
4991
|
+
createMcpMiddleware,
|
|
4279
4992
|
determineAccessLevel,
|
|
4280
4993
|
express,
|
|
4281
4994
|
extractCredentials,
|
|
4995
|
+
extractMcpCredentials,
|
|
4282
4996
|
getAccessLevelForScore,
|
|
4283
4997
|
getCapabilities,
|
|
4284
4998
|
getTrustLevel,
|
|
@@ -4288,6 +5002,7 @@ var VERSION = "2.0.0";
|
|
|
4288
5002
|
quickVerify,
|
|
4289
5003
|
recordDecision,
|
|
4290
5004
|
sdk,
|
|
5005
|
+
setMcpMeta,
|
|
4291
5006
|
transport,
|
|
4292
5007
|
verify
|
|
4293
5008
|
});
|