@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
@@ -55,7 +55,7 @@ function hasMinimumAccess(actual, required) {
55
55
  }
56
56
 
57
57
  // src/version.ts
58
- var SDK_VERSION = "2.4.7";
58
+ var SDK_VERSION = "2.4.10";
59
59
 
60
60
  // src/verify.ts
61
61
  var DEFAULT_CONFIG = {
@@ -66,8 +66,10 @@ var DEFAULT_CONFIG = {
66
66
  // through (`hasMinimumAccess('guidance', 'guidance') === true`).
67
67
  defaultAccessLevel: "none",
68
68
  // minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
69
- cacheTtl: 300,
70
- // 5 minutes
69
+ // Round-18.5 F4: cacheTtl deliberately unset. When undefined, cacheResult
70
+ // applies the split default (60s autonomous / 300s step-up). When the
71
+ // caller sets cacheTtl explicitly, that value is honoured uniformly.
72
+ // Set cacheTtl: 0 to disable caching entirely.
71
73
  debug: false
72
74
  };
73
75
  var initCheckPerformed = false;
@@ -94,11 +96,28 @@ async function performInitCheck(apiBaseUrl, debug) {
94
96
  }
95
97
  }
96
98
  var verificationCache = /* @__PURE__ */ new Map();
97
- function getCacheKey(credentials) {
98
- return `${credentials.astraId || ""}-${credentials.apiKey || ""}-${credentials.jwt || ""}`;
99
+ function getCacheKey(request) {
100
+ const c = request.credentials;
101
+ return [
102
+ c.astraId || "",
103
+ c.apiKey || "",
104
+ c.jwt || "",
105
+ request.purpose || "",
106
+ request.action || "",
107
+ request.resourceType || "",
108
+ request.resource || "",
109
+ request.jurisdiction || "",
110
+ request.transactionValue ?? "",
111
+ request.currency || "",
112
+ request.counterpartyUrl || "",
113
+ request.counterpartyType || "",
114
+ request.isSubAgentRequest ? "1" : "0",
115
+ request.parentAgentId || "",
116
+ request.subAgentDepth ?? ""
117
+ ].join("|");
99
118
  }
100
- function getCachedResult(credentials) {
101
- const key = getCacheKey(credentials);
119
+ function getCachedResult(request) {
120
+ const key = getCacheKey(request);
102
121
  const cached = verificationCache.get(key);
103
122
  if (cached && cached.expiresAt > Date.now()) {
104
123
  return cached.result;
@@ -108,8 +127,11 @@ function getCachedResult(credentials) {
108
127
  }
109
128
  return null;
110
129
  }
111
- function cacheResult(credentials, result, ttlSeconds) {
112
- const key = getCacheKey(credentials);
130
+ var DEFAULT_AUTONOMOUS_TTL_SECONDS = 60;
131
+ var DEFAULT_STEP_UP_TTL_SECONDS = 300;
132
+ function cacheResult(request, result, configuredTtl) {
133
+ const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl : result.requiresStepUp ? DEFAULT_STEP_UP_TTL_SECONDS : DEFAULT_AUTONOMOUS_TTL_SECONDS;
134
+ const key = getCacheKey(request);
113
135
  verificationCache.set(key, {
114
136
  result,
115
137
  expiresAt: Date.now() + ttlSeconds * 1e3
@@ -138,12 +160,17 @@ function createGuidanceResponse(config, reason, options = {}) {
138
160
  ]
139
161
  };
140
162
  return {
141
- verified: false,
163
+ // Round-18 G4: createGuidanceResponse fires for unverified-agent path or
164
+ // API-error fallback. Identity is not verified (no agent resolved);
165
+ // policy is not evaluated (we never reached the gate).
166
+ identityVerified: false,
167
+ policyAllowed: false,
142
168
  // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
143
- // Adapters additionally short-circuit on `verified === false` before
144
- // the gate check, but the access level still has to be honest at the
145
- // data layer so downstream consumers (SDK adapters in other languages,
146
- // custom integrations) inherit the correct semantics.
169
+ // Adapters additionally short-circuit on `!identityVerified ||
170
+ // !policyAllowed` before the gate check, but the access level still has
171
+ // to be honest at the data layer so downstream consumers (SDK adapters
172
+ // in other languages, custom integrations) inherit the correct
173
+ // semantics.
147
174
  accessLevel: "none",
148
175
  guidance,
149
176
  denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
@@ -259,8 +286,8 @@ async function verify(config, request) {
259
286
  "[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."
260
287
  );
261
288
  }
262
- if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0) {
263
- const cached = getCachedResult(request.credentials);
289
+ if (mergedConfig.cacheTtl !== 0) {
290
+ const cached = getCachedResult(request);
264
291
  if (cached) {
265
292
  if (mergedConfig.debug) {
266
293
  console.log("[VerificationGateway] Returning cached result");
@@ -287,15 +314,17 @@ async function verify(config, request) {
287
314
  }
288
315
  if (!apiResponse.access?.allowed) {
289
316
  const aggregatedFailures = apiResponse.access?.failures;
317
+ const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
290
318
  const result2 = {
291
- verified: false,
319
+ identityVerified: idVerifiedFromBackend,
320
+ policyAllowed: false,
292
321
  // v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
293
322
  // Pre-rename this hardcoded `'guidance'`, which conflated with the
294
323
  // colocated `guidance: {...}` help-payload object below and let
295
324
  // denied requests pass any route gated at `'guidance'` because
296
325
  // `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now
297
- // ALSO short-circuit on `verified === false` before the gate check —
298
- // belt-and-braces.
326
+ // ALSO short-circuit on `!identityVerified || !policyAllowed` before
327
+ // the gate check — belt-and-braces.
299
328
  accessLevel: "none",
300
329
  denialReasons: aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"],
301
330
  failures: aggregatedFailures,
@@ -339,7 +368,13 @@ async function verify(config, request) {
339
368
  const verificationContext = apiResponse.verificationContext;
340
369
  const accessLevel = apiResponse.access?.accessLevel ?? "standard";
341
370
  const result = {
342
- verified: true,
371
+ // Round-18 G4: backend allowed access. Identity is verified (we resolved
372
+ // the caller to an agent) and policy passed all gates. Read idVerified
373
+ // from verificationContext for symmetry with the deny branch; default true
374
+ // on success path since `access.allowed === true` implies identity was
375
+ // resolvable (anonymous-allow paths flow through createGuidanceResponse).
376
+ identityVerified: apiResponse.verificationContext?.idVerified !== false,
377
+ policyAllowed: true,
343
378
  accessLevel,
344
379
  agent,
345
380
  developer,
@@ -362,7 +397,7 @@ async function verify(config, request) {
362
397
  warningHeader: apiResponse.warningHeader
363
398
  };
364
399
  if (result.recommendation === "deny") {
365
- result.verified = false;
400
+ result.policyAllowed = false;
366
401
  result.accessLevel = "none";
367
402
  result.denialReasons = result.recommendationReasons || [
368
403
  "Access denied by AstraSync recommendation"
@@ -381,8 +416,8 @@ async function verify(config, request) {
381
416
  }
382
417
  result.denialReasons = result.recommendationReasons || ["Step-up verification required"];
383
418
  }
384
- if (mergedConfig.cacheTtl && mergedConfig.cacheTtl > 0 && result.recommendation !== "deny") {
385
- cacheResult(request.credentials, result, mergedConfig.cacheTtl);
419
+ if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny") {
420
+ cacheResult(request, result, mergedConfig.cacheTtl);
386
421
  }
387
422
  return result;
388
423
  }
@@ -457,8 +492,15 @@ function extractHttpCredentials(headers) {
457
492
  // src/pdlss-pre-check.ts
458
493
  function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
459
494
  const failures = [];
460
- if (routeConfig.allowedPurposes && routeConfig.allowedPurposes.length > 0 && purpose) {
461
- if (!routeConfig.allowedPurposes.includes(purpose)) {
495
+ if (purpose) {
496
+ if (!routeConfig.allowedPurposes || routeConfig.allowedPurposes.length === 0) {
497
+ failures.push({
498
+ field: "purpose",
499
+ requested: purpose,
500
+ limit: [],
501
+ message: `Purpose "${purpose}" not allowed: route declares no allowedPurposes. The endpoint owner must enumerate allowedPurposes on the route config to authorise specific purposes.`
502
+ });
503
+ } else if (!routeConfig.allowedPurposes.includes(purpose)) {
462
504
  failures.push({
463
505
  field: "purpose",
464
506
  requested: purpose,
@@ -488,9 +530,16 @@ function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
488
530
  });
489
531
  }
490
532
  }
491
- if (routeConfig.allowedJurisdictions && routeConfig.allowedJurisdictions.length > 0 && astraCreds?.pdlss?.scope?.jurisdiction) {
533
+ if (astraCreds?.pdlss?.scope?.jurisdiction) {
492
534
  const requested = astraCreds.pdlss.scope.jurisdiction;
493
- if (!routeConfig.allowedJurisdictions.includes(requested)) {
535
+ if (!routeConfig.allowedJurisdictions || routeConfig.allowedJurisdictions.length === 0) {
536
+ failures.push({
537
+ field: "jurisdiction",
538
+ requested,
539
+ limit: [],
540
+ message: `Jurisdiction "${requested}" not allowed: route declares no allowedJurisdictions. The endpoint owner must enumerate allowedJurisdictions on the route config to authorise specific jurisdictions.`
541
+ });
542
+ } else if (!routeConfig.allowedJurisdictions.includes(requested)) {
494
543
  failures.push({
495
544
  field: "jurisdiction",
496
545
  requested,
@@ -781,7 +830,8 @@ function createMiddleware(options) {
781
830
  const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);
782
831
  if (preCheckFailures.length > 0) {
783
832
  const preCheckResult = {
784
- verified: false,
833
+ identityVerified: false,
834
+ policyAllowed: false,
785
835
  accessLevel: "none",
786
836
  denialReasons: preCheckFailures.map((f) => f.message),
787
837
  guidance: {
@@ -844,20 +894,22 @@ function createMiddleware(options) {
844
894
  agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
845
895
  }
846
896
  });
847
- if (!result.verified || !hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
897
+ if (!result.identityVerified || !result.policyAllowed || !hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
848
898
  if (pathname.startsWith("/api/")) {
849
899
  return NextResponse.json(
850
900
  {
851
901
  success: false,
852
902
  error: {
853
- code: result.verified ? "INSUFFICIENT_ACCESS" : "UNAUTHORIZED",
903
+ // Round-18 G4: 401 identity missing (re-auth); 403 → identity
904
+ // OK, policy denied (update PDLSS / step up).
905
+ code: !result.identityVerified ? "UNAUTHORIZED" : "INSUFFICIENT_ACCESS",
854
906
  message: result.denialReasons?.[0] || "Access denied",
855
907
  accessLevel: result.accessLevel,
856
908
  required: routeConfig.minAccessLevel,
857
909
  guidance: result.guidance
858
910
  }
859
911
  },
860
- { status: result.verified ? 403 : 401 }
912
+ { status: !result.identityVerified ? 401 : 403 }
861
913
  );
862
914
  }
863
915
  if (showCommerceShield) {
@@ -872,7 +924,12 @@ function createMiddleware(options) {
872
924
  return NextResponse.redirect(new URL("/unauthorized", request.url));
873
925
  }
874
926
  const response = NextResponse.next();
875
- response.headers.set("X-AstraSync-Verified", result.verified.toString());
927
+ response.headers.set(
928
+ "X-AstraSync-Verified",
929
+ (result.identityVerified && result.policyAllowed).toString()
930
+ );
931
+ response.headers.set("X-AstraSync-Identity-Verified", result.identityVerified.toString());
932
+ response.headers.set("X-AstraSync-Policy-Allowed", result.policyAllowed.toString());
876
933
  response.headers.set("X-AstraSync-Access-Level", result.accessLevel);
877
934
  if (result.agent) {
878
935
  response.headers.set("X-AstraSync-Agent-Id", result.agent.astraId);