@astrasyncai/verification-gateway 2.4.8 → 2.4.10

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 (89) 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 +81 -31
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +81 -31
  8. package/dist/adapters/express.mjs.map +1 -1
  9. package/dist/adapters/mcp.d.mts +1 -1
  10. package/dist/adapters/mcp.d.ts +1 -1
  11. package/dist/adapters/mcp.js +64 -26
  12. package/dist/adapters/mcp.js.map +1 -1
  13. package/dist/adapters/mcp.mjs +64 -26
  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 +89 -32
  18. package/dist/adapters/nextjs.js.map +1 -1
  19. package/dist/adapters/nextjs.mjs +89 -32
  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 +65 -25
  24. package/dist/adapters/sdk.js.map +1 -1
  25. package/dist/adapters/sdk.mjs +65 -25
  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 +60 -25
  30. package/dist/browser/background.js.map +1 -1
  31. package/dist/browser/background.mjs +60 -25
  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 +60 -25
  42. package/dist/cursor/extension.js.map +1 -1
  43. package/dist/cursor/extension.mjs +60 -25
  44. package/dist/cursor/extension.mjs.map +1 -1
  45. package/dist/{express-DvVjR2H4.d.mts → express-4WStX3PV.d.mts} +1 -1
  46. package/dist/{express-714gJbaW.d.ts → express-C1ePFB7n.d.ts} +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 +60 -25
  50. package/dist/gateway/gateway.js.map +1 -1
  51. package/dist/gateway/gateway.mjs +60 -25
  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-DYFS9QVb.d.mts → index-ChPX4WHl.d.mts} +1 -1
  56. package/dist/{index-DO0oG8ED.d.ts → index-Cjm-zBeZ.d.ts} +1 -1
  57. package/dist/{index-2WAlxs2G.d.ts → index-CzJMCgEy.d.ts} +1 -1
  58. package/dist/{index-P9t7M_dJ.d.mts → index-D8IEntil.d.mts} +1 -1
  59. package/dist/index.d.mts +22 -11
  60. package/dist/index.d.ts +22 -11
  61. package/dist/index.js +133 -42
  62. package/dist/index.js.map +1 -1
  63. package/dist/index.mjs +132 -42
  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-CZ-MwSOT.d.ts → nextjs-BIORS__0.d.ts} +1 -1
  68. package/dist/{nextjs-BCoH7EqF.d.mts → nextjs-CjzHdaXA.d.mts} +1 -1
  69. package/dist/registration/index.d.mts +76 -1
  70. package/dist/registration/index.d.ts +76 -1
  71. package/dist/registration/index.js +27 -2
  72. package/dist/registration/index.js.map +1 -1
  73. package/dist/registration/index.mjs +25 -1
  74. package/dist/registration/index.mjs.map +1 -1
  75. package/dist/{sdk-wwhFDXWX.d.mts → sdk-Chhz-FcT.d.mts} +9 -4
  76. package/dist/{sdk-kiA49vqJ.d.ts → sdk-CqTEQAc6.d.ts} +9 -4
  77. package/dist/transport/index.d.mts +2 -2
  78. package/dist/transport/index.d.ts +2 -2
  79. package/dist/{types-DOAb89cm.d.mts → types-DNK2BgIf.d.mts} +1 -1
  80. package/dist/{types-aucqzfUa.d.ts → types-DoWIuzfj.d.ts} +1 -1
  81. package/dist/{types-BwDmjIdr.d.mts → types-L15pYd2c.d.mts} +21 -4
  82. package/dist/{types-BwDmjIdr.d.ts → types-L15pYd2c.d.ts} +21 -4
  83. package/dist/ui/index.d.mts +1 -1
  84. package/dist/ui/index.d.ts +1 -1
  85. package/dist/ui/index.js +1 -1
  86. package/dist/ui/index.js.map +1 -1
  87. package/dist/ui/index.mjs +1 -1
  88. package/dist/ui/index.mjs.map +1 -1
  89. package/package.json +1 -1
@@ -18,7 +18,7 @@ function hasMinimumAccess(actual, required) {
18
18
  }
19
19
 
20
20
  // src/version.ts
21
- var SDK_VERSION = "2.4.7";
21
+ var SDK_VERSION = "2.4.10";
22
22
 
23
23
  // src/verify.ts
24
24
  var DEFAULT_CONFIG = {
@@ -29,8 +29,10 @@ var DEFAULT_CONFIG = {
29
29
  // through (`hasMinimumAccess('guidance', 'guidance') === true`).
30
30
  defaultAccessLevel: "none",
31
31
  // minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
32
- cacheTtl: 300,
33
- // 5 minutes
32
+ // Round-18.5 F4: cacheTtl deliberately unset. When undefined, cacheResult
33
+ // applies the split default (60s autonomous / 300s step-up). When the
34
+ // caller sets cacheTtl explicitly, that value is honoured uniformly.
35
+ // Set cacheTtl: 0 to disable caching entirely.
34
36
  debug: false
35
37
  };
36
38
  var initCheckPerformed = false;
@@ -57,11 +59,28 @@ async function performInitCheck(apiBaseUrl, debug) {
57
59
  }
58
60
  }
59
61
  var verificationCache = /* @__PURE__ */ new Map();
60
- function getCacheKey(credentials) {
61
- return `${credentials.astraId || ""}-${credentials.apiKey || ""}-${credentials.jwt || ""}`;
62
+ function getCacheKey(request) {
63
+ const c = request.credentials;
64
+ return [
65
+ c.astraId || "",
66
+ c.apiKey || "",
67
+ c.jwt || "",
68
+ request.purpose || "",
69
+ request.action || "",
70
+ request.resourceType || "",
71
+ request.resource || "",
72
+ request.jurisdiction || "",
73
+ request.transactionValue ?? "",
74
+ request.currency || "",
75
+ request.counterpartyUrl || "",
76
+ request.counterpartyType || "",
77
+ request.isSubAgentRequest ? "1" : "0",
78
+ request.parentAgentId || "",
79
+ request.subAgentDepth ?? ""
80
+ ].join("|");
62
81
  }
63
- function getCachedResult(credentials) {
64
- const key = getCacheKey(credentials);
82
+ function getCachedResult(request) {
83
+ const key = getCacheKey(request);
65
84
  const cached = verificationCache.get(key);
66
85
  if (cached && cached.expiresAt > Date.now()) {
67
86
  return cached.result;
@@ -71,8 +90,11 @@ function getCachedResult(credentials) {
71
90
  }
72
91
  return null;
73
92
  }
74
- function cacheResult(credentials, result, ttlSeconds) {
75
- const key = getCacheKey(credentials);
93
+ var DEFAULT_AUTONOMOUS_TTL_SECONDS = 60;
94
+ var DEFAULT_STEP_UP_TTL_SECONDS = 300;
95
+ function cacheResult(request, result, configuredTtl) {
96
+ const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl : result.requiresStepUp ? DEFAULT_STEP_UP_TTL_SECONDS : DEFAULT_AUTONOMOUS_TTL_SECONDS;
97
+ const key = getCacheKey(request);
76
98
  verificationCache.set(key, {
77
99
  result,
78
100
  expiresAt: Date.now() + ttlSeconds * 1e3
@@ -129,12 +151,17 @@ function createGuidanceResponse(config, reason, options = {}) {
129
151
  ]
130
152
  };
131
153
  return {
132
- verified: false,
154
+ // Round-18 G4: createGuidanceResponse fires for unverified-agent path or
155
+ // API-error fallback. Identity is not verified (no agent resolved);
156
+ // policy is not evaluated (we never reached the gate).
157
+ identityVerified: false,
158
+ policyAllowed: false,
133
159
  // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
134
- // Adapters additionally short-circuit on `verified === false` before
135
- // the gate check, but the access level still has to be honest at the
136
- // data layer so downstream consumers (SDK adapters in other languages,
137
- // custom integrations) inherit the correct semantics.
160
+ // Adapters additionally short-circuit on `!identityVerified ||
161
+ // !policyAllowed` before the gate check, but the access level still has
162
+ // to be honest at the data layer so downstream consumers (SDK adapters
163
+ // in other languages, custom integrations) inherit the correct
164
+ // semantics.
138
165
  accessLevel: "none",
139
166
  guidance,
140
167
  denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
@@ -250,8 +277,8 @@ async function verify(config, request) {
250
277
  "[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access-level decisions (the SDK reads access.accessLevel from the verify-access response). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
251
278
  );
252
279
  }
253
- if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0) {
254
- const cached = getCachedResult(request.credentials);
280
+ if (mergedConfig.cacheTtl !== 0) {
281
+ const cached = getCachedResult(request);
255
282
  if (cached) {
256
283
  if (mergedConfig.debug) {
257
284
  console.log("[VerificationGateway] Returning cached result");
@@ -278,15 +305,17 @@ async function verify(config, request) {
278
305
  }
279
306
  if (!apiResponse.access?.allowed) {
280
307
  const aggregatedFailures = apiResponse.access?.failures;
308
+ const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
281
309
  const result2 = {
282
- verified: false,
310
+ identityVerified: idVerifiedFromBackend,
311
+ policyAllowed: false,
283
312
  // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
284
313
  // Pre-rename this hardcoded `'guidance'`, which conflated with the
285
314
  // colocated `guidance: {...}` help-payload object below and let
286
315
  // denied requests pass any route gated at `'guidance'` because
287
316
  // `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now
288
- // ALSO short-circuit on `verified === false` before the gate check —
289
- // belt-and-braces.
317
+ // ALSO short-circuit on `!identityVerified || !policyAllowed` before
318
+ // the gate check — belt-and-braces.
290
319
  accessLevel: "none",
291
320
  denialReasons: aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"],
292
321
  failures: aggregatedFailures,
@@ -330,7 +359,13 @@ async function verify(config, request) {
330
359
  const verificationContext = apiResponse.verificationContext;
331
360
  const accessLevel = apiResponse.access?.accessLevel ?? "standard";
332
361
  const result = {
333
- verified: true,
362
+ // Round-18 G4: backend allowed access. Identity is verified (we resolved
363
+ // the caller to an agent) and policy passed all gates. Read idVerified
364
+ // from verificationContext for symmetry with the deny branch; default true
365
+ // on success path since `access.allowed === true` implies identity was
366
+ // resolvable (anonymous-allow paths flow through createGuidanceResponse).
367
+ identityVerified: apiResponse.verificationContext?.idVerified !== false,
368
+ policyAllowed: true,
334
369
  accessLevel,
335
370
  agent,
336
371
  developer,
@@ -353,7 +388,7 @@ async function verify(config, request) {
353
388
  warningHeader: apiResponse.warningHeader
354
389
  };
355
390
  if (result.recommendation === "deny") {
356
- result.verified = false;
391
+ result.policyAllowed = false;
357
392
  result.accessLevel = "none";
358
393
  result.denialReasons = result.recommendationReasons || [
359
394
  "Access denied by AstraSync recommendation"
@@ -372,8 +407,8 @@ async function verify(config, request) {
372
407
  }
373
408
  result.denialReasons = result.recommendationReasons || ["Step-up verification required"];
374
409
  }
375
- if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0 && result.recommendation !== "deny") {
376
- cacheResult(request.credentials, result, mergedConfig.cacheTtl);
410
+ if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny") {
411
+ cacheResult(request, result, mergedConfig.cacheTtl);
377
412
  }
378
413
  return result;
379
414
  }
@@ -470,8 +505,15 @@ function extractHttpCredentials(headers) {
470
505
  // src/pdlss-pre-check.ts
471
506
  function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
472
507
  const failures = [];
473
- if (routeConfig.allowedPurposes && routeConfig.allowedPurposes.length > 0 && purpose) {
474
- if (!routeConfig.allowedPurposes.includes(purpose)) {
508
+ if (purpose) {
509
+ if (!routeConfig.allowedPurposes || routeConfig.allowedPurposes.length === 0) {
510
+ failures.push({
511
+ field: "purpose",
512
+ requested: purpose,
513
+ limit: [],
514
+ message: `Purpose "${purpose}" not allowed: route declares no allowedPurposes. The endpoint owner must enumerate allowedPurposes on the route config to authorise specific purposes.`
515
+ });
516
+ } else if (!routeConfig.allowedPurposes.includes(purpose)) {
475
517
  failures.push({
476
518
  field: "purpose",
477
519
  requested: purpose,
@@ -501,9 +543,16 @@ function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
501
543
  });
502
544
  }
503
545
  }
504
- if (routeConfig.allowedJurisdictions && routeConfig.allowedJurisdictions.length > 0 && astraCreds?.pdlss?.scope?.jurisdiction) {
546
+ if (astraCreds?.pdlss?.scope?.jurisdiction) {
505
547
  const requested = astraCreds.pdlss.scope.jurisdiction;
506
- if (!routeConfig.allowedJurisdictions.includes(requested)) {
548
+ if (!routeConfig.allowedJurisdictions || routeConfig.allowedJurisdictions.length === 0) {
549
+ failures.push({
550
+ field: "jurisdiction",
551
+ requested,
552
+ limit: [],
553
+ message: `Jurisdiction "${requested}" not allowed: route declares no allowedJurisdictions. The endpoint owner must enumerate allowedJurisdictions on the route config to authorise specific jurisdictions.`
554
+ });
555
+ } else if (!routeConfig.allowedJurisdictions.includes(requested)) {
507
556
  failures.push({
508
557
  field: "jurisdiction",
509
558
  requested,
@@ -566,12 +615,12 @@ function findRouteConfig(routes, path, method) {
566
615
  });
567
616
  }
568
617
  function defaultOnDenied(result, _req, res) {
569
- const statusCode = result.verified ? 403 : 401;
618
+ const statusCode = !result.identityVerified ? 401 : 403;
570
619
  res.setHeader("X-Astra-Gateway-Mode", "enforced");
571
620
  res.status(statusCode).json({
572
621
  success: false,
573
622
  error: {
574
- code: result.verified ? "INSUFFICIENT_ACCESS" : "UNAUTHORIZED",
623
+ code: !result.identityVerified ? "UNAUTHORIZED" : "INSUFFICIENT_ACCESS",
575
624
  message: result.denialReasons?.[0] || "Access denied",
576
625
  accessLevel: result.accessLevel,
577
626
  guidance: result.guidance,
@@ -665,7 +714,8 @@ function createMiddleware(options) {
665
714
  const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);
666
715
  if (preCheckFailures.length > 0) {
667
716
  const result2 = {
668
- verified: false,
717
+ identityVerified: false,
718
+ policyAllowed: false,
669
719
  accessLevel: "none",
670
720
  denialReasons: preCheckFailures.map((f) => f.message),
671
721
  guidance: {
@@ -714,7 +764,7 @@ function createMiddleware(options) {
714
764
  });
715
765
  req.agentVerification = result;
716
766
  const sessionId = result.sessionId;
717
- if (!result.verified) {
767
+ if (!result.identityVerified || !result.policyAllowed) {
718
768
  if (shouldRecordDecisions && sessionId) {
719
769
  recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
720
770
  });