@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.
Files changed (45) hide show
  1. package/dist/adapters/express.js +107 -15
  2. package/dist/adapters/express.js.map +1 -1
  3. package/dist/adapters/express.mjs +107 -15
  4. package/dist/adapters/express.mjs.map +1 -1
  5. package/dist/adapters/mcp.d.mts +75 -53
  6. package/dist/adapters/mcp.d.ts +75 -53
  7. package/dist/adapters/mcp.js +128 -23
  8. package/dist/adapters/mcp.js.map +1 -1
  9. package/dist/adapters/mcp.mjs +128 -23
  10. package/dist/adapters/mcp.mjs.map +1 -1
  11. package/dist/adapters/nextjs.js +24 -14
  12. package/dist/adapters/nextjs.js.map +1 -1
  13. package/dist/adapters/nextjs.mjs +24 -14
  14. package/dist/adapters/nextjs.mjs.map +1 -1
  15. package/dist/adapters/sdk.js +23 -13
  16. package/dist/adapters/sdk.js.map +1 -1
  17. package/dist/adapters/sdk.mjs +23 -13
  18. package/dist/adapters/sdk.mjs.map +1 -1
  19. package/dist/browser/background.js +23 -13
  20. package/dist/browser/background.js.map +1 -1
  21. package/dist/browser/background.mjs +23 -13
  22. package/dist/browser/background.mjs.map +1 -1
  23. package/dist/cursor/extension.js +23 -13
  24. package/dist/cursor/extension.js.map +1 -1
  25. package/dist/cursor/extension.mjs +23 -13
  26. package/dist/cursor/extension.mjs.map +1 -1
  27. package/dist/gateway/gateway.js +23 -13
  28. package/dist/gateway/gateway.js.map +1 -1
  29. package/dist/gateway/gateway.mjs +23 -13
  30. package/dist/gateway/gateway.mjs.map +1 -1
  31. package/dist/index.d.mts +32 -2
  32. package/dist/index.d.ts +32 -2
  33. package/dist/index.js +180 -39
  34. package/dist/index.js.map +1 -1
  35. package/dist/index.mjs +177 -39
  36. package/dist/index.mjs.map +1 -1
  37. package/dist/registration/index.js +7 -7
  38. package/dist/registration/index.js.map +1 -1
  39. package/dist/registration/index.mjs +7 -7
  40. package/dist/registration/index.mjs.map +1 -1
  41. package/dist/ui/index.js +2 -2
  42. package/dist/ui/index.js.map +1 -1
  43. package/dist/ui/index.mjs +2 -2
  44. package/dist/ui/index.mjs.map +1 -1
  45. package/package.json +1 -1
@@ -47,6 +47,65 @@ function hasMinimumAccess(actual, required) {
47
47
  // src/version.ts
48
48
  var SDK_VERSION = "2.4.13";
49
49
 
50
+ // src/well-known.ts
51
+ var CACHE_TTL_MS = 60 * 60 * 1e3;
52
+ var cache = /* @__PURE__ */ new Map();
53
+ var inflight = /* @__PURE__ */ new Map();
54
+ function wellKnownUrl(apiBaseUrl) {
55
+ const base = apiBaseUrl.replace(/\/api\/?$/, "");
56
+ return `${base}/.well-known/agentic-commerce`;
57
+ }
58
+ async function fetchWellKnown(apiBaseUrl) {
59
+ const url = wellKnownUrl(apiBaseUrl);
60
+ const response = await fetch(url, {
61
+ method: "GET",
62
+ headers: { Accept: "application/json" },
63
+ signal: AbortSignal.timeout(5e3)
64
+ });
65
+ if (!response.ok) {
66
+ throw new Error(
67
+ `AstraSync platform must expose /.well-known/agentic-commerce; got ${response.status} from ${url}. SDK cannot initialise without it.`
68
+ );
69
+ }
70
+ const data = await response.json();
71
+ if (!data.registrationUrl || !data.documentationUrl || !data.verifyAccessUrl) {
72
+ throw new Error(
73
+ `/.well-known/agentic-commerce response missing required fields (registrationUrl, documentationUrl, verifyAccessUrl).`
74
+ );
75
+ }
76
+ return data;
77
+ }
78
+ function prefetchWellKnown(apiBaseUrl) {
79
+ const existing = inflight.get(apiBaseUrl);
80
+ if (existing) return existing;
81
+ const promise = fetchWellKnown(apiBaseUrl).then((data) => {
82
+ cache.set(apiBaseUrl, { data, fetchedAt: Date.now() });
83
+ inflight.delete(apiBaseUrl);
84
+ return data;
85
+ }).catch((err) => {
86
+ inflight.delete(apiBaseUrl);
87
+ throw err;
88
+ });
89
+ inflight.set(apiBaseUrl, promise);
90
+ return promise;
91
+ }
92
+ async function getWellKnownUrls(apiBaseUrl) {
93
+ const entry = cache.get(apiBaseUrl);
94
+ if (entry) {
95
+ if (Date.now() - entry.fetchedAt > CACHE_TTL_MS) {
96
+ prefetchWellKnown(apiBaseUrl).catch(() => {
97
+ });
98
+ }
99
+ return entry.data;
100
+ }
101
+ const pending = inflight.get(apiBaseUrl);
102
+ if (pending) return pending;
103
+ return prefetchWellKnown(apiBaseUrl);
104
+ }
105
+ function getCachedWellKnownUrls(apiBaseUrl) {
106
+ return cache.get(apiBaseUrl)?.data;
107
+ }
108
+
50
109
  // src/verify.ts
51
110
  var DEFAULT_CONFIG = {
52
111
  apiBaseUrl: "https://astrasync.ai/api",
@@ -182,21 +241,22 @@ function extractCredentials(headers, query) {
182
241
  }
183
242
  return credentials;
184
243
  }
185
- function createGuidanceResponse(config, reason, options = {}) {
244
+ function createGuidanceResponse(_config, reason, options = {}) {
186
245
  const source = options.source ?? "no_credentials";
187
246
  const isApiError = source === "api_error";
247
+ const urls = options.urls;
188
248
  const guidance = isApiError ? {
189
249
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
190
- registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/agents/register`,
191
- documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
250
+ registrationUrl: urls?.registrationUrl ?? "",
251
+ documentationUrl: urls?.documentationUrl ?? "",
192
252
  steps: [
193
253
  "Retry the request with exponential backoff",
194
254
  "If failures persist, share the correlationId with support"
195
255
  ]
196
256
  } : {
197
257
  message: "This service verifies AI agents before granting access. Please register your agent with AstraSync.",
198
- registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/agents/register`,
199
- documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
258
+ registrationUrl: urls?.registrationUrl ?? "",
259
+ documentationUrl: urls?.documentationUrl ?? "",
200
260
  steps: [
201
261
  "Register for an AstraSync account",
202
262
  "Create and register your agent",
@@ -238,7 +298,7 @@ async function callVerifyAccessAPI(config, request) {
238
298
  const { credentials, ...requestData } = request;
239
299
  const body = {
240
300
  ...credentials.astraId && { agentId: credentials.astraId },
241
- purpose: requestData.purpose || "general"
301
+ ...requestData.purpose && { purpose: requestData.purpose }
242
302
  };
243
303
  if (requestData.action) body.action = requestData.action;
244
304
  if (requestData.resourceType) body.resourceType = requestData.resourceType;
@@ -318,6 +378,7 @@ async function callVerifyAccessAPI(config, request) {
318
378
  }
319
379
  async function verify(config, request) {
320
380
  const mergedConfig = { ...DEFAULT_CONFIG, ...config };
381
+ const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
321
382
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
322
383
  if (mergedConfig.strictInit) {
323
384
  await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
@@ -354,7 +415,8 @@ async function verify(config, request) {
354
415
  if (!apiResponse.success) {
355
416
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
356
417
  source: "api_error",
357
- correlationId: apiResponse.correlationId
418
+ correlationId: apiResponse.correlationId,
419
+ urls
358
420
  });
359
421
  }
360
422
  if (!apiResponse.access?.allowed) {
@@ -377,8 +439,8 @@ async function verify(config, request) {
377
439
  requiresApproval: apiResponse.access?.requiresApproval,
378
440
  guidance: {
379
441
  message: apiResponse.access?.reason || "Access denied by PDLSS policy",
380
- registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/agents/register`,
381
- documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/pdlss`
442
+ registrationUrl: urls?.registrationUrl ?? "",
443
+ documentationUrl: urls?.documentationUrl ?? ""
382
444
  },
383
445
  verifiedAt: /* @__PURE__ */ new Date(),
384
446
  // Extract sessionId so decisions can be recorded for denials too
@@ -449,12 +511,12 @@ async function verify(config, request) {
449
511
  ];
450
512
  result.guidance = result.runtimeChallenge ? {
451
513
  message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
452
- registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/agents/register`,
453
- documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/runtime-challenge`
514
+ registrationUrl: urls?.registrationUrl ?? "",
515
+ documentationUrl: urls?.documentationUrl ?? ""
454
516
  } : {
455
517
  message: result.recommendationReasons?.[0] || "Access denied by AstraSync recommendation",
456
- registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/agents/register`,
457
- documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/pdlss`
518
+ registrationUrl: urls?.registrationUrl ?? "",
519
+ documentationUrl: urls?.documentationUrl ?? ""
458
520
  };
459
521
  } else if (result.recommendation === "step_up_required") {
460
522
  result.requiresStepUp = true;
@@ -677,6 +739,9 @@ function dedupeFailures(result) {
677
739
  return true;
678
740
  });
679
741
  }
742
+ if (result.denialReasons && result.denialReasons.length > 1) {
743
+ result.denialReasons = [...new Set(result.denialReasons)];
744
+ }
680
745
  }
681
746
  function defaultOnDenied(result, _req, res) {
682
747
  const statusCode = !result.identityVerified ? 401 : 403;
@@ -708,6 +773,10 @@ function createMiddleware(options) {
708
773
  caseInsensitiveRouteMatch = false,
709
774
  ...config
710
775
  } = options;
776
+ if (config.apiBaseUrl) {
777
+ prefetchWellKnown(config.apiBaseUrl).catch(() => {
778
+ });
779
+ }
711
780
  let cachedRoutes = [];
712
781
  let lastFetchAt = 0;
713
782
  let refreshing = null;
@@ -770,6 +839,7 @@ function createMiddleware(options) {
770
839
  }
771
840
  return next();
772
841
  }
842
+ const wellKnownUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
773
843
  const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
774
844
  const shouldEnforce = routeConfig.minAccessLevel !== "none";
775
845
  if (routeConfig.minAccessLevel === "none" && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
@@ -791,8 +861,8 @@ function createMiddleware(options) {
791
861
  denialReasons: preCheckFailures.map((f) => f.message),
792
862
  guidance: {
793
863
  message: "Request exceeds counterparty-defined PDLSS limits.",
794
- registrationUrl: `${config.apiBaseUrl?.replace("/api", "")}/agents/register`,
795
- documentationUrl: `${config.apiBaseUrl?.replace("/api", "")}/docs/pdlss`
864
+ registrationUrl: wellKnownUrls?.registrationUrl ?? "",
865
+ documentationUrl: wellKnownUrls?.documentationUrl ?? ""
796
866
  },
797
867
  verifiedAt: /* @__PURE__ */ new Date()
798
868
  };
@@ -872,6 +942,13 @@ function createMiddleware(options) {
872
942
  };
873
943
  result.failures = [...result.failures ?? [], insufficientFailure];
874
944
  result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
945
+ if (!result.guidance && wellKnownUrls) {
946
+ result.guidance = {
947
+ message: insufficientFailure.message,
948
+ registrationUrl: wellKnownUrls.registrationUrl,
949
+ documentationUrl: wellKnownUrls.documentationUrl
950
+ };
951
+ }
875
952
  if (shouldRecordDecisions && sessionId) {
876
953
  recordDecision(config, sessionId, "denied", insufficientFailure.message).catch(() => {
877
954
  });
@@ -889,6 +966,13 @@ function createMiddleware(options) {
889
966
  };
890
967
  result.failures = [...result.failures ?? [], trustFailure];
891
968
  result.denialReasons = [trustFailure.message];
969
+ if (!result.guidance && wellKnownUrls) {
970
+ result.guidance = {
971
+ message: trustFailure.message,
972
+ registrationUrl: wellKnownUrls.registrationUrl,
973
+ documentationUrl: wellKnownUrls.documentationUrl
974
+ };
975
+ }
892
976
  if (shouldRecordDecisions && sessionId) {
893
977
  recordDecision(config, sessionId, "denied", trustFailure.message).catch(() => {
894
978
  });
@@ -929,6 +1013,14 @@ function createMiddleware(options) {
929
1013
  verifiedAt: /* @__PURE__ */ new Date(),
930
1014
  correlationId
931
1015
  };
1016
+ const catchUrls = config.apiBaseUrl ? await getWellKnownUrls(config.apiBaseUrl).catch(() => void 0) : void 0;
1017
+ if (catchUrls) {
1018
+ result.guidance = {
1019
+ message: `Middleware threw ${errorClass} \u2014 failing closed`,
1020
+ registrationUrl: catchUrls.registrationUrl,
1021
+ documentationUrl: catchUrls.documentationUrl
1022
+ };
1023
+ }
932
1024
  dedupeFailures(result);
933
1025
  return onDenied(result, req, res);
934
1026
  }