@astrasyncai/verification-gateway 3.11.1 → 4.0.0

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 (99) 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 +106 -10
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +106 -10
  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 +111 -10
  12. package/dist/adapters/mcp.js.map +1 -1
  13. package/dist/adapters/mcp.mjs +111 -10
  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 +107 -10
  18. package/dist/adapters/nextjs.js.map +1 -1
  19. package/dist/adapters/nextjs.mjs +107 -10
  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 +92 -10
  24. package/dist/adapters/sdk.js.map +1 -1
  25. package/dist/adapters/sdk.mjs +92 -10
  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/bin/astrasync-claude-hook.js +92 -10
  30. package/dist/bin/astrasync-codex-hook.js +92 -10
  31. package/dist/bin/astrasync-guard.js +92 -10
  32. package/dist/bin/astrasync.js +93 -10
  33. package/dist/browser/background.js +92 -10
  34. package/dist/browser/background.js.map +1 -1
  35. package/dist/browser/background.mjs +92 -10
  36. package/dist/browser/background.mjs.map +1 -1
  37. package/dist/browser/browser-adapter.d.mts +2 -2
  38. package/dist/browser/browser-adapter.d.ts +2 -2
  39. package/dist/claude-code/claude-code-adapter.d.mts +2 -2
  40. package/dist/claude-code/claude-code-adapter.d.ts +2 -2
  41. package/dist/cli/index.d.mts +2 -2
  42. package/dist/cli/index.d.ts +2 -2
  43. package/dist/codex/index.d.mts +2 -2
  44. package/dist/codex/index.d.ts +2 -2
  45. package/dist/codex/index.js +92 -10
  46. package/dist/codex/index.js.map +1 -1
  47. package/dist/codex/index.mjs +92 -10
  48. package/dist/codex/index.mjs.map +1 -1
  49. package/dist/cursor/cursor-adapter.d.mts +2 -2
  50. package/dist/cursor/cursor-adapter.d.ts +2 -2
  51. package/dist/cursor/extension.d.mts +2 -2
  52. package/dist/cursor/extension.d.ts +2 -2
  53. package/dist/cursor/extension.js +92 -10
  54. package/dist/cursor/extension.js.map +1 -1
  55. package/dist/cursor/extension.mjs +92 -10
  56. package/dist/cursor/extension.mjs.map +1 -1
  57. package/dist/edge-config.d.mts +1 -1
  58. package/dist/edge-config.d.ts +1 -1
  59. package/dist/{express-DCXa1oqj.d.mts → express-BZajRs4i.d.mts} +1 -1
  60. package/dist/{express-ClNtDhhc.d.ts → express-CjCUB1k7.d.ts} +1 -1
  61. package/dist/gateway/gateway.d.mts +2 -2
  62. package/dist/gateway/gateway.d.ts +2 -2
  63. package/dist/gateway/gateway.js +92 -10
  64. package/dist/gateway/gateway.js.map +1 -1
  65. package/dist/gateway/gateway.mjs +92 -10
  66. package/dist/gateway/gateway.mjs.map +1 -1
  67. package/dist/git-trigger/git-hooks.d.mts +2 -2
  68. package/dist/git-trigger/git-hooks.d.ts +2 -2
  69. package/dist/{index-BrNKDmiR.d.mts → index-B0cyMZDL.d.mts} +1 -1
  70. package/dist/{index-Dr_XiN65.d.mts → index-BRYteOqO.d.mts} +1 -1
  71. package/dist/{index-CfHurO1P.d.ts → index-BZQdVqNw.d.ts} +1 -1
  72. package/dist/{index-D2ztkumS.d.ts → index-adgKhujR.d.ts} +1 -1
  73. package/dist/index.d.mts +9 -9
  74. package/dist/index.d.ts +9 -9
  75. package/dist/index.js +160 -10
  76. package/dist/index.js.map +1 -1
  77. package/dist/index.mjs +159 -10
  78. package/dist/index.mjs.map +1 -1
  79. package/dist/local-evaluator/evaluator.d.mts +2 -2
  80. package/dist/local-evaluator/evaluator.d.ts +2 -2
  81. package/dist/{nextjs-CEBVBsdi.d.ts → nextjs-D_iFf5k-.d.ts} +1 -1
  82. package/dist/{nextjs-DcQIk6Zj.d.mts → nextjs-DeUTnOBd.d.mts} +1 -1
  83. package/dist/{sdk-H0JCLW2y.d.ts → sdk-BM3mwEAq.d.ts} +1 -1
  84. package/dist/{sdk-CZkbSOeO.d.mts → sdk-_il1Q41f.d.mts} +1 -1
  85. package/dist/transport/index.d.mts +2 -2
  86. package/dist/transport/index.d.ts +2 -2
  87. package/dist/{types-sy3tq8lp.d.mts → types-BcDf9Kk0.d.mts} +118 -1
  88. package/dist/{types-DhFPiZ3t.d.ts → types-CHKCgDFC.d.ts} +1 -1
  89. package/dist/{types-cQVCMeNV.d.mts → types-DfnP7JiM.d.mts} +1 -1
  90. package/dist/{types-9tns4wyl.d.ts → types-fTQD448H.d.ts} +118 -1
  91. package/dist/ui/index.d.mts +1 -1
  92. package/dist/ui/index.d.ts +1 -1
  93. package/dist/verify.d.mts +15 -2
  94. package/dist/verify.d.ts +15 -2
  95. package/dist/verify.js +117 -10
  96. package/dist/verify.js.map +1 -1
  97. package/dist/verify.mjs +115 -10
  98. package/dist/verify.mjs.map +1 -1
  99. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { AstraSyncGateway } from '../gateway/gateway.mjs';
2
- import { A as AgentAction, I as InterceptResult, P as PDLSSContext, V as VerificationDecision } from '../types-cQVCMeNV.mjs';
3
- import '../types-sy3tq8lp.mjs';
2
+ import { A as AgentAction, I as InterceptResult, P as PDLSSContext, V as VerificationDecision } from '../types-DfnP7JiM.mjs';
3
+ import '../types-BcDf9Kk0.mjs';
4
4
  import '../metadata-capture.mjs';
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import { AstraSyncGateway } from '../gateway/gateway.js';
2
- import { A as AgentAction, I as InterceptResult, P as PDLSSContext, V as VerificationDecision } from '../types-DhFPiZ3t.js';
3
- import '../types-9tns4wyl.js';
2
+ import { A as AgentAction, I as InterceptResult, P as PDLSSContext, V as VerificationDecision } from '../types-CHKCgDFC.js';
3
+ import '../types-fTQD448H.js';
4
4
  import '../metadata-capture.js';
5
5
 
6
6
  /**
@@ -1,4 +1,4 @@
1
1
  import 'express';
2
- import '../types-sy3tq8lp.mjs';
3
- export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-DCXa1oqj.mjs';
2
+ import '../types-BcDf9Kk0.mjs';
3
+ export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-BZajRs4i.mjs';
4
4
  import '../metadata-capture.mjs';
@@ -1,4 +1,4 @@
1
1
  import 'express';
2
- import '../types-9tns4wyl.js';
3
- export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-ClNtDhhc.js';
2
+ import '../types-fTQD448H.js';
3
+ export { c as createMiddleware, a as extractAstraSyncCredentials } from '../express-CjCUB1k7.js';
4
4
  import '../metadata-capture.js';
@@ -92,7 +92,7 @@ function getTrustLevel(score) {
92
92
  }
93
93
 
94
94
  // src/version.ts
95
- var SDK_VERSION = "3.11.1";
95
+ var SDK_VERSION = "4.0.0";
96
96
 
97
97
  // src/well-known.ts
98
98
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -170,7 +170,7 @@ var DEFAULT_CONFIG = {
170
170
  };
171
171
  var initCheckPerformed = false;
172
172
  var deprecationWarningShown = false;
173
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
173
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
174
174
  initCheckPerformed = true;
175
175
  try {
176
176
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -187,6 +187,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
187
187
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
188
188
  );
189
189
  }
190
+ if (apiKey) {
191
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
192
+ headers: { Authorization: `Bearer ${apiKey}` }
193
+ });
194
+ if (selfCheck.status === 401) {
195
+ const body = await selfCheck.json().catch(() => ({}));
196
+ const message = `[VerificationGateway] the configured AstraSync API key was REJECTED at startup (${body.code ?? "api_key_invalid"}: ${body.message ?? "invalid key"}). Every inbound agent will be turned away until the key is rotated` + (body.remediation?.manageUrl ? ` at ${body.remediation.manageUrl}` : "") + `.`;
197
+ if (strictInit) {
198
+ throw new Error(`${message} (strictInit=true)`);
199
+ }
200
+ console.error(message);
201
+ } else if (selfCheck.ok) {
202
+ const body = await selfCheck.json().catch(() => ({}));
203
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
204
+ console.warn(
205
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
206
+ );
207
+ } else if (debug) {
208
+ console.log("[VerificationGateway] API key self-check passed");
209
+ }
210
+ }
211
+ }
190
212
  } catch (err) {
191
213
  if (strictInit) {
192
214
  throw err;
@@ -298,8 +320,17 @@ function extractCredentials(headers, query) {
298
320
  function createGuidanceResponse(_config, reason, options = {}) {
299
321
  const source = options.source ?? "no_credentials";
300
322
  const isApiError = source === "api_error";
323
+ const isMisconfig = source === "merchant_misconfig";
301
324
  const urls = options.urls;
302
- const guidance = isApiError ? {
325
+ const guidance = isMisconfig ? {
326
+ message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or rotated). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
327
+ registrationUrl: urls?.registrationUrl ?? "",
328
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
329
+ steps: [
330
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
331
+ "Do not retry: the failure is deterministic until the operator updates their key"
332
+ ]
333
+ } : isApiError ? {
303
334
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
304
335
  registrationUrl: urls?.registrationUrl ?? "",
305
336
  documentationUrl: urls?.documentationUrl ?? "",
@@ -337,14 +368,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
337
368
  // partners (and their custom onDenied handlers) can branch on
338
369
  // dimension. Without this, the synthesised stub was indistinguishable
339
370
  // from a real policy deny.
340
- failures: isApiError ? [
371
+ failures: isMisconfig ? [
372
+ {
373
+ dimension: "verify_access.merchant_misconfigured",
374
+ message: reason ?? "The integration API key was rejected by AstraSync",
375
+ guidance: guidance.message
376
+ }
377
+ ] : isApiError ? [
341
378
  {
342
379
  dimension: "verify_access.api_error",
343
380
  message: reason ?? "Verification temporarily unavailable",
344
381
  guidance: guidance.message
345
382
  }
346
383
  ] : void 0,
384
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
385
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
386
+ ...isMisconfig && { misconfigured: true },
347
387
  correlationId: options.correlationId,
388
+ attemptId: options.attemptId,
348
389
  verifiedAt: /* @__PURE__ */ new Date()
349
390
  };
350
391
  }
@@ -374,6 +415,8 @@ async function callVerifyAccessAPI(config, request) {
374
415
  body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
375
416
  if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
376
417
  if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
418
+ if (requestData.attemptId) body.attemptId = requestData.attemptId;
419
+ if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
377
420
  body.sdkVersion = SDK_VERSION;
378
421
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
379
422
  const meta = {
@@ -395,12 +438,16 @@ async function callVerifyAccessAPI(config, request) {
395
438
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
396
439
  method: "POST",
397
440
  headers,
398
- body: JSON.stringify(body)
441
+ body: JSON.stringify(body),
442
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
399
443
  });
400
444
  const data = await response.json();
401
445
  if (response.status === 410) {
402
446
  return {
403
447
  success: true,
448
+ // 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
449
+ // the synthesised 410 deny shape (echoed on every branch).
450
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
404
451
  access: {
405
452
  allowed: false,
406
453
  accessLevel: "none",
@@ -416,10 +463,22 @@ async function callVerifyAccessAPI(config, request) {
416
463
  };
417
464
  }
418
465
  if (!response.ok) {
466
+ if (response.status === 401) {
467
+ return {
468
+ success: false,
469
+ error: data.message || data.error || "Integration API key rejected",
470
+ misconfig: true,
471
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
472
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
473
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
474
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
475
+ };
476
+ }
419
477
  return {
420
478
  success: false,
421
479
  error: data.message || data.error || `API returned ${response.status}`,
422
- correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
480
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
481
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
423
482
  };
424
483
  }
425
484
  return data;
@@ -436,9 +495,19 @@ async function verify(config, request, options) {
436
495
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
437
496
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
438
497
  if (mergedConfig.strictInit) {
439
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
498
+ await performInitCheck(
499
+ mergedConfig.apiBaseUrl,
500
+ mergedConfig.debug,
501
+ true,
502
+ mergedConfig.apiKey
503
+ );
440
504
  } else {
441
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
505
+ void performInitCheck(
506
+ mergedConfig.apiBaseUrl,
507
+ mergedConfig.debug,
508
+ false,
509
+ mergedConfig.apiKey
510
+ );
442
511
  }
443
512
  }
444
513
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -453,7 +522,13 @@ async function verify(config, request, options) {
453
522
  if (mergedConfig.debug) {
454
523
  console.log("[VerificationGateway] Returning cached result");
455
524
  }
456
- return cached;
525
+ const hit = { ...cached };
526
+ if (request.attemptId) {
527
+ hit.attemptId = request.attemptId;
528
+ } else {
529
+ delete hit.attemptId;
530
+ }
531
+ return hit;
457
532
  }
458
533
  }
459
534
  const enrichedRequest = { ...request };
@@ -471,8 +546,10 @@ async function verify(config, request, options) {
471
546
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
472
547
  if (!apiResponse.success) {
473
548
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
474
- source: "api_error",
549
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
475
550
  correlationId: apiResponse.correlationId,
551
+ attemptId: apiResponse.attemptId,
552
+ remediation: apiResponse.remediation,
476
553
  urls
477
554
  });
478
555
  }
@@ -508,6 +585,9 @@ async function verify(config, request, options) {
508
585
  // Anonymous traffic has no session → correlationId is the per-attempt
509
586
  // linking key (the sessionId-equivalent for anonymous callers).
510
587
  correlationId: apiResponse.correlationId,
588
+ // 3.12.0 (Trust Record): server echoes the attempt-chain handle on
589
+ // every branch — denials included (the funnel outlives one deny).
590
+ attemptId: apiResponse.attemptId,
511
591
  recommendation: apiResponse.recommendation,
512
592
  recommendationReasons: apiResponse.recommendationReasons,
513
593
  stepUpApproval: apiResponse.stepUpApproval,
@@ -559,6 +639,8 @@ async function verify(config, request, options) {
559
639
  // v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
560
640
  // (no session row exists for unverified callers).
561
641
  correlationId: apiResponse.correlationId,
642
+ // 3.12.0 (Trust Record): server-echoed attempt-chain handle.
643
+ attemptId: apiResponse.attemptId,
562
644
  runtimeChallenge: apiResponse.runtimeChallenge,
563
645
  tokenGuidance: apiResponse.tokenGuidance,
564
646
  recommendation: apiResponse.recommendation,
@@ -1024,6 +1106,20 @@ function dedupeFailures(result) {
1024
1106
  }
1025
1107
  }
1026
1108
  function defaultOnDenied(result, _req, res) {
1109
+ if (result.misconfigured) {
1110
+ res.setHeader("X-Astra-Gateway-Mode", "enforced");
1111
+ res.status(503).json({
1112
+ success: false,
1113
+ error: {
1114
+ code: "MERCHANT_VERIFICATION_MISCONFIGURED",
1115
+ message: result.denialReasons?.[0] || "This site's AstraSync integration is misconfigured",
1116
+ guidance: result.guidance,
1117
+ failures: result.failures,
1118
+ correlationId: result.correlationId
1119
+ }
1120
+ });
1121
+ return;
1122
+ }
1027
1123
  const statusCode = !result.identityVerified ? 401 : 403;
1028
1124
  res.setHeader("X-Astra-Gateway-Mode", "enforced");
1029
1125
  res.status(statusCode).json({