@astrasyncai/verification-gateway 2.4.14 → 2.5.1
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 +107 -15
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +107 -15
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +75 -53
- package/dist/adapters/mcp.d.ts +75 -53
- package/dist/adapters/mcp.js +128 -23
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +128 -23
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.js +24 -14
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +24 -14
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.js +23 -13
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +23 -13
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/browser/background.js +23 -13
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +23 -13
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cursor/extension.js +23 -13
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +23 -13
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/gateway/gateway.js +23 -13
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +23 -13
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/index.d.mts +32 -2
- package/dist/index.d.ts +32 -2
- package/dist/index.js +180 -39
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +177 -39
- package/dist/index.mjs.map +1 -1
- package/dist/registration/index.js +7 -7
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +7 -7
- package/dist/registration/index.mjs.map +1 -1
- package/dist/ui/index.js +2 -2
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/index.mjs +2 -2
- package/dist/ui/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -128,6 +128,65 @@ function getCapabilities(accessLevel) {
|
|
|
128
128
|
// src/version.ts
|
|
129
129
|
var SDK_VERSION = "2.4.13";
|
|
130
130
|
|
|
131
|
+
// src/well-known.ts
|
|
132
|
+
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
133
|
+
var cache = /* @__PURE__ */ new Map();
|
|
134
|
+
var inflight = /* @__PURE__ */ new Map();
|
|
135
|
+
function wellKnownUrl(apiBaseUrl) {
|
|
136
|
+
const base = apiBaseUrl.replace(/\/api\/?$/, "");
|
|
137
|
+
return `${base}/.well-known/agentic-commerce`;
|
|
138
|
+
}
|
|
139
|
+
async function fetchWellKnown(apiBaseUrl) {
|
|
140
|
+
const url = wellKnownUrl(apiBaseUrl);
|
|
141
|
+
const response = await fetch(url, {
|
|
142
|
+
method: "GET",
|
|
143
|
+
headers: { Accept: "application/json" },
|
|
144
|
+
signal: AbortSignal.timeout(5e3)
|
|
145
|
+
});
|
|
146
|
+
if (!response.ok) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
`AstraSync platform must expose /.well-known/agentic-commerce; got ${response.status} from ${url}. SDK cannot initialise without it.`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
const data = await response.json();
|
|
152
|
+
if (!data.registrationUrl || !data.documentationUrl || !data.verifyAccessUrl) {
|
|
153
|
+
throw new Error(
|
|
154
|
+
`/.well-known/agentic-commerce response missing required fields (registrationUrl, documentationUrl, verifyAccessUrl).`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
return data;
|
|
158
|
+
}
|
|
159
|
+
function prefetchWellKnown(apiBaseUrl) {
|
|
160
|
+
const existing = inflight.get(apiBaseUrl);
|
|
161
|
+
if (existing) return existing;
|
|
162
|
+
const promise = fetchWellKnown(apiBaseUrl).then((data) => {
|
|
163
|
+
cache.set(apiBaseUrl, { data, fetchedAt: Date.now() });
|
|
164
|
+
inflight.delete(apiBaseUrl);
|
|
165
|
+
return data;
|
|
166
|
+
}).catch((err) => {
|
|
167
|
+
inflight.delete(apiBaseUrl);
|
|
168
|
+
throw err;
|
|
169
|
+
});
|
|
170
|
+
inflight.set(apiBaseUrl, promise);
|
|
171
|
+
return promise;
|
|
172
|
+
}
|
|
173
|
+
async function getWellKnownUrls(apiBaseUrl) {
|
|
174
|
+
const entry = cache.get(apiBaseUrl);
|
|
175
|
+
if (entry) {
|
|
176
|
+
if (Date.now() - entry.fetchedAt > CACHE_TTL_MS) {
|
|
177
|
+
prefetchWellKnown(apiBaseUrl).catch(() => {
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return entry.data;
|
|
181
|
+
}
|
|
182
|
+
const pending = inflight.get(apiBaseUrl);
|
|
183
|
+
if (pending) return pending;
|
|
184
|
+
return prefetchWellKnown(apiBaseUrl);
|
|
185
|
+
}
|
|
186
|
+
function getCachedWellKnownUrls(apiBaseUrl) {
|
|
187
|
+
return cache.get(apiBaseUrl)?.data;
|
|
188
|
+
}
|
|
189
|
+
|
|
131
190
|
// src/verify.ts
|
|
132
191
|
var DEFAULT_CONFIG = {
|
|
133
192
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -269,21 +328,22 @@ function extractCredentials(headers, query) {
|
|
|
269
328
|
function hasCredentials(credentials) {
|
|
270
329
|
return !!(credentials.astraId || credentials.apiKey || credentials.jwt);
|
|
271
330
|
}
|
|
272
|
-
function createGuidanceResponse(
|
|
331
|
+
function createGuidanceResponse(_config, reason, options = {}) {
|
|
273
332
|
const source = options.source ?? "no_credentials";
|
|
274
333
|
const isApiError = source === "api_error";
|
|
334
|
+
const urls = options.urls;
|
|
275
335
|
const guidance = isApiError ? {
|
|
276
336
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
277
|
-
registrationUrl:
|
|
278
|
-
documentationUrl:
|
|
337
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
338
|
+
documentationUrl: urls?.documentationUrl ?? "",
|
|
279
339
|
steps: [
|
|
280
340
|
"Retry the request with exponential backoff",
|
|
281
341
|
"If failures persist, share the correlationId with support"
|
|
282
342
|
]
|
|
283
343
|
} : {
|
|
284
344
|
message: "This service verifies AI agents before granting access. Please register your agent with AstraSync.",
|
|
285
|
-
registrationUrl:
|
|
286
|
-
documentationUrl:
|
|
345
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
346
|
+
documentationUrl: urls?.documentationUrl ?? "",
|
|
287
347
|
steps: [
|
|
288
348
|
"Register for an AstraSync account",
|
|
289
349
|
"Create and register your agent",
|
|
@@ -325,7 +385,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
325
385
|
const { credentials, ...requestData } = request;
|
|
326
386
|
const body = {
|
|
327
387
|
...credentials.astraId && { agentId: credentials.astraId },
|
|
328
|
-
purpose: requestData.purpose
|
|
388
|
+
...requestData.purpose && { purpose: requestData.purpose }
|
|
329
389
|
};
|
|
330
390
|
if (requestData.action) body.action = requestData.action;
|
|
331
391
|
if (requestData.resourceType) body.resourceType = requestData.resourceType;
|
|
@@ -405,6 +465,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
405
465
|
}
|
|
406
466
|
async function verify(config, request) {
|
|
407
467
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
468
|
+
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
408
469
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
409
470
|
if (mergedConfig.strictInit) {
|
|
410
471
|
await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
|
|
@@ -441,7 +502,8 @@ async function verify(config, request) {
|
|
|
441
502
|
if (!apiResponse.success) {
|
|
442
503
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
443
504
|
source: "api_error",
|
|
444
|
-
correlationId: apiResponse.correlationId
|
|
505
|
+
correlationId: apiResponse.correlationId,
|
|
506
|
+
urls
|
|
445
507
|
});
|
|
446
508
|
}
|
|
447
509
|
if (!apiResponse.access?.allowed) {
|
|
@@ -464,8 +526,8 @@ async function verify(config, request) {
|
|
|
464
526
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
465
527
|
guidance: {
|
|
466
528
|
message: apiResponse.access?.reason || "Access denied by PDLSS policy",
|
|
467
|
-
registrationUrl:
|
|
468
|
-
documentationUrl:
|
|
529
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
530
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
469
531
|
},
|
|
470
532
|
verifiedAt: /* @__PURE__ */ new Date(),
|
|
471
533
|
// Extract sessionId so decisions can be recorded for denials too
|
|
@@ -536,12 +598,12 @@ async function verify(config, request) {
|
|
|
536
598
|
];
|
|
537
599
|
result.guidance = result.runtimeChallenge ? {
|
|
538
600
|
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
539
|
-
registrationUrl:
|
|
540
|
-
documentationUrl:
|
|
601
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
602
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
541
603
|
} : {
|
|
542
604
|
message: result.recommendationReasons?.[0] || "Access denied by AstraSync recommendation",
|
|
543
|
-
registrationUrl:
|
|
544
|
-
documentationUrl:
|
|
605
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
606
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
545
607
|
};
|
|
546
608
|
} else if (result.recommendation === "step_up_required") {
|
|
547
609
|
result.requiresStepUp = true;
|
|
@@ -824,6 +886,9 @@ function dedupeFailures(result) {
|
|
|
824
886
|
return true;
|
|
825
887
|
});
|
|
826
888
|
}
|
|
889
|
+
if (result.denialReasons && result.denialReasons.length > 1) {
|
|
890
|
+
result.denialReasons = [...new Set(result.denialReasons)];
|
|
891
|
+
}
|
|
827
892
|
}
|
|
828
893
|
function defaultOnDenied(result, _req, res) {
|
|
829
894
|
const statusCode = !result.identityVerified ? 401 : 403;
|
|
@@ -855,6 +920,10 @@ function createMiddleware(options) {
|
|
|
855
920
|
caseInsensitiveRouteMatch = false,
|
|
856
921
|
...config
|
|
857
922
|
} = options;
|
|
923
|
+
if (config.apiBaseUrl) {
|
|
924
|
+
prefetchWellKnown(config.apiBaseUrl).catch(() => {
|
|
925
|
+
});
|
|
926
|
+
}
|
|
858
927
|
let cachedRoutes = [];
|
|
859
928
|
let lastFetchAt = 0;
|
|
860
929
|
let refreshing = null;
|
|
@@ -917,6 +986,7 @@ function createMiddleware(options) {
|
|
|
917
986
|
}
|
|
918
987
|
return next();
|
|
919
988
|
}
|
|
989
|
+
const wellKnownUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
920
990
|
const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
|
|
921
991
|
const shouldEnforce = routeConfig.minAccessLevel !== "none";
|
|
922
992
|
if (routeConfig.minAccessLevel === "none" && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
|
|
@@ -938,8 +1008,8 @@ function createMiddleware(options) {
|
|
|
938
1008
|
denialReasons: preCheckFailures.map((f) => f.message),
|
|
939
1009
|
guidance: {
|
|
940
1010
|
message: "Request exceeds counterparty-defined PDLSS limits.",
|
|
941
|
-
registrationUrl:
|
|
942
|
-
documentationUrl:
|
|
1011
|
+
registrationUrl: wellKnownUrls?.registrationUrl ?? "",
|
|
1012
|
+
documentationUrl: wellKnownUrls?.documentationUrl ?? ""
|
|
943
1013
|
},
|
|
944
1014
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
945
1015
|
};
|
|
@@ -1019,6 +1089,13 @@ function createMiddleware(options) {
|
|
|
1019
1089
|
};
|
|
1020
1090
|
result.failures = [...result.failures ?? [], insufficientFailure];
|
|
1021
1091
|
result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
|
|
1092
|
+
if (!result.guidance && wellKnownUrls) {
|
|
1093
|
+
result.guidance = {
|
|
1094
|
+
message: insufficientFailure.message,
|
|
1095
|
+
registrationUrl: wellKnownUrls.registrationUrl,
|
|
1096
|
+
documentationUrl: wellKnownUrls.documentationUrl
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1022
1099
|
if (shouldRecordDecisions && sessionId) {
|
|
1023
1100
|
recordDecision(config, sessionId, "denied", insufficientFailure.message).catch(() => {
|
|
1024
1101
|
});
|
|
@@ -1036,6 +1113,13 @@ function createMiddleware(options) {
|
|
|
1036
1113
|
};
|
|
1037
1114
|
result.failures = [...result.failures ?? [], trustFailure];
|
|
1038
1115
|
result.denialReasons = [trustFailure.message];
|
|
1116
|
+
if (!result.guidance && wellKnownUrls) {
|
|
1117
|
+
result.guidance = {
|
|
1118
|
+
message: trustFailure.message,
|
|
1119
|
+
registrationUrl: wellKnownUrls.registrationUrl,
|
|
1120
|
+
documentationUrl: wellKnownUrls.documentationUrl
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1039
1123
|
if (shouldRecordDecisions && sessionId) {
|
|
1040
1124
|
recordDecision(config, sessionId, "denied", trustFailure.message).catch(() => {
|
|
1041
1125
|
});
|
|
@@ -1076,6 +1160,14 @@ function createMiddleware(options) {
|
|
|
1076
1160
|
verifiedAt: /* @__PURE__ */ new Date(),
|
|
1077
1161
|
correlationId
|
|
1078
1162
|
};
|
|
1163
|
+
const catchUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
1164
|
+
if (catchUrls) {
|
|
1165
|
+
result.guidance = {
|
|
1166
|
+
message: `Middleware threw ${errorClass} \u2014 failing closed`,
|
|
1167
|
+
registrationUrl: catchUrls.registrationUrl,
|
|
1168
|
+
documentationUrl: catchUrls.documentationUrl
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1079
1171
|
dedupeFailures(result);
|
|
1080
1172
|
return onDenied(result, req, res);
|
|
1081
1173
|
}
|
|
@@ -1179,7 +1271,7 @@ function generateCommerceShieldHtml(result, options) {
|
|
|
1179
1271
|
);
|
|
1180
1272
|
const registrationUrl = sanitizeUrl(
|
|
1181
1273
|
result.guidance?.registrationUrl,
|
|
1182
|
-
"https://astrasync.ai/register"
|
|
1274
|
+
"https://astrasync.ai/agents/register"
|
|
1183
1275
|
);
|
|
1184
1276
|
const docsUrl = sanitizeUrl(
|
|
1185
1277
|
result.guidance?.documentationUrl,
|
|
@@ -4083,7 +4175,7 @@ async function exportJwkFromKeyLike(keyLike) {
|
|
|
4083
4175
|
|
|
4084
4176
|
// src/transport/registry/mastercard.ts
|
|
4085
4177
|
function createMastercardRegistry(options = {}) {
|
|
4086
|
-
const
|
|
4178
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
4087
4179
|
const ttlSec = options.cacheTtlSec ?? 3600;
|
|
4088
4180
|
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
4089
4181
|
let warned = false;
|
|
@@ -4100,7 +4192,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4100
4192
|
}
|
|
4101
4193
|
return null;
|
|
4102
4194
|
}
|
|
4103
|
-
const cached =
|
|
4195
|
+
const cached = cache2.get(kid);
|
|
4104
4196
|
if (cached && cached.expiresAt > Date.now()) return cached.jwk;
|
|
4105
4197
|
try {
|
|
4106
4198
|
const res = await fetchFn(options.registryUrl);
|
|
@@ -4109,7 +4201,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4109
4201
|
const keys = body.keys ?? [];
|
|
4110
4202
|
for (const k of keys) {
|
|
4111
4203
|
if (k.kid === kid) {
|
|
4112
|
-
|
|
4204
|
+
cache2.set(kid, { jwk: k, expiresAt: Date.now() + ttlSec * 1e3 });
|
|
4113
4205
|
return k;
|
|
4114
4206
|
}
|
|
4115
4207
|
}
|
|
@@ -4124,7 +4216,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4124
4216
|
// src/transport/registry/web-bot-auth.ts
|
|
4125
4217
|
var DIRECTORY_PATH = "/.well-known/http-message-signatures-directory";
|
|
4126
4218
|
function createWebBotAuthRegistry(options = {}) {
|
|
4127
|
-
const
|
|
4219
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
4128
4220
|
const ttlSec = options.cacheTtlSec ?? 3600;
|
|
4129
4221
|
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
4130
4222
|
return {
|
|
@@ -4133,7 +4225,7 @@ function createWebBotAuthRegistry(options = {}) {
|
|
|
4133
4225
|
if (!kid) return null;
|
|
4134
4226
|
const directoryUrl = resolveDirectoryUrl(options.directoryUrl, context?.origin);
|
|
4135
4227
|
if (!directoryUrl) return null;
|
|
4136
|
-
const cached =
|
|
4228
|
+
const cached = cache2.get(directoryUrl);
|
|
4137
4229
|
const now = Date.now();
|
|
4138
4230
|
if (cached && cached.expiresAt > now) {
|
|
4139
4231
|
return findKeyByKid(cached.keys, kid);
|
|
@@ -4143,7 +4235,7 @@ function createWebBotAuthRegistry(options = {}) {
|
|
|
4143
4235
|
if (!res.ok) return null;
|
|
4144
4236
|
const body = await res.json();
|
|
4145
4237
|
const keys = body.keys ?? [];
|
|
4146
|
-
|
|
4238
|
+
cache2.set(directoryUrl, { keys, expiresAt: now + ttlSec * 1e3 });
|
|
4147
4239
|
return findKeyByKid(keys, kid);
|
|
4148
4240
|
} catch {
|
|
4149
4241
|
return null;
|
|
@@ -4282,19 +4374,22 @@ function extractFromMcpBody(astrasyncMeta, args, key) {
|
|
|
4282
4374
|
}
|
|
4283
4375
|
return { value: void 0, source: void 0 };
|
|
4284
4376
|
}
|
|
4285
|
-
function mcpToPdlss(parsed, headerPurpose, headerAction) {
|
|
4286
|
-
const resource =
|
|
4377
|
+
function mcpToPdlss(parsed, requestPath, headerPurpose, headerAction, toolGate) {
|
|
4378
|
+
const resource = toolGate?.resource ?? requestPath;
|
|
4287
4379
|
let purpose;
|
|
4288
4380
|
let purposeSource;
|
|
4289
|
-
if (
|
|
4381
|
+
if (toolGate?.purpose !== void 0) {
|
|
4382
|
+
purpose = toolGate.purpose;
|
|
4383
|
+
purposeSource = "tool_gate";
|
|
4384
|
+
} else if (headerPurpose) {
|
|
4290
4385
|
purpose = headerPurpose;
|
|
4291
4386
|
purposeSource = "header";
|
|
4292
4387
|
} else if (parsed.purposeFromBody && parsed.purposeSourceFromBody) {
|
|
4293
4388
|
purpose = parsed.purposeFromBody;
|
|
4294
4389
|
purposeSource = parsed.purposeSourceFromBody;
|
|
4295
4390
|
} else {
|
|
4296
|
-
purpose =
|
|
4297
|
-
purposeSource =
|
|
4391
|
+
purpose = void 0;
|
|
4392
|
+
purposeSource = void 0;
|
|
4298
4393
|
}
|
|
4299
4394
|
let action;
|
|
4300
4395
|
let actionSource;
|
|
@@ -4319,6 +4414,9 @@ function mcpRiskTier(parsed) {
|
|
|
4319
4414
|
}
|
|
4320
4415
|
|
|
4321
4416
|
// src/adapters/mcp.ts
|
|
4417
|
+
function normalizeToolGate(gate) {
|
|
4418
|
+
return typeof gate === "string" ? { minAccessLevel: gate } : gate;
|
|
4419
|
+
}
|
|
4322
4420
|
function readSingleHeader(value) {
|
|
4323
4421
|
if (typeof value === "string") return value;
|
|
4324
4422
|
if (Array.isArray(value)) return value[0];
|
|
@@ -4334,6 +4432,9 @@ function dedupeFailures2(result) {
|
|
|
4334
4432
|
return true;
|
|
4335
4433
|
});
|
|
4336
4434
|
}
|
|
4435
|
+
if (result.denialReasons && result.denialReasons.length > 1) {
|
|
4436
|
+
result.denialReasons = [...new Set(result.denialReasons)];
|
|
4437
|
+
}
|
|
4337
4438
|
}
|
|
4338
4439
|
function defaultMcpDenied(result, req, res) {
|
|
4339
4440
|
const id = req.body?.id ?? null;
|
|
@@ -4359,11 +4460,17 @@ function defaultMcpDenied(result, req, res) {
|
|
|
4359
4460
|
});
|
|
4360
4461
|
}
|
|
4361
4462
|
function resolveMinAccessLevel(parsed, opts) {
|
|
4362
|
-
if (parsed.toolName
|
|
4363
|
-
|
|
4463
|
+
if (!parsed.toolName) {
|
|
4464
|
+
if (opts.methodGates && opts.methodGates[parsed.method] !== void 0) {
|
|
4465
|
+
return { level: opts.methodGates[parsed.method], source: "methodGate" };
|
|
4466
|
+
}
|
|
4467
|
+
return { level: "none", source: "discovery_default" };
|
|
4364
4468
|
}
|
|
4365
|
-
if (opts.
|
|
4366
|
-
return {
|
|
4469
|
+
if (opts.toolGates && opts.toolGates[parsed.toolName] !== void 0) {
|
|
4470
|
+
return {
|
|
4471
|
+
level: normalizeToolGate(opts.toolGates[parsed.toolName]).minAccessLevel,
|
|
4472
|
+
source: "toolGate"
|
|
4473
|
+
};
|
|
4367
4474
|
}
|
|
4368
4475
|
return { level: mcpRiskTier(parsed), source: "tier" };
|
|
4369
4476
|
}
|
|
@@ -4381,6 +4488,10 @@ function createMcpMiddleware(options) {
|
|
|
4381
4488
|
failOnError = "open",
|
|
4382
4489
|
...config
|
|
4383
4490
|
} = options;
|
|
4491
|
+
if (config.apiBaseUrl) {
|
|
4492
|
+
prefetchWellKnown(config.apiBaseUrl).catch(() => {
|
|
4493
|
+
});
|
|
4494
|
+
}
|
|
4384
4495
|
return async (req, res, next) => {
|
|
4385
4496
|
try {
|
|
4386
4497
|
if (skip) return next();
|
|
@@ -4393,6 +4504,7 @@ function createMcpMiddleware(options) {
|
|
|
4393
4504
|
return next();
|
|
4394
4505
|
}
|
|
4395
4506
|
req.mcpRequest = parsed;
|
|
4507
|
+
const wellKnownUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
4396
4508
|
const headerRaw = req.headers["x-astra-id"] ?? req.headers["x-astra-agentid"];
|
|
4397
4509
|
const headerAstraId = typeof headerRaw === "string" ? headerRaw : Array.isArray(headerRaw) ? headerRaw[0] : void 0;
|
|
4398
4510
|
const bodyAstraId = parsed.agentIdFromBody;
|
|
@@ -4446,9 +4558,17 @@ function createMcpMiddleware(options) {
|
|
|
4446
4558
|
}
|
|
4447
4559
|
return next();
|
|
4448
4560
|
}
|
|
4561
|
+
const rawGate = parsed.toolName && toolGates?.[parsed.toolName];
|
|
4562
|
+
const gate = rawGate ? normalizeToolGate(rawGate) : void 0;
|
|
4449
4563
|
const headerPurpose = readSingleHeader(req.headers["x-astra-purpose"]);
|
|
4450
4564
|
const headerAction = readSingleHeader(req.headers["x-astra-action"]);
|
|
4451
|
-
const pdlss = mcpToPdlss(
|
|
4565
|
+
const pdlss = mcpToPdlss(
|
|
4566
|
+
parsed,
|
|
4567
|
+
req.path,
|
|
4568
|
+
headerPurpose,
|
|
4569
|
+
headerAction,
|
|
4570
|
+
gate ? { purpose: gate.purpose, resource: gate.resource } : void 0
|
|
4571
|
+
);
|
|
4452
4572
|
if (config.debug) {
|
|
4453
4573
|
console.debug("[mcp-middleware] pdlss resolved", {
|
|
4454
4574
|
purpose_source: pdlss.purposeSource,
|
|
@@ -4509,6 +4629,13 @@ function createMcpMiddleware(options) {
|
|
|
4509
4629
|
};
|
|
4510
4630
|
result.failures = [...result.failures ?? [], insufficientFailure];
|
|
4511
4631
|
result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
|
|
4632
|
+
if (!result.guidance && wellKnownUrls) {
|
|
4633
|
+
result.guidance = {
|
|
4634
|
+
message: insufficientFailure.message,
|
|
4635
|
+
registrationUrl: wellKnownUrls.registrationUrl,
|
|
4636
|
+
documentationUrl: wellKnownUrls.documentationUrl
|
|
4637
|
+
};
|
|
4638
|
+
}
|
|
4512
4639
|
if (shouldRecordDecisions) {
|
|
4513
4640
|
const overrideKind = gateSource === "toolGate" ? "toolGate" : gateSource === "methodGate" ? "methodGate" : "other";
|
|
4514
4641
|
const override = {
|
|
@@ -4577,6 +4704,14 @@ function createMcpMiddleware(options) {
|
|
|
4577
4704
|
verifiedAt: /* @__PURE__ */ new Date(),
|
|
4578
4705
|
correlationId
|
|
4579
4706
|
};
|
|
4707
|
+
const catchUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
4708
|
+
if (catchUrls) {
|
|
4709
|
+
result.guidance = {
|
|
4710
|
+
message: `Middleware threw ${errorClass} \u2014 failing closed`,
|
|
4711
|
+
registrationUrl: catchUrls.registrationUrl,
|
|
4712
|
+
documentationUrl: catchUrls.documentationUrl
|
|
4713
|
+
};
|
|
4714
|
+
}
|
|
4580
4715
|
dedupeFailures2(result);
|
|
4581
4716
|
return onDenied(result, req, res);
|
|
4582
4717
|
}
|
|
@@ -4932,15 +5067,15 @@ function buildGuidance(params) {
|
|
|
4932
5067
|
status: "credentials_required",
|
|
4933
5068
|
message,
|
|
4934
5069
|
guidance: {
|
|
4935
|
-
message: "
|
|
4936
|
-
registrationUrl: `${origin}/register`,
|
|
5070
|
+
message: "Register either with an agent-scoped API key (the recommended credentialed path) OR, if you hold no credentials, via the owner's email using request_registration. Never send a password or private key over the wire.",
|
|
5071
|
+
registrationUrl: `${origin}/agents/register`,
|
|
4937
5072
|
documentationUrl: `${origin}${docsPath.startsWith("/") ? docsPath : `/${docsPath}`}`,
|
|
4938
5073
|
steps: [
|
|
4939
|
-
"
|
|
4940
|
-
"
|
|
4941
|
-
"
|
|
4942
|
-
"
|
|
4943
|
-
"
|
|
5074
|
+
"Credentialed path (recommended): have your human mint an agent-scoped API key at Settings \u2192 API Keys, then re-call register_agent with apiKey set. An agent holding its own scoped kya_ key is fine and intended.",
|
|
5075
|
+
"No-credentials path: call request_registration({ name, ownerEmail, ... }) with the human owner's email \u2014 the only bootstrap credential. No API key is involved.",
|
|
5076
|
+
"The owner approves via an emailed link (first time, they create an account and complete a quick verification).",
|
|
5077
|
+
"Use poll_registration({ requestId }) once the owner confirms approval to retrieve the astraId.",
|
|
5078
|
+
"Never transmit a password or private key over the MCP wire \u2014 those are never required."
|
|
4944
5079
|
]
|
|
4945
5080
|
}
|
|
4946
5081
|
};
|
|
@@ -5286,11 +5421,14 @@ export {
|
|
|
5286
5421
|
extractCredentials,
|
|
5287
5422
|
extractMcpCredentials,
|
|
5288
5423
|
getAccessLevelForScore,
|
|
5424
|
+
getCachedWellKnownUrls,
|
|
5289
5425
|
getCapabilities,
|
|
5290
5426
|
getTrustLevel,
|
|
5427
|
+
getWellKnownUrls,
|
|
5291
5428
|
hasCredentials,
|
|
5292
5429
|
hasMinimumAccess,
|
|
5293
5430
|
nextjs_exports as nextjs,
|
|
5431
|
+
prefetchWellKnown,
|
|
5294
5432
|
quickVerify,
|
|
5295
5433
|
recordDecision2 as recordDecision,
|
|
5296
5434
|
sdk_exports as sdk,
|