@astrasyncai/verification-gateway 2.4.14 → 2.5.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/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 +23 -13
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +23 -13
- 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 +172 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +169 -31
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ export { A as ACCESS_LEVEL_DESCRIPTIONS, a as ACCESS_LEVEL_HIERARCHY, b as Acces
|
|
|
4
4
|
export { e as express } from './express-ienhAXps.mjs';
|
|
5
5
|
export { n as nextjs } from './nextjs-DSpisQst.mjs';
|
|
6
6
|
export { aR as extractMcpCredentials, bg as setMcpMeta, b1 as transport } from './index-CEg_WG6y.mjs';
|
|
7
|
-
export { McpMiddlewareOptions, createMcpMiddleware } from './adapters/mcp.mjs';
|
|
7
|
+
export { McpMiddlewareOptions, ToolGateConfig, createMcpMiddleware } from './adapters/mcp.mjs';
|
|
8
8
|
export { AgentProtocol, AgentRecord, AstraSync, AstraSyncConfig, AstraSyncError, AuthenticationError, BuildGuidanceParams, FrameworkConfig, GuidanceEnvelope, HealthResponse, KYDRequiredError, ModelConfig, PDLSSConfig, PDLSSDuration, PDLSSLimits, PDLSSPurpose, PDLSSScope, PDLSSSelfInstantiation, PendingRegistrationResponse, PollRegistrationResult, RegisterOptions, RegisterResult, RegistrationDeniedError, RegistrationExpiredError, RegistrationResponse, RegistrationTimeoutError, VerifyResponse, WaitForApprovalOptions, buildGuidance } from './registration/index.mjs';
|
|
9
9
|
export { A as AgentClient, C as ChallengeHandler, i as agent, r as recordDecision } from './index-B5e2IDWU.mjs';
|
|
10
10
|
import 'express';
|
|
@@ -50,6 +50,36 @@ declare function quickVerify(config: GatewayConfig, credentials: AgentCredential
|
|
|
50
50
|
reason?: string;
|
|
51
51
|
}>;
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* SDK-side discovery of canonical platform URLs via `/.well-known/agentic-commerce`.
|
|
55
|
+
*
|
|
56
|
+
* Fire-and-forget pre-fetch at middleware creation; first verify() awaits
|
|
57
|
+
* the in-flight promise if it hasn't resolved. 60-minute TTL with
|
|
58
|
+
* stale-while-revalidate background refresh.
|
|
59
|
+
*/
|
|
60
|
+
interface WellKnownAgenticCommerce {
|
|
61
|
+
registrationUrl: string;
|
|
62
|
+
documentationUrl: string;
|
|
63
|
+
verifyAccessUrl: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Start a background fetch. Returns the promise for callers that need
|
|
67
|
+
* to await it (first verify() call).
|
|
68
|
+
*/
|
|
69
|
+
declare function prefetchWellKnown(apiBaseUrl: string): Promise<WellKnownAgenticCommerce>;
|
|
70
|
+
/**
|
|
71
|
+
* Get cached well-known URLs. If stale, triggers a background refresh
|
|
72
|
+
* and returns stale data (stale-while-revalidate). If no cache exists,
|
|
73
|
+
* awaits the in-flight fetch or starts a new one.
|
|
74
|
+
*/
|
|
75
|
+
declare function getWellKnownUrls(apiBaseUrl: string): Promise<WellKnownAgenticCommerce>;
|
|
76
|
+
/**
|
|
77
|
+
* Synchronous cache read — returns cached URLs or undefined.
|
|
78
|
+
* Never triggers a fetch. Used by verify() to avoid extra HTTP calls
|
|
79
|
+
* in the hot path; adapters are responsible for prefetching.
|
|
80
|
+
*/
|
|
81
|
+
declare function getCachedWellKnownUrls(apiBaseUrl: string): WellKnownAgenticCommerce | undefined;
|
|
82
|
+
|
|
53
83
|
/**
|
|
54
84
|
* AstraSync Universal Verification Gateway
|
|
55
85
|
*
|
|
@@ -77,4 +107,4 @@ declare function quickVerify(config: GatewayConfig, credentials: AgentCredential
|
|
|
77
107
|
|
|
78
108
|
declare const VERSION = "2.0.0";
|
|
79
109
|
|
|
80
|
-
export { AccessLevel, AgentCredentials, GatewayConfig, VERSION, VerificationRequest, VerificationResult, clearCache, extractCredentials, hasCredentials, quickVerify, verify };
|
|
110
|
+
export { AccessLevel, AgentCredentials, GatewayConfig, VERSION, VerificationRequest, VerificationResult, type WellKnownAgenticCommerce, clearCache, extractCredentials, getCachedWellKnownUrls, getWellKnownUrls, hasCredentials, prefetchWellKnown, quickVerify, verify };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { A as ACCESS_LEVEL_DESCRIPTIONS, a as ACCESS_LEVEL_HIERARCHY, b as Acces
|
|
|
4
4
|
export { e as express } from './express-CrfwoNAR.js';
|
|
5
5
|
export { n as nextjs } from './nextjs-66R1KW8e.js';
|
|
6
6
|
export { aR as extractMcpCredentials, bg as setMcpMeta, b1 as transport } from './index-CCdZxvAr.js';
|
|
7
|
-
export { McpMiddlewareOptions, createMcpMiddleware } from './adapters/mcp.js';
|
|
7
|
+
export { McpMiddlewareOptions, ToolGateConfig, createMcpMiddleware } from './adapters/mcp.js';
|
|
8
8
|
export { AgentProtocol, AgentRecord, AstraSync, AstraSyncConfig, AstraSyncError, AuthenticationError, BuildGuidanceParams, FrameworkConfig, GuidanceEnvelope, HealthResponse, KYDRequiredError, ModelConfig, PDLSSConfig, PDLSSDuration, PDLSSLimits, PDLSSPurpose, PDLSSScope, PDLSSSelfInstantiation, PendingRegistrationResponse, PollRegistrationResult, RegisterOptions, RegisterResult, RegistrationDeniedError, RegistrationExpiredError, RegistrationResponse, RegistrationTimeoutError, VerifyResponse, WaitForApprovalOptions, buildGuidance } from './registration/index.js';
|
|
9
9
|
export { A as AgentClient, C as ChallengeHandler, i as agent, r as recordDecision } from './index-DC5f8eoQ.js';
|
|
10
10
|
import 'express';
|
|
@@ -50,6 +50,36 @@ declare function quickVerify(config: GatewayConfig, credentials: AgentCredential
|
|
|
50
50
|
reason?: string;
|
|
51
51
|
}>;
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* SDK-side discovery of canonical platform URLs via `/.well-known/agentic-commerce`.
|
|
55
|
+
*
|
|
56
|
+
* Fire-and-forget pre-fetch at middleware creation; first verify() awaits
|
|
57
|
+
* the in-flight promise if it hasn't resolved. 60-minute TTL with
|
|
58
|
+
* stale-while-revalidate background refresh.
|
|
59
|
+
*/
|
|
60
|
+
interface WellKnownAgenticCommerce {
|
|
61
|
+
registrationUrl: string;
|
|
62
|
+
documentationUrl: string;
|
|
63
|
+
verifyAccessUrl: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Start a background fetch. Returns the promise for callers that need
|
|
67
|
+
* to await it (first verify() call).
|
|
68
|
+
*/
|
|
69
|
+
declare function prefetchWellKnown(apiBaseUrl: string): Promise<WellKnownAgenticCommerce>;
|
|
70
|
+
/**
|
|
71
|
+
* Get cached well-known URLs. If stale, triggers a background refresh
|
|
72
|
+
* and returns stale data (stale-while-revalidate). If no cache exists,
|
|
73
|
+
* awaits the in-flight fetch or starts a new one.
|
|
74
|
+
*/
|
|
75
|
+
declare function getWellKnownUrls(apiBaseUrl: string): Promise<WellKnownAgenticCommerce>;
|
|
76
|
+
/**
|
|
77
|
+
* Synchronous cache read — returns cached URLs or undefined.
|
|
78
|
+
* Never triggers a fetch. Used by verify() to avoid extra HTTP calls
|
|
79
|
+
* in the hot path; adapters are responsible for prefetching.
|
|
80
|
+
*/
|
|
81
|
+
declare function getCachedWellKnownUrls(apiBaseUrl: string): WellKnownAgenticCommerce | undefined;
|
|
82
|
+
|
|
53
83
|
/**
|
|
54
84
|
* AstraSync Universal Verification Gateway
|
|
55
85
|
*
|
|
@@ -77,4 +107,4 @@ declare function quickVerify(config: GatewayConfig, credentials: AgentCredential
|
|
|
77
107
|
|
|
78
108
|
declare const VERSION = "2.0.0";
|
|
79
109
|
|
|
80
|
-
export { AccessLevel, AgentCredentials, GatewayConfig, VERSION, VerificationRequest, VerificationResult, clearCache, extractCredentials, hasCredentials, quickVerify, verify };
|
|
110
|
+
export { AccessLevel, AgentCredentials, GatewayConfig, VERSION, VerificationRequest, VerificationResult, type WellKnownAgenticCommerce, clearCache, extractCredentials, getCachedWellKnownUrls, getWellKnownUrls, hasCredentials, prefetchWellKnown, quickVerify, verify };
|
package/dist/index.js
CHANGED
|
@@ -53,11 +53,14 @@ __export(src_exports, {
|
|
|
53
53
|
extractCredentials: () => extractCredentials,
|
|
54
54
|
extractMcpCredentials: () => extractMcpCredentials,
|
|
55
55
|
getAccessLevelForScore: () => getAccessLevelForScore,
|
|
56
|
+
getCachedWellKnownUrls: () => getCachedWellKnownUrls,
|
|
56
57
|
getCapabilities: () => getCapabilities,
|
|
57
58
|
getTrustLevel: () => getTrustLevel,
|
|
59
|
+
getWellKnownUrls: () => getWellKnownUrls,
|
|
58
60
|
hasCredentials: () => hasCredentials,
|
|
59
61
|
hasMinimumAccess: () => hasMinimumAccess,
|
|
60
62
|
nextjs: () => nextjs_exports,
|
|
63
|
+
prefetchWellKnown: () => prefetchWellKnown,
|
|
61
64
|
quickVerify: () => quickVerify,
|
|
62
65
|
recordDecision: () => recordDecision2,
|
|
63
66
|
sdk: () => sdk_exports,
|
|
@@ -191,6 +194,65 @@ function getCapabilities(accessLevel) {
|
|
|
191
194
|
// src/version.ts
|
|
192
195
|
var SDK_VERSION = "2.4.13";
|
|
193
196
|
|
|
197
|
+
// src/well-known.ts
|
|
198
|
+
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
199
|
+
var cache = /* @__PURE__ */ new Map();
|
|
200
|
+
var inflight = /* @__PURE__ */ new Map();
|
|
201
|
+
function wellKnownUrl(apiBaseUrl) {
|
|
202
|
+
const base = apiBaseUrl.replace(/\/api\/?$/, "");
|
|
203
|
+
return `${base}/.well-known/agentic-commerce`;
|
|
204
|
+
}
|
|
205
|
+
async function fetchWellKnown(apiBaseUrl) {
|
|
206
|
+
const url = wellKnownUrl(apiBaseUrl);
|
|
207
|
+
const response = await fetch(url, {
|
|
208
|
+
method: "GET",
|
|
209
|
+
headers: { Accept: "application/json" },
|
|
210
|
+
signal: AbortSignal.timeout(5e3)
|
|
211
|
+
});
|
|
212
|
+
if (!response.ok) {
|
|
213
|
+
throw new Error(
|
|
214
|
+
`AstraSync platform must expose /.well-known/agentic-commerce; got ${response.status} from ${url}. SDK cannot initialise without it.`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
const data = await response.json();
|
|
218
|
+
if (!data.registrationUrl || !data.documentationUrl || !data.verifyAccessUrl) {
|
|
219
|
+
throw new Error(
|
|
220
|
+
`/.well-known/agentic-commerce response missing required fields (registrationUrl, documentationUrl, verifyAccessUrl).`
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
return data;
|
|
224
|
+
}
|
|
225
|
+
function prefetchWellKnown(apiBaseUrl) {
|
|
226
|
+
const existing = inflight.get(apiBaseUrl);
|
|
227
|
+
if (existing) return existing;
|
|
228
|
+
const promise = fetchWellKnown(apiBaseUrl).then((data) => {
|
|
229
|
+
cache.set(apiBaseUrl, { data, fetchedAt: Date.now() });
|
|
230
|
+
inflight.delete(apiBaseUrl);
|
|
231
|
+
return data;
|
|
232
|
+
}).catch((err) => {
|
|
233
|
+
inflight.delete(apiBaseUrl);
|
|
234
|
+
throw err;
|
|
235
|
+
});
|
|
236
|
+
inflight.set(apiBaseUrl, promise);
|
|
237
|
+
return promise;
|
|
238
|
+
}
|
|
239
|
+
async function getWellKnownUrls(apiBaseUrl) {
|
|
240
|
+
const entry = cache.get(apiBaseUrl);
|
|
241
|
+
if (entry) {
|
|
242
|
+
if (Date.now() - entry.fetchedAt > CACHE_TTL_MS) {
|
|
243
|
+
prefetchWellKnown(apiBaseUrl).catch(() => {
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return entry.data;
|
|
247
|
+
}
|
|
248
|
+
const pending = inflight.get(apiBaseUrl);
|
|
249
|
+
if (pending) return pending;
|
|
250
|
+
return prefetchWellKnown(apiBaseUrl);
|
|
251
|
+
}
|
|
252
|
+
function getCachedWellKnownUrls(apiBaseUrl) {
|
|
253
|
+
return cache.get(apiBaseUrl)?.data;
|
|
254
|
+
}
|
|
255
|
+
|
|
194
256
|
// src/verify.ts
|
|
195
257
|
var DEFAULT_CONFIG = {
|
|
196
258
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -332,21 +394,22 @@ function extractCredentials(headers, query) {
|
|
|
332
394
|
function hasCredentials(credentials) {
|
|
333
395
|
return !!(credentials.astraId || credentials.apiKey || credentials.jwt);
|
|
334
396
|
}
|
|
335
|
-
function createGuidanceResponse(
|
|
397
|
+
function createGuidanceResponse(_config, reason, options = {}) {
|
|
336
398
|
const source = options.source ?? "no_credentials";
|
|
337
399
|
const isApiError = source === "api_error";
|
|
400
|
+
const urls = options.urls;
|
|
338
401
|
const guidance = isApiError ? {
|
|
339
402
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
340
|
-
registrationUrl:
|
|
341
|
-
documentationUrl:
|
|
403
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
404
|
+
documentationUrl: urls?.documentationUrl ?? "",
|
|
342
405
|
steps: [
|
|
343
406
|
"Retry the request with exponential backoff",
|
|
344
407
|
"If failures persist, share the correlationId with support"
|
|
345
408
|
]
|
|
346
409
|
} : {
|
|
347
410
|
message: "This service verifies AI agents before granting access. Please register your agent with AstraSync.",
|
|
348
|
-
registrationUrl:
|
|
349
|
-
documentationUrl:
|
|
411
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
412
|
+
documentationUrl: urls?.documentationUrl ?? "",
|
|
350
413
|
steps: [
|
|
351
414
|
"Register for an AstraSync account",
|
|
352
415
|
"Create and register your agent",
|
|
@@ -388,7 +451,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
388
451
|
const { credentials, ...requestData } = request;
|
|
389
452
|
const body = {
|
|
390
453
|
...credentials.astraId && { agentId: credentials.astraId },
|
|
391
|
-
purpose: requestData.purpose
|
|
454
|
+
...requestData.purpose && { purpose: requestData.purpose }
|
|
392
455
|
};
|
|
393
456
|
if (requestData.action) body.action = requestData.action;
|
|
394
457
|
if (requestData.resourceType) body.resourceType = requestData.resourceType;
|
|
@@ -468,6 +531,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
468
531
|
}
|
|
469
532
|
async function verify(config, request) {
|
|
470
533
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
534
|
+
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
471
535
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
472
536
|
if (mergedConfig.strictInit) {
|
|
473
537
|
await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
|
|
@@ -504,7 +568,8 @@ async function verify(config, request) {
|
|
|
504
568
|
if (!apiResponse.success) {
|
|
505
569
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
506
570
|
source: "api_error",
|
|
507
|
-
correlationId: apiResponse.correlationId
|
|
571
|
+
correlationId: apiResponse.correlationId,
|
|
572
|
+
urls
|
|
508
573
|
});
|
|
509
574
|
}
|
|
510
575
|
if (!apiResponse.access?.allowed) {
|
|
@@ -527,8 +592,8 @@ async function verify(config, request) {
|
|
|
527
592
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
528
593
|
guidance: {
|
|
529
594
|
message: apiResponse.access?.reason || "Access denied by PDLSS policy",
|
|
530
|
-
registrationUrl:
|
|
531
|
-
documentationUrl:
|
|
595
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
596
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
532
597
|
},
|
|
533
598
|
verifiedAt: /* @__PURE__ */ new Date(),
|
|
534
599
|
// Extract sessionId so decisions can be recorded for denials too
|
|
@@ -599,12 +664,12 @@ async function verify(config, request) {
|
|
|
599
664
|
];
|
|
600
665
|
result.guidance = result.runtimeChallenge ? {
|
|
601
666
|
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
602
|
-
registrationUrl:
|
|
603
|
-
documentationUrl:
|
|
667
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
668
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
604
669
|
} : {
|
|
605
670
|
message: result.recommendationReasons?.[0] || "Access denied by AstraSync recommendation",
|
|
606
|
-
registrationUrl:
|
|
607
|
-
documentationUrl:
|
|
671
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
672
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
608
673
|
};
|
|
609
674
|
} else if (result.recommendation === "step_up_required") {
|
|
610
675
|
result.requiresStepUp = true;
|
|
@@ -887,6 +952,9 @@ function dedupeFailures(result) {
|
|
|
887
952
|
return true;
|
|
888
953
|
});
|
|
889
954
|
}
|
|
955
|
+
if (result.denialReasons && result.denialReasons.length > 1) {
|
|
956
|
+
result.denialReasons = [...new Set(result.denialReasons)];
|
|
957
|
+
}
|
|
890
958
|
}
|
|
891
959
|
function defaultOnDenied(result, _req, res) {
|
|
892
960
|
const statusCode = !result.identityVerified ? 401 : 403;
|
|
@@ -918,6 +986,10 @@ function createMiddleware(options) {
|
|
|
918
986
|
caseInsensitiveRouteMatch = false,
|
|
919
987
|
...config
|
|
920
988
|
} = options;
|
|
989
|
+
if (config.apiBaseUrl) {
|
|
990
|
+
prefetchWellKnown(config.apiBaseUrl).catch(() => {
|
|
991
|
+
});
|
|
992
|
+
}
|
|
921
993
|
let cachedRoutes = [];
|
|
922
994
|
let lastFetchAt = 0;
|
|
923
995
|
let refreshing = null;
|
|
@@ -980,6 +1052,7 @@ function createMiddleware(options) {
|
|
|
980
1052
|
}
|
|
981
1053
|
return next();
|
|
982
1054
|
}
|
|
1055
|
+
const wellKnownUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
983
1056
|
const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
|
|
984
1057
|
const shouldEnforce = routeConfig.minAccessLevel !== "none";
|
|
985
1058
|
if (routeConfig.minAccessLevel === "none" && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
|
|
@@ -1001,8 +1074,8 @@ function createMiddleware(options) {
|
|
|
1001
1074
|
denialReasons: preCheckFailures.map((f) => f.message),
|
|
1002
1075
|
guidance: {
|
|
1003
1076
|
message: "Request exceeds counterparty-defined PDLSS limits.",
|
|
1004
|
-
registrationUrl:
|
|
1005
|
-
documentationUrl:
|
|
1077
|
+
registrationUrl: wellKnownUrls?.registrationUrl ?? "",
|
|
1078
|
+
documentationUrl: wellKnownUrls?.documentationUrl ?? ""
|
|
1006
1079
|
},
|
|
1007
1080
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
1008
1081
|
};
|
|
@@ -1082,6 +1155,13 @@ function createMiddleware(options) {
|
|
|
1082
1155
|
};
|
|
1083
1156
|
result.failures = [...result.failures ?? [], insufficientFailure];
|
|
1084
1157
|
result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
|
|
1158
|
+
if (!result.guidance && wellKnownUrls) {
|
|
1159
|
+
result.guidance = {
|
|
1160
|
+
message: insufficientFailure.message,
|
|
1161
|
+
registrationUrl: wellKnownUrls.registrationUrl,
|
|
1162
|
+
documentationUrl: wellKnownUrls.documentationUrl
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1085
1165
|
if (shouldRecordDecisions && sessionId) {
|
|
1086
1166
|
recordDecision(config, sessionId, "denied", insufficientFailure.message).catch(() => {
|
|
1087
1167
|
});
|
|
@@ -1099,6 +1179,13 @@ function createMiddleware(options) {
|
|
|
1099
1179
|
};
|
|
1100
1180
|
result.failures = [...result.failures ?? [], trustFailure];
|
|
1101
1181
|
result.denialReasons = [trustFailure.message];
|
|
1182
|
+
if (!result.guidance && wellKnownUrls) {
|
|
1183
|
+
result.guidance = {
|
|
1184
|
+
message: trustFailure.message,
|
|
1185
|
+
registrationUrl: wellKnownUrls.registrationUrl,
|
|
1186
|
+
documentationUrl: wellKnownUrls.documentationUrl
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1102
1189
|
if (shouldRecordDecisions && sessionId) {
|
|
1103
1190
|
recordDecision(config, sessionId, "denied", trustFailure.message).catch(() => {
|
|
1104
1191
|
});
|
|
@@ -1139,6 +1226,14 @@ function createMiddleware(options) {
|
|
|
1139
1226
|
verifiedAt: /* @__PURE__ */ new Date(),
|
|
1140
1227
|
correlationId
|
|
1141
1228
|
};
|
|
1229
|
+
const catchUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
1230
|
+
if (catchUrls) {
|
|
1231
|
+
result.guidance = {
|
|
1232
|
+
message: `Middleware threw ${errorClass} \u2014 failing closed`,
|
|
1233
|
+
registrationUrl: catchUrls.registrationUrl,
|
|
1234
|
+
documentationUrl: catchUrls.documentationUrl
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1142
1237
|
dedupeFailures(result);
|
|
1143
1238
|
return onDenied(result, req, res);
|
|
1144
1239
|
}
|
|
@@ -4143,7 +4238,7 @@ async function exportJwkFromKeyLike(keyLike) {
|
|
|
4143
4238
|
|
|
4144
4239
|
// src/transport/registry/mastercard.ts
|
|
4145
4240
|
function createMastercardRegistry(options = {}) {
|
|
4146
|
-
const
|
|
4241
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
4147
4242
|
const ttlSec = options.cacheTtlSec ?? 3600;
|
|
4148
4243
|
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
4149
4244
|
let warned = false;
|
|
@@ -4160,7 +4255,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4160
4255
|
}
|
|
4161
4256
|
return null;
|
|
4162
4257
|
}
|
|
4163
|
-
const cached =
|
|
4258
|
+
const cached = cache2.get(kid);
|
|
4164
4259
|
if (cached && cached.expiresAt > Date.now()) return cached.jwk;
|
|
4165
4260
|
try {
|
|
4166
4261
|
const res = await fetchFn(options.registryUrl);
|
|
@@ -4169,7 +4264,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4169
4264
|
const keys = body.keys ?? [];
|
|
4170
4265
|
for (const k of keys) {
|
|
4171
4266
|
if (k.kid === kid) {
|
|
4172
|
-
|
|
4267
|
+
cache2.set(kid, { jwk: k, expiresAt: Date.now() + ttlSec * 1e3 });
|
|
4173
4268
|
return k;
|
|
4174
4269
|
}
|
|
4175
4270
|
}
|
|
@@ -4184,7 +4279,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4184
4279
|
// src/transport/registry/web-bot-auth.ts
|
|
4185
4280
|
var DIRECTORY_PATH = "/.well-known/http-message-signatures-directory";
|
|
4186
4281
|
function createWebBotAuthRegistry(options = {}) {
|
|
4187
|
-
const
|
|
4282
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
4188
4283
|
const ttlSec = options.cacheTtlSec ?? 3600;
|
|
4189
4284
|
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
4190
4285
|
return {
|
|
@@ -4193,7 +4288,7 @@ function createWebBotAuthRegistry(options = {}) {
|
|
|
4193
4288
|
if (!kid) return null;
|
|
4194
4289
|
const directoryUrl = resolveDirectoryUrl(options.directoryUrl, context?.origin);
|
|
4195
4290
|
if (!directoryUrl) return null;
|
|
4196
|
-
const cached =
|
|
4291
|
+
const cached = cache2.get(directoryUrl);
|
|
4197
4292
|
const now = Date.now();
|
|
4198
4293
|
if (cached && cached.expiresAt > now) {
|
|
4199
4294
|
return findKeyByKid(cached.keys, kid);
|
|
@@ -4203,7 +4298,7 @@ function createWebBotAuthRegistry(options = {}) {
|
|
|
4203
4298
|
if (!res.ok) return null;
|
|
4204
4299
|
const body = await res.json();
|
|
4205
4300
|
const keys = body.keys ?? [];
|
|
4206
|
-
|
|
4301
|
+
cache2.set(directoryUrl, { keys, expiresAt: now + ttlSec * 1e3 });
|
|
4207
4302
|
return findKeyByKid(keys, kid);
|
|
4208
4303
|
} catch {
|
|
4209
4304
|
return null;
|
|
@@ -4342,19 +4437,22 @@ function extractFromMcpBody(astrasyncMeta, args, key) {
|
|
|
4342
4437
|
}
|
|
4343
4438
|
return { value: void 0, source: void 0 };
|
|
4344
4439
|
}
|
|
4345
|
-
function mcpToPdlss(parsed, headerPurpose, headerAction) {
|
|
4346
|
-
const resource =
|
|
4440
|
+
function mcpToPdlss(parsed, requestPath, headerPurpose, headerAction, toolGate) {
|
|
4441
|
+
const resource = toolGate?.resource ?? requestPath;
|
|
4347
4442
|
let purpose;
|
|
4348
4443
|
let purposeSource;
|
|
4349
|
-
if (
|
|
4444
|
+
if (toolGate?.purpose !== void 0) {
|
|
4445
|
+
purpose = toolGate.purpose;
|
|
4446
|
+
purposeSource = "tool_gate";
|
|
4447
|
+
} else if (headerPurpose) {
|
|
4350
4448
|
purpose = headerPurpose;
|
|
4351
4449
|
purposeSource = "header";
|
|
4352
4450
|
} else if (parsed.purposeFromBody && parsed.purposeSourceFromBody) {
|
|
4353
4451
|
purpose = parsed.purposeFromBody;
|
|
4354
4452
|
purposeSource = parsed.purposeSourceFromBody;
|
|
4355
4453
|
} else {
|
|
4356
|
-
purpose =
|
|
4357
|
-
purposeSource =
|
|
4454
|
+
purpose = void 0;
|
|
4455
|
+
purposeSource = void 0;
|
|
4358
4456
|
}
|
|
4359
4457
|
let action;
|
|
4360
4458
|
let actionSource;
|
|
@@ -4379,6 +4477,9 @@ function mcpRiskTier(parsed) {
|
|
|
4379
4477
|
}
|
|
4380
4478
|
|
|
4381
4479
|
// src/adapters/mcp.ts
|
|
4480
|
+
function normalizeToolGate(gate) {
|
|
4481
|
+
return typeof gate === "string" ? { minAccessLevel: gate } : gate;
|
|
4482
|
+
}
|
|
4382
4483
|
function readSingleHeader(value) {
|
|
4383
4484
|
if (typeof value === "string") return value;
|
|
4384
4485
|
if (Array.isArray(value)) return value[0];
|
|
@@ -4394,6 +4495,9 @@ function dedupeFailures2(result) {
|
|
|
4394
4495
|
return true;
|
|
4395
4496
|
});
|
|
4396
4497
|
}
|
|
4498
|
+
if (result.denialReasons && result.denialReasons.length > 1) {
|
|
4499
|
+
result.denialReasons = [...new Set(result.denialReasons)];
|
|
4500
|
+
}
|
|
4397
4501
|
}
|
|
4398
4502
|
function defaultMcpDenied(result, req, res) {
|
|
4399
4503
|
const id = req.body?.id ?? null;
|
|
@@ -4419,11 +4523,17 @@ function defaultMcpDenied(result, req, res) {
|
|
|
4419
4523
|
});
|
|
4420
4524
|
}
|
|
4421
4525
|
function resolveMinAccessLevel(parsed, opts) {
|
|
4422
|
-
if (parsed.toolName
|
|
4423
|
-
|
|
4526
|
+
if (!parsed.toolName) {
|
|
4527
|
+
if (opts.methodGates && opts.methodGates[parsed.method] !== void 0) {
|
|
4528
|
+
return { level: opts.methodGates[parsed.method], source: "methodGate" };
|
|
4529
|
+
}
|
|
4530
|
+
return { level: "none", source: "discovery_default" };
|
|
4424
4531
|
}
|
|
4425
|
-
if (opts.
|
|
4426
|
-
return {
|
|
4532
|
+
if (opts.toolGates && opts.toolGates[parsed.toolName] !== void 0) {
|
|
4533
|
+
return {
|
|
4534
|
+
level: normalizeToolGate(opts.toolGates[parsed.toolName]).minAccessLevel,
|
|
4535
|
+
source: "toolGate"
|
|
4536
|
+
};
|
|
4427
4537
|
}
|
|
4428
4538
|
return { level: mcpRiskTier(parsed), source: "tier" };
|
|
4429
4539
|
}
|
|
@@ -4441,6 +4551,10 @@ function createMcpMiddleware(options) {
|
|
|
4441
4551
|
failOnError = "open",
|
|
4442
4552
|
...config
|
|
4443
4553
|
} = options;
|
|
4554
|
+
if (config.apiBaseUrl) {
|
|
4555
|
+
prefetchWellKnown(config.apiBaseUrl).catch(() => {
|
|
4556
|
+
});
|
|
4557
|
+
}
|
|
4444
4558
|
return async (req, res, next) => {
|
|
4445
4559
|
try {
|
|
4446
4560
|
if (skip) return next();
|
|
@@ -4453,6 +4567,7 @@ function createMcpMiddleware(options) {
|
|
|
4453
4567
|
return next();
|
|
4454
4568
|
}
|
|
4455
4569
|
req.mcpRequest = parsed;
|
|
4570
|
+
const wellKnownUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
4456
4571
|
const headerRaw = req.headers["x-astra-id"] ?? req.headers["x-astra-agentid"];
|
|
4457
4572
|
const headerAstraId = typeof headerRaw === "string" ? headerRaw : Array.isArray(headerRaw) ? headerRaw[0] : void 0;
|
|
4458
4573
|
const bodyAstraId = parsed.agentIdFromBody;
|
|
@@ -4506,9 +4621,17 @@ function createMcpMiddleware(options) {
|
|
|
4506
4621
|
}
|
|
4507
4622
|
return next();
|
|
4508
4623
|
}
|
|
4624
|
+
const rawGate = parsed.toolName && toolGates?.[parsed.toolName];
|
|
4625
|
+
const gate = rawGate ? normalizeToolGate(rawGate) : void 0;
|
|
4509
4626
|
const headerPurpose = readSingleHeader(req.headers["x-astra-purpose"]);
|
|
4510
4627
|
const headerAction = readSingleHeader(req.headers["x-astra-action"]);
|
|
4511
|
-
const pdlss = mcpToPdlss(
|
|
4628
|
+
const pdlss = mcpToPdlss(
|
|
4629
|
+
parsed,
|
|
4630
|
+
req.path,
|
|
4631
|
+
headerPurpose,
|
|
4632
|
+
headerAction,
|
|
4633
|
+
gate ? { purpose: gate.purpose, resource: gate.resource } : void 0
|
|
4634
|
+
);
|
|
4512
4635
|
if (config.debug) {
|
|
4513
4636
|
console.debug("[mcp-middleware] pdlss resolved", {
|
|
4514
4637
|
purpose_source: pdlss.purposeSource,
|
|
@@ -4569,6 +4692,13 @@ function createMcpMiddleware(options) {
|
|
|
4569
4692
|
};
|
|
4570
4693
|
result.failures = [...result.failures ?? [], insufficientFailure];
|
|
4571
4694
|
result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
|
|
4695
|
+
if (!result.guidance && wellKnownUrls) {
|
|
4696
|
+
result.guidance = {
|
|
4697
|
+
message: insufficientFailure.message,
|
|
4698
|
+
registrationUrl: wellKnownUrls.registrationUrl,
|
|
4699
|
+
documentationUrl: wellKnownUrls.documentationUrl
|
|
4700
|
+
};
|
|
4701
|
+
}
|
|
4572
4702
|
if (shouldRecordDecisions) {
|
|
4573
4703
|
const overrideKind = gateSource === "toolGate" ? "toolGate" : gateSource === "methodGate" ? "methodGate" : "other";
|
|
4574
4704
|
const override = {
|
|
@@ -4637,6 +4767,14 @@ function createMcpMiddleware(options) {
|
|
|
4637
4767
|
verifiedAt: /* @__PURE__ */ new Date(),
|
|
4638
4768
|
correlationId
|
|
4639
4769
|
};
|
|
4770
|
+
const catchUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
|
|
4771
|
+
if (catchUrls) {
|
|
4772
|
+
result.guidance = {
|
|
4773
|
+
message: `Middleware threw ${errorClass} \u2014 failing closed`,
|
|
4774
|
+
registrationUrl: catchUrls.registrationUrl,
|
|
4775
|
+
documentationUrl: catchUrls.documentationUrl
|
|
4776
|
+
};
|
|
4777
|
+
}
|
|
4640
4778
|
dedupeFailures2(result);
|
|
4641
4779
|
return onDenied(result, req, res);
|
|
4642
4780
|
}
|
|
@@ -5347,11 +5485,14 @@ var VERSION = "2.0.0";
|
|
|
5347
5485
|
extractCredentials,
|
|
5348
5486
|
extractMcpCredentials,
|
|
5349
5487
|
getAccessLevelForScore,
|
|
5488
|
+
getCachedWellKnownUrls,
|
|
5350
5489
|
getCapabilities,
|
|
5351
5490
|
getTrustLevel,
|
|
5491
|
+
getWellKnownUrls,
|
|
5352
5492
|
hasCredentials,
|
|
5353
5493
|
hasMinimumAccess,
|
|
5354
5494
|
nextjs,
|
|
5495
|
+
prefetchWellKnown,
|
|
5355
5496
|
quickVerify,
|
|
5356
5497
|
recordDecision,
|
|
5357
5498
|
sdk,
|