@astrasyncai/verification-gateway 4.2.0 → 4.3.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 (112) hide show
  1. package/README.md +45 -21
  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 +56 -4
  7. package/dist/adapters/express.js.map +1 -1
  8. package/dist/adapters/express.mjs +56 -4
  9. package/dist/adapters/express.mjs.map +1 -1
  10. package/dist/adapters/mcp.d.mts +38 -30
  11. package/dist/adapters/mcp.d.ts +38 -30
  12. package/dist/adapters/mcp.js +22 -5
  13. package/dist/adapters/mcp.js.map +1 -1
  14. package/dist/adapters/mcp.mjs +22 -5
  15. package/dist/adapters/mcp.mjs.map +1 -1
  16. package/dist/adapters/nextjs.d.mts +2 -2
  17. package/dist/adapters/nextjs.d.ts +2 -2
  18. package/dist/adapters/nextjs.js +54 -4
  19. package/dist/adapters/nextjs.js.map +1 -1
  20. package/dist/adapters/nextjs.mjs +54 -4
  21. package/dist/adapters/nextjs.mjs.map +1 -1
  22. package/dist/adapters/sdk.d.mts +2 -2
  23. package/dist/adapters/sdk.d.ts +2 -2
  24. package/dist/agent/index.d.mts +2 -2
  25. package/dist/agent/index.d.ts +2 -2
  26. package/dist/agent/index.js +2 -2
  27. package/dist/agent/index.js.map +1 -1
  28. package/dist/agent/index.mjs +2 -2
  29. package/dist/agent/index.mjs.map +1 -1
  30. package/dist/bin/astrasync-claude-hook.js +2 -2
  31. package/dist/bin/astrasync-codex-hook.js +2 -2
  32. package/dist/bin/astrasync-guard.js +2 -2
  33. package/dist/bin/astrasync.js +14 -4
  34. package/dist/browser/background.js +2 -2
  35. package/dist/browser/background.js.map +1 -1
  36. package/dist/browser/background.mjs +2 -2
  37. package/dist/browser/background.mjs.map +1 -1
  38. package/dist/browser/browser-adapter.d.mts +2 -2
  39. package/dist/browser/browser-adapter.d.ts +2 -2
  40. package/dist/claude-code/claude-code-adapter.d.mts +2 -2
  41. package/dist/claude-code/claude-code-adapter.d.ts +2 -2
  42. package/dist/cli/index.d.mts +2 -2
  43. package/dist/cli/index.d.ts +2 -2
  44. package/dist/codex/index.d.mts +2 -2
  45. package/dist/codex/index.d.ts +2 -2
  46. package/dist/codex/index.js +2 -2
  47. package/dist/codex/index.js.map +1 -1
  48. package/dist/codex/index.mjs +2 -2
  49. package/dist/codex/index.mjs.map +1 -1
  50. package/dist/cursor/cursor-adapter.d.mts +2 -2
  51. package/dist/cursor/cursor-adapter.d.ts +2 -2
  52. package/dist/cursor/extension.d.mts +2 -2
  53. package/dist/cursor/extension.d.ts +2 -2
  54. package/dist/cursor/extension.js +2 -2
  55. package/dist/cursor/extension.js.map +1 -1
  56. package/dist/cursor/extension.mjs +2 -2
  57. package/dist/cursor/extension.mjs.map +1 -1
  58. package/dist/edge-config.d.mts +1 -1
  59. package/dist/edge-config.d.ts +1 -1
  60. package/dist/edge-core/index.d.mts +1 -1
  61. package/dist/edge-core/index.d.ts +1 -1
  62. package/dist/edge-core/index.js +25 -5
  63. package/dist/edge-core/index.js.map +1 -1
  64. package/dist/edge-core/index.mjs +25 -5
  65. package/dist/edge-core/index.mjs.map +1 -1
  66. package/dist/{express-D_4hTn5Z.d.mts → express-CR6F3njD.d.mts} +1 -1
  67. package/dist/{express-BVd1_3FE.d.ts → express-DaqL11tx.d.ts} +1 -1
  68. package/dist/gateway/gateway.d.mts +2 -2
  69. package/dist/gateway/gateway.d.ts +2 -2
  70. package/dist/gateway/gateway.js +2 -2
  71. package/dist/gateway/gateway.js.map +1 -1
  72. package/dist/gateway/gateway.mjs +2 -2
  73. package/dist/gateway/gateway.mjs.map +1 -1
  74. package/dist/git-trigger/git-hooks.d.mts +2 -2
  75. package/dist/git-trigger/git-hooks.d.ts +2 -2
  76. package/dist/{index-B0YHu_SP.d.ts → index-B5Ts1WtM.d.ts} +3 -3
  77. package/dist/{index-T1aBoUcc.d.ts → index-BfIxCYIZ.d.ts} +1 -1
  78. package/dist/{index-BPEBlOsE.d.mts → index-Cub7lK-T.d.mts} +3 -3
  79. package/dist/{index-DQb5-_1X.d.mts → index-CwAh7Tln.d.mts} +1 -1
  80. package/dist/index.d.mts +7 -7
  81. package/dist/index.d.ts +7 -7
  82. package/dist/index.js +74 -35
  83. package/dist/index.js.map +1 -1
  84. package/dist/index.mjs +71 -32
  85. package/dist/index.mjs.map +1 -1
  86. package/dist/local-evaluator/evaluator.d.mts +2 -2
  87. package/dist/local-evaluator/evaluator.d.ts +2 -2
  88. package/dist/metadata-capture.d.mts +18 -5
  89. package/dist/metadata-capture.d.ts +18 -5
  90. package/dist/metadata-capture.js +21 -4
  91. package/dist/metadata-capture.js.map +1 -1
  92. package/dist/metadata-capture.mjs +20 -4
  93. package/dist/metadata-capture.mjs.map +1 -1
  94. package/dist/{nextjs-w7RTbP1P.d.ts → nextjs-DL6uE1ye.d.ts} +1 -1
  95. package/dist/{nextjs-WyeVr2Kp.d.mts → nextjs-DlX6xwbU.d.mts} +1 -1
  96. package/dist/{sdk-CbTNIkAa.d.mts → sdk-Bbh9B_dw.d.mts} +1 -1
  97. package/dist/{sdk-QeX0Z8Ho.d.ts → sdk-C6SASmsh.d.ts} +1 -1
  98. package/dist/transport/index.d.mts +2 -2
  99. package/dist/transport/index.d.ts +2 -2
  100. package/dist/transport/index.js +5 -5
  101. package/dist/transport/index.js.map +1 -1
  102. package/dist/transport/index.mjs +2 -2
  103. package/dist/transport/index.mjs.map +1 -1
  104. package/dist/{types-r850cOt0.d.mts → types-C0zfSXMB.d.mts} +22 -0
  105. package/dist/{types-DqfPU5Bl.d.mts → types-C7Rb-w0d.d.mts} +1 -1
  106. package/dist/{types-sMxBT-nM.d.ts → types-DwSfO7Sb.d.ts} +22 -0
  107. package/dist/{types-BLUx92FJ.d.ts → types-nIh3HtuA.d.ts} +1 -1
  108. package/dist/ui/index.d.mts +1 -1
  109. package/dist/ui/index.d.ts +1 -1
  110. package/dist/verify.d.mts +1 -1
  111. package/dist/verify.d.ts +1 -1
  112. package/package.json +2 -4
@@ -748,6 +748,31 @@ function extractHttpCredentials(headers) {
748
748
  return credentials;
749
749
  }
750
750
 
751
+ // src/verified-hop.ts
752
+ var MCP_VERIFIED_HOP_HEADER = "X-Astra-Verified-Hop";
753
+ var MCP_VERIFIED_HOP_MAX_AGE_MS = 6e4;
754
+ function parseVerifiedHop(value) {
755
+ if (!value) return null;
756
+ const parts = value.split(";");
757
+ if (parts.length !== 3) return null;
758
+ const [astraId, sessionId, checkedAtRaw] = parts;
759
+ if (!astraId) return null;
760
+ const checkedAt = Number(checkedAtRaw);
761
+ if (!Number.isFinite(checkedAt) || checkedAt <= 0) return null;
762
+ return {
763
+ astraId,
764
+ ...sessionId ? { sessionId } : {},
765
+ checkedAt
766
+ };
767
+ }
768
+ function isVerifiedHopValidFor(marker, expectedAstraId, opts = {}) {
769
+ if (!marker) return false;
770
+ if (marker.astraId !== expectedAstraId) return false;
771
+ const maxAge = opts.maxAgeMs ?? MCP_VERIFIED_HOP_MAX_AGE_MS;
772
+ const now = opts.now ?? Date.now();
773
+ return now - marker.checkedAt <= maxAge && now >= marker.checkedAt;
774
+ }
775
+
751
776
  // src/adapters/http-pdlss.ts
752
777
  var HTTP_METHOD_ACTION_TABLE = {
753
778
  GET: "data.read",
@@ -898,7 +923,9 @@ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
898
923
  "x-astrasync-signature",
899
924
  "x-astrasync-secret",
900
925
  "x-hub-signature",
901
- "x-hub-signature-256"
926
+ "x-hub-signature-256",
927
+ // Short-lived verify dedupe token — must never persist in stored metadata.
928
+ "x-astra-verified-hop"
902
929
  ]);
903
930
  var SECRET_HEADER_PREFIXES = ["x-astrasync-", "kya-", "kya_"];
904
931
  var CREDENTIAL_HEADER_NAMES = /* @__PURE__ */ new Set([
@@ -1033,16 +1060,25 @@ var CONNECTION_HEADER_SOURCES = [
1033
1060
  ["cf-ipcountry", "x-vercel-ip-country", "cloudfront-viewer-country", "fastly-geo-country"]
1034
1061
  ],
1035
1062
  ["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
1063
+ ["countryRegionName", ["cloudfront-viewer-country-region-name"]],
1036
1064
  ["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
1037
1065
  ["asn", ["cloudfront-viewer-asn"]],
1038
1066
  ["tlsVersion", ["cloudfront-viewer-tls"]],
1039
1067
  ["httpVersion", ["cloudfront-viewer-http-version"]],
1068
+ ["timeZone", ["x-vercel-ip-timezone", "cloudfront-viewer-time-zone"]],
1069
+ ["metroCode", ["cloudfront-viewer-metro-code"]],
1040
1070
  // TLS fingerprints can only be computed where TLS terminates. When a CDN
1041
1071
  // terminates TLS in front of the merchant, its fingerprint headers ARE the
1042
1072
  // connection-layer truth — normalising them here is the permanent design.
1043
- ["tlsFingerprint", ["cf-ja3-hash"]],
1044
- ["ja4", ["cf-ja4"]]
1073
+ // CloudFront delivers JA3/JA4 only via an origin request policy and only
1074
+ // for HTTPS viewer connections.
1075
+ ["tlsFingerprint", ["cf-ja3-hash", "cloudfront-viewer-ja3-fingerprint"]],
1076
+ ["ja4", ["cf-ja4", "cloudfront-viewer-ja4-fingerprint"]],
1077
+ // Header-structure fingerprint: browser/SDK-distinctive header ordering.
1078
+ ["headerOrder", ["cloudfront-viewer-header-order"]],
1079
+ ["headerCount", ["cloudfront-viewer-header-count"]]
1045
1080
  ];
1081
+ var MAX_CONNECTION_VALUE_CHARS = 256;
1046
1082
  function deriveConnectionFromHeaders(headers) {
1047
1083
  if (!headers) return void 0;
1048
1084
  const lower = {};
@@ -1055,11 +1091,15 @@ function deriveConnectionFromHeaders(headers) {
1055
1091
  for (const source of sources) {
1056
1092
  const value = lower[source]?.trim();
1057
1093
  if (value) {
1058
- connection[key] = value;
1094
+ connection[key] = value.slice(0, MAX_CONNECTION_VALUE_CHARS);
1059
1095
  break;
1060
1096
  }
1061
1097
  }
1062
1098
  }
1099
+ if (!connection.ip) {
1100
+ const addr = lower["cloudfront-viewer-address"]?.trim();
1101
+ if (addr) connection.ip = addr.replace(/:\d+$/, "");
1102
+ }
1063
1103
  if (!connection.ip) {
1064
1104
  const xff = lower["x-forwarded-for"];
1065
1105
  const client = xff?.split(",")[0]?.trim();
@@ -1500,6 +1540,8 @@ function createMiddleware(options) {
1500
1540
  failOnError = "open",
1501
1541
  caseInsensitiveRouteMatch = false,
1502
1542
  anonymousBeacon = true,
1543
+ trustVerifiedHop = false,
1544
+ verifiedHopMaxAgeMs,
1503
1545
  ...config
1504
1546
  } = options;
1505
1547
  if (config.apiBaseUrl) {
@@ -1592,6 +1634,16 @@ function createMiddleware(options) {
1592
1634
  beaconPassThrough?.(req);
1593
1635
  return next();
1594
1636
  }
1637
+ if (trustVerifiedHop && credentials.astraId) {
1638
+ const hopRaw = req.headers[MCP_VERIFIED_HOP_HEADER.toLowerCase()];
1639
+ const hopValue = typeof hopRaw === "string" ? hopRaw : Array.isArray(hopRaw) ? hopRaw[0] : void 0;
1640
+ const marker = parseVerifiedHop(hopValue);
1641
+ if (isVerifiedHopValidFor(marker, credentials.astraId, {
1642
+ ...verifiedHopMaxAgeMs !== void 0 ? { maxAgeMs: verifiedHopMaxAgeMs } : {}
1643
+ })) {
1644
+ return next();
1645
+ }
1646
+ }
1595
1647
  const pdlssPair = resolveRequestPdlss(
1596
1648
  req,
1597
1649
  routeConfig,