@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
@@ -101,12 +123,17 @@ function createGuidanceResponse(config, reason, options = {}) {
101
123
  ]
102
124
  };
103
125
  return {
104
- verified: false,
126
+ // Round-18 G4: createGuidanceResponse fires for unverified-agent path or
127
+ // API-error fallback. Identity is not verified (no agent resolved);
128
+ // policy is not evaluated (we never reached the gate).
129
+ identityVerified: false,
130
+ policyAllowed: false,
105
131
  // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
106
- // Adapters additionally short-circuit on `verified === false` before
107
- // the gate check, but the access level still has to be honest at the
108
- // data layer so downstream consumers (SDK adapters in other languages,
109
- // custom integrations) inherit the correct semantics.
132
+ // Adapters additionally short-circuit on `!identityVerified ||
133
+ // !policyAllowed` before the gate check, but the access level still has
134
+ // to be honest at the data layer so downstream consumers (SDK adapters
135
+ // in other languages, custom integrations) inherit the correct
136
+ // semantics.
110
137
  accessLevel: "none",
111
138
  guidance,
112
139
  denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
@@ -222,8 +249,8 @@ async function verify(config, request) {
222
249
  "[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."
223
250
  );
224
251
  }
225
- if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0) {
226
- const cached = getCachedResult(request.credentials);
252
+ if (mergedConfig.cacheTtl !== 0) {
253
+ const cached = getCachedResult(request);
227
254
  if (cached) {
228
255
  if (mergedConfig.debug) {
229
256
  console.log("[VerificationGateway] Returning cached result");
@@ -250,15 +277,17 @@ async function verify(config, request) {
250
277
  }
251
278
  if (!apiResponse.access?.allowed) {
252
279
  const aggregatedFailures = apiResponse.access?.failures;
280
+ const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
253
281
  const result2 = {
254
- verified: false,
282
+ identityVerified: idVerifiedFromBackend,
283
+ policyAllowed: false,
255
284
  // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
256
285
  // Pre-rename this hardcoded `'guidance'`, which conflated with the
257
286
  // colocated `guidance: {...}` help-payload object below and let
258
287
  // denied requests pass any route gated at `'guidance'` because
259
288
  // `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now
260
- // ALSO short-circuit on `verified === false` before the gate check —
261
- // belt-and-braces.
289
+ // ALSO short-circuit on `!identityVerified || !policyAllowed` before
290
+ // the gate check — belt-and-braces.
262
291
  accessLevel: "none",
263
292
  denialReasons: aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"],
264
293
  failures: aggregatedFailures,
@@ -302,7 +331,13 @@ async function verify(config, request) {
302
331
  const verificationContext = apiResponse.verificationContext;
303
332
  const accessLevel = apiResponse.access?.accessLevel ?? "standard";
304
333
  const result = {
305
- verified: true,
334
+ // Round-18 G4: backend allowed access. Identity is verified (we resolved
335
+ // the caller to an agent) and policy passed all gates. Read idVerified
336
+ // from verificationContext for symmetry with the deny branch; default true
337
+ // on success path since `access.allowed === true` implies identity was
338
+ // resolvable (anonymous-allow paths flow through createGuidanceResponse).
339
+ identityVerified: apiResponse.verificationContext?.idVerified !== false,
340
+ policyAllowed: true,
306
341
  accessLevel,
307
342
  agent,
308
343
  developer,
@@ -325,7 +360,7 @@ async function verify(config, request) {
325
360
  warningHeader: apiResponse.warningHeader
326
361
  };
327
362
  if (result.recommendation === "deny") {
328
- result.verified = false;
363
+ result.policyAllowed = false;
329
364
  result.accessLevel = "none";
330
365
  result.denialReasons = result.recommendationReasons || [
331
366
  "Access denied by AstraSync recommendation"
@@ -344,8 +379,8 @@ async function verify(config, request) {
344
379
  }
345
380
  result.denialReasons = result.recommendationReasons || ["Step-up verification required"];
346
381
  }
347
- if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0 && result.recommendation !== "deny") {
348
- cacheResult(request.credentials, result, mergedConfig.cacheTtl);
382
+ if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny") {
383
+ cacheResult(request, result, mergedConfig.cacheTtl);
349
384
  }
350
385
  return result;
351
386
  }
@@ -420,8 +455,15 @@ function extractHttpCredentials(headers) {
420
455
  // src/pdlss-pre-check.ts
421
456
  function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
422
457
  const failures = [];
423
- if (routeConfig.allowedPurposes && routeConfig.allowedPurposes.length > 0 && purpose) {
424
- if (!routeConfig.allowedPurposes.includes(purpose)) {
458
+ if (purpose) {
459
+ if (!routeConfig.allowedPurposes || routeConfig.allowedPurposes.length === 0) {
460
+ failures.push({
461
+ field: "purpose",
462
+ requested: purpose,
463
+ limit: [],
464
+ message: `Purpose "${purpose}" not allowed: route declares no allowedPurposes. The endpoint owner must enumerate allowedPurposes on the route config to authorise specific purposes.`
465
+ });
466
+ } else if (!routeConfig.allowedPurposes.includes(purpose)) {
425
467
  failures.push({
426
468
  field: "purpose",
427
469
  requested: purpose,
@@ -451,9 +493,16 @@ function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
451
493
  });
452
494
  }
453
495
  }
454
- if (routeConfig.allowedJurisdictions && routeConfig.allowedJurisdictions.length > 0 && astraCreds?.pdlss?.scope?.jurisdiction) {
496
+ if (astraCreds?.pdlss?.scope?.jurisdiction) {
455
497
  const requested = astraCreds.pdlss.scope.jurisdiction;
456
- if (!routeConfig.allowedJurisdictions.includes(requested)) {
498
+ if (!routeConfig.allowedJurisdictions || routeConfig.allowedJurisdictions.length === 0) {
499
+ failures.push({
500
+ field: "jurisdiction",
501
+ requested,
502
+ limit: [],
503
+ message: `Jurisdiction "${requested}" not allowed: route declares no allowedJurisdictions. The endpoint owner must enumerate allowedJurisdictions on the route config to authorise specific jurisdictions.`
504
+ });
505
+ } else if (!routeConfig.allowedJurisdictions.includes(requested)) {
457
506
  failures.push({
458
507
  field: "jurisdiction",
459
508
  requested,
@@ -744,7 +793,8 @@ function createMiddleware(options) {
744
793
  const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);
745
794
  if (preCheckFailures.length > 0) {
746
795
  const preCheckResult = {
747
- verified: false,
796
+ identityVerified: false,
797
+ policyAllowed: false,
748
798
  accessLevel: "none",
749
799
  denialReasons: preCheckFailures.map((f) => f.message),
750
800
  guidance: {
@@ -807,20 +857,22 @@ function createMiddleware(options) {
807
857
  agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
808
858
  }
809
859
  });
810
- if (!result.verified || !hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
860
+ if (!result.identityVerified || !result.policyAllowed || !hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
811
861
  if (pathname.startsWith("/api/")) {
812
862
  return NextResponse.json(
813
863
  {
814
864
  success: false,
815
865
  error: {
816
- code: result.verified ? "INSUFFICIENT_ACCESS" : "UNAUTHORIZED",
866
+ // Round-18 G4: 401 identity missing (re-auth); 403 → identity
867
+ // OK, policy denied (update PDLSS / step up).
868
+ code: !result.identityVerified ? "UNAUTHORIZED" : "INSUFFICIENT_ACCESS",
817
869
  message: result.denialReasons?.[0] || "Access denied",
818
870
  accessLevel: result.accessLevel,
819
871
  required: routeConfig.minAccessLevel,
820
872
  guidance: result.guidance
821
873
  }
822
874
  },
823
- { status: result.verified ? 403 : 401 }
875
+ { status: !result.identityVerified ? 401 : 403 }
824
876
  );
825
877
  }
826
878
  if (showCommerceShield) {
@@ -835,7 +887,12 @@ function createMiddleware(options) {
835
887
  return NextResponse.redirect(new URL("/unauthorized", request.url));
836
888
  }
837
889
  const response = NextResponse.next();
838
- response.headers.set("X-AstraSync-Verified", result.verified.toString());
890
+ response.headers.set(
891
+ "X-AstraSync-Verified",
892
+ (result.identityVerified && result.policyAllowed).toString()
893
+ );
894
+ response.headers.set("X-AstraSync-Identity-Verified", result.identityVerified.toString());
895
+ response.headers.set("X-AstraSync-Policy-Allowed", result.policyAllowed.toString());
839
896
  response.headers.set("X-AstraSync-Access-Level", result.accessLevel);
840
897
  if (result.agent) {
841
898
  response.headers.set("X-AstraSync-Agent-Id", result.agent.astraId);