@astrasyncai/verification-gateway 3.1.0 → 3.2.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 (79) hide show
  1. package/dist/adapter-interface/interface.d.mts +2 -2
  2. package/dist/adapter-interface/interface.d.ts +2 -2
  3. package/dist/adapters/express.d.mts +2 -2
  4. package/dist/adapters/express.d.ts +2 -2
  5. package/dist/adapters/express.js +46 -61
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +46 -61
  8. package/dist/adapters/express.mjs.map +1 -1
  9. package/dist/adapters/mcp.d.mts +12 -7
  10. package/dist/adapters/mcp.d.ts +12 -7
  11. package/dist/adapters/mcp.js +60 -99
  12. package/dist/adapters/mcp.js.map +1 -1
  13. package/dist/adapters/mcp.mjs +60 -99
  14. package/dist/adapters/mcp.mjs.map +1 -1
  15. package/dist/adapters/nextjs.d.mts +2 -2
  16. package/dist/adapters/nextjs.d.ts +2 -2
  17. package/dist/adapters/nextjs.js +37 -30
  18. package/dist/adapters/nextjs.js.map +1 -1
  19. package/dist/adapters/nextjs.mjs +37 -30
  20. package/dist/adapters/nextjs.mjs.map +1 -1
  21. package/dist/adapters/sdk.d.mts +2 -2
  22. package/dist/adapters/sdk.d.ts +2 -2
  23. package/dist/adapters/sdk.js +25 -14
  24. package/dist/adapters/sdk.js.map +1 -1
  25. package/dist/adapters/sdk.mjs +25 -14
  26. package/dist/adapters/sdk.mjs.map +1 -1
  27. package/dist/agent/index.d.mts +2 -2
  28. package/dist/agent/index.d.ts +2 -2
  29. package/dist/browser/background.js +18 -21
  30. package/dist/browser/background.js.map +1 -1
  31. package/dist/browser/background.mjs +18 -21
  32. package/dist/browser/background.mjs.map +1 -1
  33. package/dist/browser/browser-adapter.d.mts +2 -2
  34. package/dist/browser/browser-adapter.d.ts +2 -2
  35. package/dist/cli/index.d.mts +2 -2
  36. package/dist/cli/index.d.ts +2 -2
  37. package/dist/cursor/cursor-adapter.d.mts +2 -2
  38. package/dist/cursor/cursor-adapter.d.ts +2 -2
  39. package/dist/cursor/extension.d.mts +2 -2
  40. package/dist/cursor/extension.d.ts +2 -2
  41. package/dist/cursor/extension.js +18 -21
  42. package/dist/cursor/extension.js.map +1 -1
  43. package/dist/cursor/extension.mjs +18 -21
  44. package/dist/cursor/extension.mjs.map +1 -1
  45. package/dist/{express-DavQ76oF.d.ts → express-BowlMHQF.d.ts} +1 -1
  46. package/dist/{express-DFVBlXr_.d.mts → express-CeoSdOAZ.d.mts} +1 -1
  47. package/dist/gateway/gateway.d.mts +2 -2
  48. package/dist/gateway/gateway.d.ts +2 -2
  49. package/dist/gateway/gateway.js +18 -21
  50. package/dist/gateway/gateway.js.map +1 -1
  51. package/dist/gateway/gateway.mjs +18 -21
  52. package/dist/gateway/gateway.mjs.map +1 -1
  53. package/dist/git-trigger/git-hooks.d.mts +2 -2
  54. package/dist/git-trigger/git-hooks.d.ts +2 -2
  55. package/dist/{index-BhL2R65s.d.mts → index-B51W8gn8.d.mts} +1 -1
  56. package/dist/{index-BhEgEiJL.d.ts → index-DBmlycVm.d.ts} +1 -1
  57. package/dist/{index-BVxantdv.d.mts → index-DtGziFEm.d.mts} +1 -1
  58. package/dist/{index-Dk2nIA4w.d.ts → index-DzXXBuLm.d.ts} +1 -1
  59. package/dist/index.d.mts +7 -7
  60. package/dist/index.d.ts +7 -7
  61. package/dist/index.js +87 -122
  62. package/dist/index.js.map +1 -1
  63. package/dist/index.mjs +87 -122
  64. package/dist/index.mjs.map +1 -1
  65. package/dist/local-evaluator/evaluator.d.mts +2 -2
  66. package/dist/local-evaluator/evaluator.d.ts +2 -2
  67. package/dist/{nextjs-D-maqrNz.d.mts → nextjs-BW1rzr1I.d.mts} +1 -1
  68. package/dist/{nextjs-BXLH1hJj.d.ts → nextjs-V_K0qlAQ.d.ts} +1 -1
  69. package/dist/{sdk-767LaEP8.d.mts → sdk-ZYgI7G9f.d.ts} +14 -3
  70. package/dist/{sdk-K8IgssHI.d.ts → sdk-e5jg7sqW.d.mts} +14 -3
  71. package/dist/transport/index.d.mts +2 -2
  72. package/dist/transport/index.d.ts +2 -2
  73. package/dist/{types-CyFwZ_Yu.d.mts → types-BNiLZY0i.d.mts} +1 -1
  74. package/dist/{types-WIRp_BP_.d.ts → types-DJi-u3fz.d.ts} +1 -1
  75. package/dist/{types-Cuh7ELfr.d.mts → types-rFh4VMH4.d.mts} +5 -2
  76. package/dist/{types-Cuh7ELfr.d.ts → types-rFh4VMH4.d.ts} +5 -2
  77. package/dist/ui/index.d.mts +1 -1
  78. package/dist/ui/index.d.ts +1 -1
  79. package/package.json +1 -1
@@ -1,24 +1,13 @@
1
1
  // src/access-levels.ts
2
- var ACCESS_LEVEL_HIERARCHY = {
3
- none: 0,
4
- restricted: 1,
5
- "read-only": 2,
6
- standard: 3,
7
- full: 4,
8
- internal: 5
9
- };
10
2
  function getTrustLevel(score) {
11
3
  if (score >= 80) return "PLATINUM";
12
4
  if (score >= 60) return "GOLD";
13
5
  if (score >= 40) return "SILVER";
14
6
  return "BRONZE";
15
7
  }
16
- function hasMinimumAccess(actual, required) {
17
- return ACCESS_LEVEL_HIERARCHY[actual] >= ACCESS_LEVEL_HIERARCHY[required];
18
- }
19
8
 
20
9
  // src/version.ts
21
- var SDK_VERSION = "3.1.0";
10
+ var SDK_VERSION = "3.2.1";
22
11
 
23
12
  // src/well-known.ts
24
13
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -71,7 +60,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
71
60
  }
72
61
  }
73
62
  var verificationCache = /* @__PURE__ */ new Map();
74
- function getCacheKey(request) {
63
+ function getCacheKey(request, counterpartyId) {
75
64
  const c = request.credentials;
76
65
  return [
77
66
  c.astraId || "",
@@ -84,6 +73,14 @@ function getCacheKey(request) {
84
73
  request.jurisdiction || "",
85
74
  request.transactionValue ?? "",
86
75
  request.currency || "",
76
+ // SECURITY (cross-merchant cache leak): the merchant identity is sent via
77
+ // `config.counterpartyId`, NOT on the request, so it was previously absent
78
+ // from the key — two verifies for the SAME agent/purpose/action/value but
79
+ // DIFFERENT merchants collided, and a grant at a permissive merchant (low
80
+ // trust floor) was served for a stricter one. Same bug class as the
81
+ // duration omission (F-A1-07). counterpartyId affects the backend verdict
82
+ // (trust floor / per-route policy), so it MUST key the cache.
83
+ counterpartyId || "",
87
84
  request.counterpartyUrl || "",
88
85
  request.counterpartyType || "",
89
86
  request.isSubAgentRequest ? "1" : "0",
@@ -107,8 +104,8 @@ function getCacheKey(request) {
107
104
  request.callerMetadata?.agentCardUrl || ""
108
105
  ].join("|");
109
106
  }
110
- function getCachedResult(request) {
111
- const key = getCacheKey(request);
107
+ function getCachedResult(request, counterpartyId) {
108
+ const key = getCacheKey(request, counterpartyId);
112
109
  const cached = verificationCache.get(key);
113
110
  if (cached && cached.expiresAt > Date.now()) {
114
111
  return cached.result;
@@ -120,9 +117,9 @@ function getCachedResult(request) {
120
117
  }
121
118
  var DEFAULT_AUTONOMOUS_TTL_SECONDS = 60;
122
119
  var DEFAULT_STEP_UP_TTL_SECONDS = 300;
123
- function cacheResult(request, result, configuredTtl) {
120
+ function cacheResult(request, result, configuredTtl, counterpartyId) {
124
121
  const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl : result.requiresStepUp ? DEFAULT_STEP_UP_TTL_SECONDS : DEFAULT_AUTONOMOUS_TTL_SECONDS;
125
- const key = getCacheKey(request);
122
+ const key = getCacheKey(request, counterpartyId);
126
123
  verificationCache.set(key, {
127
124
  result,
128
125
  expiresAt: Date.now() + ttlSeconds * 1e3
@@ -280,7 +277,7 @@ async function verify(config, request) {
280
277
  );
281
278
  }
282
279
  if (mergedConfig.cacheTtl !== 0) {
283
- const cached = getCachedResult(request);
280
+ const cached = getCachedResult(request, mergedConfig.counterpartyId);
284
281
  if (cached) {
285
282
  if (mergedConfig.debug) {
286
283
  console.log("[VerificationGateway] Returning cached result");
@@ -332,8 +329,8 @@ async function verify(config, request) {
332
329
  verifiedAt: /* @__PURE__ */ new Date(),
333
330
  // Extract sessionId so decisions can be recorded for denials too
334
331
  sessionId: apiResponse.sessionId,
335
- // v2.3.10 (defect #34, round-4): anonymous traffic has no session →
336
- // correlationId is the linking key for paired local_override events.
332
+ // Anonymous traffic has no session → correlationId is the per-attempt
333
+ // linking key (the sessionId-equivalent for anonymous callers).
337
334
  correlationId: apiResponse.correlationId,
338
335
  recommendation: apiResponse.recommendation,
339
336
  recommendationReasons: apiResponse.recommendationReasons
@@ -407,13 +404,10 @@ async function verify(config, request) {
407
404
  };
408
405
  } else if (result.recommendation === "step_up_required") {
409
406
  result.requiresStepUp = true;
410
- if (ACCESS_LEVEL_HIERARCHY[result.accessLevel] > ACCESS_LEVEL_HIERARCHY["read-only"]) {
411
- result.accessLevel = "read-only";
412
- }
413
407
  result.denialReasons = result.recommendationReasons || ["Step-up verification required"];
414
408
  }
415
409
  if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny") {
416
- cacheResult(request, result, mergedConfig.cacheTtl);
410
+ cacheResult(request, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
417
411
  }
418
412
  return result;
419
413
  }
@@ -619,6 +613,19 @@ function resolveHttpPdlss(input) {
619
613
  return { purpose, action, purposeSource, actionSource };
620
614
  }
621
615
 
616
+ // src/adapters/approval-gate.ts
617
+ var APPROVAL_REASON = "Transaction is above the autonomous limit and requires human approval, which is not yet available \u2014 it cannot be completed automatically.";
618
+ function requiresHumanApproval(result) {
619
+ return result.requiresStepUp === true || result.requiresApproval === true;
620
+ }
621
+ function annotateApprovalRequired(result) {
622
+ result.failures = [
623
+ ...result.failures ?? [],
624
+ { dimension: "commerce.intent.approval_required", message: APPROVAL_REASON }
625
+ ];
626
+ result.denialReasons = [APPROVAL_REASON, ...result.denialReasons ?? []];
627
+ }
628
+
622
629
  // src/adapters/nextjs.ts
623
630
  function escapeHtml(value) {
624
631
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
@@ -978,7 +985,9 @@ function createMiddleware(options) {
978
985
  agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
979
986
  }
980
987
  });
981
- if (!result.identityVerified || !result.policyAllowed || !hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
988
+ const approvalRequired = result.identityVerified && result.policyAllowed && requiresHumanApproval(result);
989
+ if (approvalRequired) annotateApprovalRequired(result);
990
+ if (!result.identityVerified || !result.policyAllowed || approvalRequired) {
982
991
  if (pathname.startsWith("/api/")) {
983
992
  return NextResponse.json(
984
993
  {
@@ -986,11 +995,10 @@ function createMiddleware(options) {
986
995
  error: {
987
996
  // Round-18 G4: 401 → identity missing (re-auth); 403 → identity
988
997
  // OK, policy denied (update PDLSS / step up).
989
- code: !result.identityVerified ? "UNAUTHORIZED" : "INSUFFICIENT_ACCESS",
998
+ code: !result.identityVerified ? "UNAUTHORIZED" : "POLICY_DENIED",
990
999
  message: result.denialReasons?.[0] || "Access denied",
991
- accessLevel: result.accessLevel,
992
- required: routeConfig.minAccessLevel,
993
- guidance: result.guidance
1000
+ guidance: result.guidance,
1001
+ failures: result.failures
994
1002
  }
995
1003
  },
996
1004
  { status: !result.identityVerified ? 401 : 403 }
@@ -1017,7 +1025,6 @@ function createMiddleware(options) {
1017
1025
  response.headers.set("X-AstraSync-Access-Level", result.accessLevel);
1018
1026
  if (result.agent) {
1019
1027
  response.headers.set("X-AstraSync-Agent-Id", result.agent.astraId);
1020
- response.headers.set("X-AstraSync-Trust-Score", result.agent.trustScore.toString());
1021
1028
  }
1022
1029
  return response;
1023
1030
  };