@astrasyncai/verification-gateway 3.12.0 → 4.1.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 (134) hide show
  1. package/README.md +106 -29
  2. package/dist/adapter-interface/interface.d.mts +2 -2
  3. package/dist/adapter-interface/interface.d.ts +2 -2
  4. package/dist/adapters/express.d.mts +2 -2
  5. package/dist/adapters/express.d.ts +2 -2
  6. package/dist/adapters/express.js +482 -22
  7. package/dist/adapters/express.js.map +1 -1
  8. package/dist/adapters/express.mjs +482 -22
  9. package/dist/adapters/express.mjs.map +1 -1
  10. package/dist/adapters/http-pdlss.d.mts +3 -3
  11. package/dist/adapters/http-pdlss.d.ts +3 -3
  12. package/dist/adapters/http-pdlss.js.map +1 -1
  13. package/dist/adapters/http-pdlss.mjs.map +1 -1
  14. package/dist/adapters/mcp.d.mts +56 -36
  15. package/dist/adapters/mcp.d.ts +56 -36
  16. package/dist/adapters/mcp.js +309 -10
  17. package/dist/adapters/mcp.js.map +1 -1
  18. package/dist/adapters/mcp.mjs +309 -10
  19. package/dist/adapters/mcp.mjs.map +1 -1
  20. package/dist/adapters/nextjs.d.mts +2 -2
  21. package/dist/adapters/nextjs.d.ts +2 -2
  22. package/dist/adapters/nextjs.js +518 -25
  23. package/dist/adapters/nextjs.js.map +1 -1
  24. package/dist/adapters/nextjs.mjs +518 -25
  25. package/dist/adapters/nextjs.mjs.map +1 -1
  26. package/dist/adapters/sdk.d.mts +2 -2
  27. package/dist/adapters/sdk.d.ts +2 -2
  28. package/dist/adapters/sdk.js +72 -9
  29. package/dist/adapters/sdk.js.map +1 -1
  30. package/dist/adapters/sdk.mjs +72 -9
  31. package/dist/adapters/sdk.mjs.map +1 -1
  32. package/dist/agent/index.d.mts +2 -2
  33. package/dist/agent/index.d.ts +2 -2
  34. package/dist/agent/index.js.map +1 -1
  35. package/dist/agent/index.mjs.map +1 -1
  36. package/dist/bin/astrasync-claude-hook.js +83 -20
  37. package/dist/bin/astrasync-codex-hook.js +83 -20
  38. package/dist/bin/astrasync-guard.js +83 -20
  39. package/dist/bin/astrasync.js +150 -33
  40. package/dist/browser/background.js +83 -20
  41. package/dist/browser/background.js.map +1 -1
  42. package/dist/browser/background.mjs +83 -20
  43. package/dist/browser/background.mjs.map +1 -1
  44. package/dist/browser/browser-adapter.d.mts +2 -2
  45. package/dist/browser/browser-adapter.d.ts +2 -2
  46. package/dist/claude-code/claude-code-adapter.d.mts +2 -2
  47. package/dist/claude-code/claude-code-adapter.d.ts +2 -2
  48. package/dist/cli/index.d.mts +2 -2
  49. package/dist/cli/index.d.ts +2 -2
  50. package/dist/codex/index.d.mts +3 -3
  51. package/dist/codex/index.d.ts +3 -3
  52. package/dist/codex/index.js +83 -20
  53. package/dist/codex/index.js.map +1 -1
  54. package/dist/codex/index.mjs +83 -20
  55. package/dist/codex/index.mjs.map +1 -1
  56. package/dist/cursor/cursor-adapter.d.mts +2 -2
  57. package/dist/cursor/cursor-adapter.d.ts +2 -2
  58. package/dist/cursor/extension.d.mts +2 -2
  59. package/dist/cursor/extension.d.ts +2 -2
  60. package/dist/cursor/extension.js +83 -20
  61. package/dist/cursor/extension.js.map +1 -1
  62. package/dist/cursor/extension.mjs +83 -20
  63. package/dist/cursor/extension.mjs.map +1 -1
  64. package/dist/edge-config.d.mts +22 -7
  65. package/dist/edge-config.d.ts +22 -7
  66. package/dist/edge-config.js.map +1 -1
  67. package/dist/edge-config.mjs.map +1 -1
  68. package/dist/edge-core/index.d.mts +425 -0
  69. package/dist/edge-core/index.d.ts +425 -0
  70. package/dist/edge-core/index.js +1482 -0
  71. package/dist/edge-core/index.js.map +1 -0
  72. package/dist/edge-core/index.mjs +1437 -0
  73. package/dist/edge-core/index.mjs.map +1 -0
  74. package/dist/{express-B39o89gf.d.mts → express-BVd1_3FE.d.ts} +9 -7
  75. package/dist/{express-BuxKNO_q.d.ts → express-D_4hTn5Z.d.mts} +9 -7
  76. package/dist/gateway/gateway.d.mts +2 -2
  77. package/dist/gateway/gateway.d.ts +2 -2
  78. package/dist/gateway/gateway.js +83 -20
  79. package/dist/gateway/gateway.js.map +1 -1
  80. package/dist/gateway/gateway.mjs +83 -20
  81. package/dist/gateway/gateway.mjs.map +1 -1
  82. package/dist/git-trigger/git-hooks.d.mts +2 -2
  83. package/dist/git-trigger/git-hooks.d.ts +2 -2
  84. package/dist/{index-CLHdqs2M.d.ts → index-B0YHu_SP.d.ts} +30 -27
  85. package/dist/{index-DME3w3lf.d.mts → index-BPEBlOsE.d.mts} +30 -27
  86. package/dist/{index-CqydB4ks.d.mts → index-DQb5-_1X.d.mts} +1 -1
  87. package/dist/{index-BG62SXso.d.ts → index-T1aBoUcc.d.ts} +1 -1
  88. package/dist/index.d.mts +11 -11
  89. package/dist/index.d.ts +11 -11
  90. package/dist/index.js +595 -272
  91. package/dist/index.js.map +1 -1
  92. package/dist/index.mjs +592 -272
  93. package/dist/index.mjs.map +1 -1
  94. package/dist/local-evaluator/evaluator.d.mts +2 -2
  95. package/dist/local-evaluator/evaluator.d.ts +2 -2
  96. package/dist/metadata-capture.d.mts +63 -4
  97. package/dist/metadata-capture.d.ts +63 -4
  98. package/dist/metadata-capture.js +67 -0
  99. package/dist/metadata-capture.js.map +1 -1
  100. package/dist/metadata-capture.mjs +64 -0
  101. package/dist/metadata-capture.mjs.map +1 -1
  102. package/dist/{nextjs-D74W7wt-.d.mts → nextjs-WyeVr2Kp.d.mts} +3 -3
  103. package/dist/{nextjs-Ddlw_J1J.d.ts → nextjs-w7RTbP1P.d.ts} +3 -3
  104. package/dist/platform-signatures.d.mts +5 -6
  105. package/dist/platform-signatures.d.ts +5 -6
  106. package/dist/platform-signatures.js.map +1 -1
  107. package/dist/platform-signatures.mjs.map +1 -1
  108. package/dist/registration/index.d.mts +10 -11
  109. package/dist/registration/index.d.ts +10 -11
  110. package/dist/registration/index.js.map +1 -1
  111. package/dist/registration/index.mjs.map +1 -1
  112. package/dist/{sdk-CT7gdkfR.d.ts → sdk-CbTNIkAa.d.mts} +4 -4
  113. package/dist/{sdk-Bn6bj7kt.d.mts → sdk-QeX0Z8Ho.d.ts} +4 -4
  114. package/dist/transport/index.d.mts +2 -2
  115. package/dist/transport/index.d.ts +2 -2
  116. package/dist/transport/index.js.map +1 -1
  117. package/dist/transport/index.mjs.map +1 -1
  118. package/dist/{types-DHu7m9HI.d.ts → types-BLUx92FJ.d.ts} +1 -1
  119. package/dist/{types-Djw4GLtz.d.mts → types-DqfPU5Bl.d.mts} +1 -1
  120. package/dist/{types-BntuzEEn.d.mts → types-r850cOt0.d.mts} +121 -88
  121. package/dist/{types-SDu4Llbe.d.ts → types-sMxBT-nM.d.ts} +121 -88
  122. package/dist/ui/index.d.mts +11 -7
  123. package/dist/ui/index.d.ts +11 -7
  124. package/dist/ui/index.js +13 -9
  125. package/dist/ui/index.js.map +1 -1
  126. package/dist/ui/index.mjs +10 -8
  127. package/dist/ui/index.mjs.map +1 -1
  128. package/dist/verify.d.mts +11 -8
  129. package/dist/verify.d.ts +11 -8
  130. package/dist/verify.js +76 -8
  131. package/dist/verify.js.map +1 -1
  132. package/dist/verify.mjs +75 -8
  133. package/dist/verify.mjs.map +1 -1
  134. package/package.json +8 -2
@@ -3701,7 +3701,7 @@ function getTrustLevel(score) {
3701
3701
  }
3702
3702
 
3703
3703
  // src/version.ts
3704
- var SDK_VERSION = "3.12.0";
3704
+ var SDK_VERSION = "4.1.0";
3705
3705
 
3706
3706
  // src/well-known.ts
3707
3707
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -3727,7 +3727,7 @@ var DEFAULT_CONFIG = {
3727
3727
  };
3728
3728
  var initCheckPerformed = false;
3729
3729
  var deprecationWarningShown = false;
3730
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
3730
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
3731
3731
  initCheckPerformed = true;
3732
3732
  try {
3733
3733
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -3744,6 +3744,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
3744
3744
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
3745
3745
  );
3746
3746
  }
3747
+ if (apiKey) {
3748
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
3749
+ headers: { Authorization: `Bearer ${apiKey}` }
3750
+ });
3751
+ if (selfCheck.status === 401) {
3752
+ const body = await selfCheck.json().catch(() => ({}));
3753
+ 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}` : "") + `.`;
3754
+ if (strictInit) {
3755
+ throw new Error(`${message} (strictInit=true)`);
3756
+ }
3757
+ console.error(message);
3758
+ } else if (selfCheck.ok) {
3759
+ const body = await selfCheck.json().catch(() => ({}));
3760
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
3761
+ console.warn(
3762
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
3763
+ );
3764
+ } else if (debug) {
3765
+ console.log("[VerificationGateway] API key self-check passed");
3766
+ }
3767
+ }
3768
+ }
3747
3769
  } catch (err) {
3748
3770
  if (strictInit) {
3749
3771
  throw err;
@@ -3821,8 +3843,17 @@ function cacheResult(request, result, configuredTtl, counterpartyId) {
3821
3843
  function createGuidanceResponse(_config, reason, options = {}) {
3822
3844
  const source = options.source ?? "no_credentials";
3823
3845
  const isApiError = source === "api_error";
3846
+ const isMisconfig = source === "merchant_misconfig";
3824
3847
  const urls = options.urls;
3825
- const guidance = isApiError ? {
3848
+ const guidance = isMisconfig ? {
3849
+ 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.",
3850
+ registrationUrl: urls?.registrationUrl ?? "",
3851
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
3852
+ steps: [
3853
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
3854
+ "Do not retry: the failure is deterministic until the operator updates their key"
3855
+ ]
3856
+ } : isApiError ? {
3826
3857
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
3827
3858
  registrationUrl: urls?.registrationUrl ?? "",
3828
3859
  documentationUrl: urls?.documentationUrl ?? "",
@@ -3860,13 +3891,22 @@ function createGuidanceResponse(_config, reason, options = {}) {
3860
3891
  // partners (and their custom onDenied handlers) can branch on
3861
3892
  // dimension. Without this, the synthesised stub was indistinguishable
3862
3893
  // from a real policy deny.
3863
- failures: isApiError ? [
3894
+ failures: isMisconfig ? [
3895
+ {
3896
+ dimension: "verify_access.merchant_misconfigured",
3897
+ message: reason ?? "The integration API key was rejected by AstraSync",
3898
+ guidance: guidance.message
3899
+ }
3900
+ ] : isApiError ? [
3864
3901
  {
3865
3902
  dimension: "verify_access.api_error",
3866
3903
  message: reason ?? "Verification temporarily unavailable",
3867
3904
  guidance: guidance.message
3868
3905
  }
3869
3906
  ] : void 0,
3907
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
3908
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
3909
+ ...isMisconfig && { misconfigured: true },
3870
3910
  correlationId: options.correlationId,
3871
3911
  attemptId: options.attemptId,
3872
3912
  verifiedAt: /* @__PURE__ */ new Date()
@@ -3921,7 +3961,8 @@ async function callVerifyAccessAPI(config, request) {
3921
3961
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
3922
3962
  method: "POST",
3923
3963
  headers,
3924
- body: JSON.stringify(body)
3964
+ body: JSON.stringify(body),
3965
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
3925
3966
  });
3926
3967
  const data = await response.json();
3927
3968
  if (response.status === 410) {
@@ -3945,6 +3986,17 @@ async function callVerifyAccessAPI(config, request) {
3945
3986
  };
3946
3987
  }
3947
3988
  if (!response.ok) {
3989
+ if (response.status === 401) {
3990
+ return {
3991
+ success: false,
3992
+ error: data.message || data.error || "Integration API key rejected",
3993
+ misconfig: true,
3994
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
3995
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
3996
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
3997
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
3998
+ };
3999
+ }
3948
4000
  return {
3949
4001
  success: false,
3950
4002
  error: data.message || data.error || `API returned ${response.status}`,
@@ -3966,9 +4018,19 @@ async function verify(config, request, options) {
3966
4018
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
3967
4019
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
3968
4020
  if (mergedConfig.strictInit) {
3969
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
4021
+ await performInitCheck(
4022
+ mergedConfig.apiBaseUrl,
4023
+ mergedConfig.debug,
4024
+ true,
4025
+ mergedConfig.apiKey
4026
+ );
3970
4027
  } else {
3971
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
4028
+ void performInitCheck(
4029
+ mergedConfig.apiBaseUrl,
4030
+ mergedConfig.debug,
4031
+ false,
4032
+ mergedConfig.apiKey
4033
+ );
3972
4034
  }
3973
4035
  }
3974
4036
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -4007,9 +4069,10 @@ async function verify(config, request, options) {
4007
4069
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
4008
4070
  if (!apiResponse.success) {
4009
4071
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
4010
- source: "api_error",
4072
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
4011
4073
  correlationId: apiResponse.correlationId,
4012
4074
  attemptId: apiResponse.attemptId,
4075
+ remediation: apiResponse.remediation,
4013
4076
  urls
4014
4077
  });
4015
4078
  }
@@ -4139,6 +4202,18 @@ var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
4139
4202
  // src/metadata-capture.ts
4140
4203
  var MAX_TOTAL_BYTES = 16 * 1024;
4141
4204
 
4205
+ // src/edge-config.ts
4206
+ var DEFAULT_EDGE_CONFIG = Object.freeze({
4207
+ version: 1,
4208
+ mode: "observe",
4209
+ depth: "classify",
4210
+ pathRules: [],
4211
+ sampling: Object.freeze({ anonymousBeaconRate: 0.1 }),
4212
+ failurePosture: "open"
4213
+ });
4214
+ var DEFAULT_TTL_MS = 60 * 1e3;
4215
+ var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
4216
+
4142
4217
  // src/adapters/express.ts
4143
4218
  var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
4144
4219
 
@@ -4207,18 +4282,6 @@ var import_node_crypto4 = require("crypto");
4207
4282
  // src/transport/registry/visa.ts
4208
4283
  var import_jose = require("jose");
4209
4284
 
4210
- // src/edge-config.ts
4211
- var DEFAULT_EDGE_CONFIG = Object.freeze({
4212
- version: 1,
4213
- mode: "observe",
4214
- depth: "classify",
4215
- pathRules: [],
4216
- sampling: Object.freeze({ anonymousBeaconRate: 0.1 }),
4217
- failurePosture: "open"
4218
- });
4219
- var DEFAULT_TTL_MS = 60 * 1e3;
4220
- var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
4221
-
4222
4285
  // src/gateway/modes/online.ts
4223
4286
  function toGatewayConfig(config) {
4224
4287
  return {
@@ -3700,7 +3700,7 @@ function getTrustLevel(score) {
3700
3700
  }
3701
3701
 
3702
3702
  // src/version.ts
3703
- var SDK_VERSION = "3.12.0";
3703
+ var SDK_VERSION = "4.1.0";
3704
3704
 
3705
3705
  // src/well-known.ts
3706
3706
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -3726,7 +3726,7 @@ var DEFAULT_CONFIG = {
3726
3726
  };
3727
3727
  var initCheckPerformed = false;
3728
3728
  var deprecationWarningShown = false;
3729
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
3729
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
3730
3730
  initCheckPerformed = true;
3731
3731
  try {
3732
3732
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -3743,6 +3743,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
3743
3743
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
3744
3744
  );
3745
3745
  }
3746
+ if (apiKey) {
3747
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
3748
+ headers: { Authorization: `Bearer ${apiKey}` }
3749
+ });
3750
+ if (selfCheck.status === 401) {
3751
+ const body = await selfCheck.json().catch(() => ({}));
3752
+ 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}` : "") + `.`;
3753
+ if (strictInit) {
3754
+ throw new Error(`${message} (strictInit=true)`);
3755
+ }
3756
+ console.error(message);
3757
+ } else if (selfCheck.ok) {
3758
+ const body = await selfCheck.json().catch(() => ({}));
3759
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
3760
+ console.warn(
3761
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
3762
+ );
3763
+ } else if (debug) {
3764
+ console.log("[VerificationGateway] API key self-check passed");
3765
+ }
3766
+ }
3767
+ }
3746
3768
  } catch (err) {
3747
3769
  if (strictInit) {
3748
3770
  throw err;
@@ -3820,8 +3842,17 @@ function cacheResult(request, result, configuredTtl, counterpartyId) {
3820
3842
  function createGuidanceResponse(_config, reason, options = {}) {
3821
3843
  const source = options.source ?? "no_credentials";
3822
3844
  const isApiError = source === "api_error";
3845
+ const isMisconfig = source === "merchant_misconfig";
3823
3846
  const urls = options.urls;
3824
- const guidance = isApiError ? {
3847
+ const guidance = isMisconfig ? {
3848
+ 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.",
3849
+ registrationUrl: urls?.registrationUrl ?? "",
3850
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
3851
+ steps: [
3852
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
3853
+ "Do not retry: the failure is deterministic until the operator updates their key"
3854
+ ]
3855
+ } : isApiError ? {
3825
3856
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
3826
3857
  registrationUrl: urls?.registrationUrl ?? "",
3827
3858
  documentationUrl: urls?.documentationUrl ?? "",
@@ -3859,13 +3890,22 @@ function createGuidanceResponse(_config, reason, options = {}) {
3859
3890
  // partners (and their custom onDenied handlers) can branch on
3860
3891
  // dimension. Without this, the synthesised stub was indistinguishable
3861
3892
  // from a real policy deny.
3862
- failures: isApiError ? [
3893
+ failures: isMisconfig ? [
3894
+ {
3895
+ dimension: "verify_access.merchant_misconfigured",
3896
+ message: reason ?? "The integration API key was rejected by AstraSync",
3897
+ guidance: guidance.message
3898
+ }
3899
+ ] : isApiError ? [
3863
3900
  {
3864
3901
  dimension: "verify_access.api_error",
3865
3902
  message: reason ?? "Verification temporarily unavailable",
3866
3903
  guidance: guidance.message
3867
3904
  }
3868
3905
  ] : void 0,
3906
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
3907
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
3908
+ ...isMisconfig && { misconfigured: true },
3869
3909
  correlationId: options.correlationId,
3870
3910
  attemptId: options.attemptId,
3871
3911
  verifiedAt: /* @__PURE__ */ new Date()
@@ -3920,7 +3960,8 @@ async function callVerifyAccessAPI(config, request) {
3920
3960
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
3921
3961
  method: "POST",
3922
3962
  headers,
3923
- body: JSON.stringify(body)
3963
+ body: JSON.stringify(body),
3964
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
3924
3965
  });
3925
3966
  const data = await response.json();
3926
3967
  if (response.status === 410) {
@@ -3944,6 +3985,17 @@ async function callVerifyAccessAPI(config, request) {
3944
3985
  };
3945
3986
  }
3946
3987
  if (!response.ok) {
3988
+ if (response.status === 401) {
3989
+ return {
3990
+ success: false,
3991
+ error: data.message || data.error || "Integration API key rejected",
3992
+ misconfig: true,
3993
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
3994
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
3995
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
3996
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
3997
+ };
3998
+ }
3947
3999
  return {
3948
4000
  success: false,
3949
4001
  error: data.message || data.error || `API returned ${response.status}`,
@@ -3965,9 +4017,19 @@ async function verify(config, request, options) {
3965
4017
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
3966
4018
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
3967
4019
  if (mergedConfig.strictInit) {
3968
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
4020
+ await performInitCheck(
4021
+ mergedConfig.apiBaseUrl,
4022
+ mergedConfig.debug,
4023
+ true,
4024
+ mergedConfig.apiKey
4025
+ );
3969
4026
  } else {
3970
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
4027
+ void performInitCheck(
4028
+ mergedConfig.apiBaseUrl,
4029
+ mergedConfig.debug,
4030
+ false,
4031
+ mergedConfig.apiKey
4032
+ );
3971
4033
  }
3972
4034
  }
3973
4035
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -4006,9 +4068,10 @@ async function verify(config, request, options) {
4006
4068
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
4007
4069
  if (!apiResponse.success) {
4008
4070
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
4009
- source: "api_error",
4071
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
4010
4072
  correlationId: apiResponse.correlationId,
4011
4073
  attemptId: apiResponse.attemptId,
4074
+ remediation: apiResponse.remediation,
4012
4075
  urls
4013
4076
  });
4014
4077
  }
@@ -4138,6 +4201,18 @@ var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
4138
4201
  // src/metadata-capture.ts
4139
4202
  var MAX_TOTAL_BYTES = 16 * 1024;
4140
4203
 
4204
+ // src/edge-config.ts
4205
+ var DEFAULT_EDGE_CONFIG = Object.freeze({
4206
+ version: 1,
4207
+ mode: "observe",
4208
+ depth: "classify",
4209
+ pathRules: [],
4210
+ sampling: Object.freeze({ anonymousBeaconRate: 0.1 }),
4211
+ failurePosture: "open"
4212
+ });
4213
+ var DEFAULT_TTL_MS = 60 * 1e3;
4214
+ var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
4215
+
4141
4216
  // src/adapters/express.ts
4142
4217
  var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
4143
4218
 
@@ -4206,18 +4281,6 @@ var import_node_crypto4 = require("crypto");
4206
4281
  // src/transport/registry/visa.ts
4207
4282
  var import_jose = require("jose");
4208
4283
 
4209
- // src/edge-config.ts
4210
- var DEFAULT_EDGE_CONFIG = Object.freeze({
4211
- version: 1,
4212
- mode: "observe",
4213
- depth: "classify",
4214
- pathRules: [],
4215
- sampling: Object.freeze({ anonymousBeaconRate: 0.1 }),
4216
- failurePosture: "open"
4217
- });
4218
- var DEFAULT_TTL_MS = 60 * 1e3;
4219
- var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
4220
-
4221
4284
  // src/gateway/modes/online.ts
4222
4285
  function toGatewayConfig(config) {
4223
4286
  return {
@@ -4609,7 +4609,7 @@ function getTrustLevel(score) {
4609
4609
  }
4610
4610
 
4611
4611
  // src/version.ts
4612
- var SDK_VERSION = "3.12.0";
4612
+ var SDK_VERSION = "4.1.0";
4613
4613
 
4614
4614
  // src/well-known.ts
4615
4615
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -4635,7 +4635,7 @@ var DEFAULT_CONFIG = {
4635
4635
  };
4636
4636
  var initCheckPerformed = false;
4637
4637
  var deprecationWarningShown = false;
4638
- async function performInitCheck(apiBaseUrl, debug, strictInit) {
4638
+ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
4639
4639
  initCheckPerformed = true;
4640
4640
  try {
4641
4641
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
@@ -4652,6 +4652,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
4652
4652
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
4653
4653
  );
4654
4654
  }
4655
+ if (apiKey) {
4656
+ const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
4657
+ headers: { Authorization: `Bearer ${apiKey}` }
4658
+ });
4659
+ if (selfCheck.status === 401) {
4660
+ const body = await selfCheck.json().catch(() => ({}));
4661
+ 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}` : "") + `.`;
4662
+ if (strictInit) {
4663
+ throw new Error(`${message} (strictInit=true)`);
4664
+ }
4665
+ console.error(message);
4666
+ } else if (selfCheck.ok) {
4667
+ const body = await selfCheck.json().catch(() => ({}));
4668
+ if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
4669
+ console.warn(
4670
+ `[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
4671
+ );
4672
+ } else if (debug) {
4673
+ console.log("[VerificationGateway] API key self-check passed");
4674
+ }
4675
+ }
4676
+ }
4655
4677
  } catch (err) {
4656
4678
  if (strictInit) {
4657
4679
  throw err;
@@ -4729,8 +4751,17 @@ function cacheResult(request2, result, configuredTtl, counterpartyId) {
4729
4751
  function createGuidanceResponse(_config, reason, options = {}) {
4730
4752
  const source = options.source ?? "no_credentials";
4731
4753
  const isApiError = source === "api_error";
4754
+ const isMisconfig = source === "merchant_misconfig";
4732
4755
  const urls = options.urls;
4733
- const guidance = isApiError ? {
4756
+ const guidance = isMisconfig ? {
4757
+ 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.",
4758
+ registrationUrl: urls?.registrationUrl ?? "",
4759
+ documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
4760
+ steps: [
4761
+ "Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
4762
+ "Do not retry: the failure is deterministic until the operator updates their key"
4763
+ ]
4764
+ } : isApiError ? {
4734
4765
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
4735
4766
  registrationUrl: urls?.registrationUrl ?? "",
4736
4767
  documentationUrl: urls?.documentationUrl ?? "",
@@ -4768,13 +4799,22 @@ function createGuidanceResponse(_config, reason, options = {}) {
4768
4799
  // partners (and their custom onDenied handlers) can branch on
4769
4800
  // dimension. Without this, the synthesised stub was indistinguishable
4770
4801
  // from a real policy deny.
4771
- failures: isApiError ? [
4802
+ failures: isMisconfig ? [
4803
+ {
4804
+ dimension: "verify_access.merchant_misconfigured",
4805
+ message: reason ?? "The integration API key was rejected by AstraSync",
4806
+ guidance: guidance.message
4807
+ }
4808
+ ] : isApiError ? [
4772
4809
  {
4773
4810
  dimension: "verify_access.api_error",
4774
4811
  message: reason ?? "Verification temporarily unavailable",
4775
4812
  guidance: guidance.message
4776
4813
  }
4777
4814
  ] : void 0,
4815
+ // 4.0.0: typed marker so adapters render the misconfig envelope (503 +
4816
+ // MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
4817
+ ...isMisconfig && { misconfigured: true },
4778
4818
  correlationId: options.correlationId,
4779
4819
  attemptId: options.attemptId,
4780
4820
  verifiedAt: /* @__PURE__ */ new Date()
@@ -4829,7 +4869,8 @@ async function callVerifyAccessAPI(config, request2) {
4829
4869
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
4830
4870
  method: "POST",
4831
4871
  headers,
4832
- body: JSON.stringify(body)
4872
+ body: JSON.stringify(body),
4873
+ signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
4833
4874
  });
4834
4875
  const data = await response.json();
4835
4876
  if (response.status === 410) {
@@ -4853,6 +4894,17 @@ async function callVerifyAccessAPI(config, request2) {
4853
4894
  };
4854
4895
  }
4855
4896
  if (!response.ok) {
4897
+ if (response.status === 401) {
4898
+ return {
4899
+ success: false,
4900
+ error: data.message || data.error || "Integration API key rejected",
4901
+ misconfig: true,
4902
+ misconfigCode: typeof data?.code === "string" ? data.code : void 0,
4903
+ remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
4904
+ correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
4905
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
4906
+ };
4907
+ }
4856
4908
  return {
4857
4909
  success: false,
4858
4910
  error: data.message || data.error || `API returned ${response.status}`,
@@ -4874,9 +4926,19 @@ async function verify(config, request2, options) {
4874
4926
  const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
4875
4927
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
4876
4928
  if (mergedConfig.strictInit) {
4877
- await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
4929
+ await performInitCheck(
4930
+ mergedConfig.apiBaseUrl,
4931
+ mergedConfig.debug,
4932
+ true,
4933
+ mergedConfig.apiKey
4934
+ );
4878
4935
  } else {
4879
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
4936
+ void performInitCheck(
4937
+ mergedConfig.apiBaseUrl,
4938
+ mergedConfig.debug,
4939
+ false,
4940
+ mergedConfig.apiKey
4941
+ );
4880
4942
  }
4881
4943
  }
4882
4944
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
@@ -4915,9 +4977,10 @@ async function verify(config, request2, options) {
4915
4977
  const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
4916
4978
  if (!apiResponse.success) {
4917
4979
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
4918
- source: "api_error",
4980
+ source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
4919
4981
  correlationId: apiResponse.correlationId,
4920
4982
  attemptId: apiResponse.attemptId,
4983
+ remediation: apiResponse.remediation,
4921
4984
  urls
4922
4985
  });
4923
4986
  }
@@ -5047,6 +5110,18 @@ var FALLBACK_MAX_WAIT_MS = 5 * 60 * 1e3;
5047
5110
  // src/metadata-capture.ts
5048
5111
  var MAX_TOTAL_BYTES = 16 * 1024;
5049
5112
 
5113
+ // src/edge-config.ts
5114
+ var DEFAULT_EDGE_CONFIG = Object.freeze({
5115
+ version: 1,
5116
+ mode: "observe",
5117
+ depth: "classify",
5118
+ pathRules: [],
5119
+ sampling: Object.freeze({ anonymousBeaconRate: 0.1 }),
5120
+ failurePosture: "open"
5121
+ });
5122
+ var DEFAULT_TTL_MS = 60 * 1e3;
5123
+ var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
5124
+
5050
5125
  // src/adapters/express.ts
5051
5126
  var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
5052
5127
 
@@ -5115,18 +5190,6 @@ var import_node_crypto4 = require("crypto");
5115
5190
  // src/transport/registry/visa.ts
5116
5191
  var import_jose = require("jose");
5117
5192
 
5118
- // src/edge-config.ts
5119
- var DEFAULT_EDGE_CONFIG = Object.freeze({
5120
- version: 1,
5121
- mode: "observe",
5122
- depth: "classify",
5123
- pathRules: [],
5124
- sampling: Object.freeze({ anonymousBeaconRate: 0.1 }),
5125
- failurePosture: "open"
5126
- });
5127
- var DEFAULT_TTL_MS = 60 * 1e3;
5128
- var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
5129
-
5130
5193
  // src/gateway/modes/online.ts
5131
5194
  function toGatewayConfig(config) {
5132
5195
  return {