@astrasyncai/verification-gateway 5.21.2 → 5.22.1

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 (87) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +19 -7
  3. package/dist/adapters/express.js +60 -11
  4. package/dist/adapters/express.js.map +1 -1
  5. package/dist/adapters/express.mjs +60 -11
  6. package/dist/adapters/express.mjs.map +1 -1
  7. package/dist/adapters/mcp.js +34 -3
  8. package/dist/adapters/mcp.js.map +1 -1
  9. package/dist/adapters/mcp.mjs +34 -3
  10. package/dist/adapters/mcp.mjs.map +1 -1
  11. package/dist/adapters/nextjs.js +60 -11
  12. package/dist/adapters/nextjs.js.map +1 -1
  13. package/dist/adapters/nextjs.mjs +60 -11
  14. package/dist/adapters/nextjs.mjs.map +1 -1
  15. package/dist/adapters/sdk.js +1 -1
  16. package/dist/adapters/sdk.js.map +1 -1
  17. package/dist/adapters/sdk.mjs +1 -1
  18. package/dist/adapters/sdk.mjs.map +1 -1
  19. package/dist/agent/index.js +1 -1
  20. package/dist/agent/index.js.map +1 -1
  21. package/dist/agent/index.mjs +1 -1
  22. package/dist/agent/index.mjs.map +1 -1
  23. package/dist/bin/astrasync-claude-hook.js +1 -1
  24. package/dist/bin/astrasync-codex-hook.js +1 -1
  25. package/dist/bin/astrasync-guard.js +1 -1
  26. package/dist/bin/astrasync.js +1 -1
  27. package/dist/browser/background.js +1 -1
  28. package/dist/browser/background.js.map +1 -1
  29. package/dist/browser/background.mjs +1 -1
  30. package/dist/browser/background.mjs.map +1 -1
  31. package/dist/cli/index.js +1 -1
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/index.mjs +1 -1
  34. package/dist/cli/index.mjs.map +1 -1
  35. package/dist/codex/index.js +1 -1
  36. package/dist/codex/index.js.map +1 -1
  37. package/dist/codex/index.mjs +1 -1
  38. package/dist/codex/index.mjs.map +1 -1
  39. package/dist/cursor/extension.js +1 -1
  40. package/dist/cursor/extension.js.map +1 -1
  41. package/dist/cursor/extension.mjs +1 -1
  42. package/dist/cursor/extension.mjs.map +1 -1
  43. package/dist/edge-config.js +1 -1
  44. package/dist/edge-config.js.map +1 -1
  45. package/dist/edge-config.mjs +1 -1
  46. package/dist/edge-config.mjs.map +1 -1
  47. package/dist/edge-core/index.d.mts +4 -1
  48. package/dist/edge-core/index.d.ts +4 -1
  49. package/dist/edge-core/index.js +45 -15
  50. package/dist/edge-core/index.js.map +1 -1
  51. package/dist/edge-core/index.mjs +45 -15
  52. package/dist/edge-core/index.mjs.map +1 -1
  53. package/dist/gateway/gateway.js +1 -1
  54. package/dist/gateway/gateway.js.map +1 -1
  55. package/dist/gateway/gateway.mjs +1 -1
  56. package/dist/gateway/gateway.mjs.map +1 -1
  57. package/dist/index.d.mts +44 -6
  58. package/dist/index.d.ts +44 -6
  59. package/dist/index.js +71 -14
  60. package/dist/index.js.map +1 -1
  61. package/dist/index.mjs +71 -14
  62. package/dist/index.mjs.map +1 -1
  63. package/dist/metadata-capture.d.mts +5 -3
  64. package/dist/metadata-capture.d.ts +5 -3
  65. package/dist/metadata-capture.js +33 -2
  66. package/dist/metadata-capture.js.map +1 -1
  67. package/dist/metadata-capture.mjs +33 -2
  68. package/dist/metadata-capture.mjs.map +1 -1
  69. package/dist/platform-signatures.d.mts +13 -0
  70. package/dist/platform-signatures.d.ts +13 -0
  71. package/dist/platform-signatures.js +26 -8
  72. package/dist/platform-signatures.js.map +1 -1
  73. package/dist/platform-signatures.mjs +26 -8
  74. package/dist/platform-signatures.mjs.map +1 -1
  75. package/dist/registration/index.js +1 -1
  76. package/dist/registration/index.js.map +1 -1
  77. package/dist/registration/index.mjs +1 -1
  78. package/dist/registration/index.mjs.map +1 -1
  79. package/dist/transport/index.js +1 -1
  80. package/dist/transport/index.js.map +1 -1
  81. package/dist/transport/index.mjs +1 -1
  82. package/dist/transport/index.mjs.map +1 -1
  83. package/dist/verify.js +1 -1
  84. package/dist/verify.js.map +1 -1
  85. package/dist/verify.mjs +1 -1
  86. package/dist/verify.mjs.map +1 -1
  87. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var SDK_VERSION = "5.21.2";
2
+ var SDK_VERSION = "5.22.1";
3
3
 
4
4
  // src/http.ts
5
5
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -98,7 +98,11 @@ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
98
98
  "x-goog-api-client",
99
99
  "user-agent",
100
100
  "x-agent-card-url",
101
- "x-agent-provider"
101
+ "x-agent-provider",
102
+ // Round 31 — Web Bot Auth's Signature-Agent names the signing agent's
103
+ // directory host (a public URL, never a secret). It attributes a signed
104
+ // agent even when its UA is stock Chrome.
105
+ "signature-agent"
102
106
  ]);
103
107
  var PLATFORM_HEADER_PREFIXES = [
104
108
  "x-goog-",
@@ -229,7 +233,8 @@ var PLATFORM_AGENT_SIGNATURES = [
229
233
  uaPatterns: [/claude/i, /anthropic/i],
230
234
  agentCardPatterns: [/anthropic\.com/i, /claude\.ai/i],
231
235
  apiKeyFormatPatterns: [/^sk-ant/i],
232
- headerPatterns: [/^anthropic-version/i, /^anthropic-beta/i, /^x-anthropic-/i]
236
+ headerPatterns: [/^anthropic-version/i, /^anthropic-beta/i, /^x-anthropic-/i],
237
+ wafLabelPatterns: [/\bclaude/i, /\banthropic/i]
233
238
  },
234
239
  {
235
240
  vendor: "chatgpt",
@@ -240,7 +245,14 @@ var PLATFORM_AGENT_SIGNATURES = [
240
245
  uaPatterns: [/chatgpt/i, /openai/i, /gpt-?\d/i, /\bGPTBot\b/i, /\bOAI-SearchBot\b/i],
241
246
  agentCardPatterns: [/openai\.com/i, /chatgpt\.com/i],
242
247
  apiKeyFormatPatterns: [/^sk-proj/i, /^sk-svcacct/i],
243
- headerPatterns: [/^openai-organization/i, /^openai-project/i, /^openai-version/i]
248
+ headerPatterns: [
249
+ /^openai-organization/i,
250
+ /^openai-project/i,
251
+ /^openai-version/i,
252
+ // ChatGPT agent signs with Web Bot Auth under this directory host.
253
+ /^signature-agent: "?https:\/\/chatgpt\.com/i
254
+ ],
255
+ wafLabelPatterns: [/\bgptbot\b/i, /\bchatgpt/i, /\boai-searchbot\b/i, /\bopenai/i]
244
256
  },
245
257
  {
246
258
  vendor: "gemini",
@@ -261,7 +273,8 @@ var PLATFORM_AGENT_SIGNATURES = [
261
273
  ],
262
274
  agentCardPatterns: [/gemini\.google\.com/i, /ai\.google\.dev/i],
263
275
  apiKeyFormatPatterns: [/^aiza/i],
264
- headerPatterns: [/^x-goog-user-project/i, /^x-goog-api-client/i]
276
+ headerPatterns: [/^x-goog-user-project/i, /^x-goog-api-client/i],
277
+ wafLabelPatterns: [/\bgoogle-extended\b/i, /\bgoogleother\b/i, /\bgemini/i]
265
278
  },
266
279
  {
267
280
  vendor: "cursor",
@@ -280,7 +293,8 @@ var PLATFORM_AGENT_SIGNATURES = [
280
293
  displayName: "Perplexity",
281
294
  uaPatterns: [/perplexity/i],
282
295
  agentCardPatterns: [/perplexity\.ai/i],
283
- apiKeyFormatPatterns: [/^pplx-/i]
296
+ apiKeyFormatPatterns: [/^pplx-/i],
297
+ wafLabelPatterns: [/\bperplexity/i]
284
298
  },
285
299
  // Round 30.1: xAI's documented crawlers (GrokBot/1.0, xAI-Grok/1.0,
286
300
  // Grok-DeepSearch/1.0). Anchored, versioned tokens — never in a stock UA.
@@ -289,7 +303,8 @@ var PLATFORM_AGENT_SIGNATURES = [
289
303
  displayName: "xAI Grok",
290
304
  uaPatterns: [/\bGrokBot\//i, /\bxAI-Grok\//i, /\bGrok-DeepSearch\//i],
291
305
  agentCardPatterns: [/\bx\.ai\b/i, /grok\.com/i],
292
- apiKeyFormatPatterns: [/^xai-/i]
306
+ apiKeyFormatPatterns: [/^xai-/i],
307
+ wafLabelPatterns: [/\bgrok/i, /\bxai\b/i]
293
308
  },
294
309
  // Round 30.1: Meta AI's index and fetch crawlers. facebookexternalhit
295
310
  // (link previews) is deliberately NOT here — it stays a generic crawler.
@@ -297,7 +312,12 @@ var PLATFORM_AGENT_SIGNATURES = [
297
312
  vendor: "meta-ai",
298
313
  displayName: "Meta AI",
299
314
  uaPatterns: [/\bMeta-WebIndexer\b/i, /\bMeta-ExternalFetcher\b/i],
300
- agentCardPatterns: [/meta\.ai/i]
315
+ agentCardPatterns: [/meta\.ai/i],
316
+ wafLabelPatterns: [
317
+ /\bmeta-webindexer\b/i,
318
+ /\bmeta-externalfetcher\b/i,
319
+ /\bmeta-externalagent\b/i
320
+ ]
301
321
  },
302
322
  // Agentic browsers — versioned-token patterns ONLY (a stock Chrome UA must
303
323
  // never match). Distinct vendor keys (not 'chatgpt'/'perplexity'): the
@@ -345,6 +365,7 @@ function matchPlatformSignature(signatures, input) {
345
365
  const apiKeyFormat = input.apiKeyFormat ?? "";
346
366
  const ja4 = input.ja4 ?? "";
347
367
  const asn = input.asn ?? "";
368
+ const wafLabels = input.wafLabels ?? [];
348
369
  const headerLines = [];
349
370
  if (input.platformHeaders) {
350
371
  for (const [name, value] of Object.entries(input.platformHeaders)) {
@@ -358,7 +379,8 @@ function matchPlatformSignature(signatures, input) {
358
379
  const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
359
380
  const ja4Match = ja4.length > 0 && sig.ja4Patterns?.some((p) => p.test(ja4));
360
381
  const asnMatch = asn.length > 0 && sig.asnList?.includes(asn);
361
- if (uaMatch || cardMatch || keyMatch || headerMatch || ja4Match || asnMatch) {
382
+ const wafMatch = wafLabels.length > 0 && sig.wafLabelPatterns?.some((p) => wafLabels.some((label) => p.test(label)));
383
+ if (uaMatch || cardMatch || keyMatch || headerMatch || ja4Match || asnMatch || wafMatch) {
362
384
  const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
363
385
  const cardHost = (() => {
364
386
  try {
@@ -367,7 +389,7 @@ function matchPlatformSignature(signatures, input) {
367
389
  return "";
368
390
  }
369
391
  })();
370
- const keyBasis = uaBase || cardHost || apiKeyFormat || ja4 || asn && `asn${asn}` || "unknown";
392
+ const keyBasis = uaBase || cardHost || apiKeyFormat || ja4 || asn && `asn${asn}` || wafMatch && `waf:${wafLabels[0]?.toLowerCase()}` || "unknown";
371
393
  return {
372
394
  vendor: sig.vendor,
373
395
  fingerprintKey: `${sig.vendor}:${keyBasis}`,
@@ -1880,7 +1902,7 @@ function resetBeaconBuffer(options) {
1880
1902
  beaconBuffer = new BeaconBuffer(options);
1881
1903
  return beaconBuffer;
1882
1904
  }
1883
- async function emitBeacon(options, req, classification, budgetMs, queryValueAllowlist, apiKey) {
1905
+ async function emitBeacon(options, req, classification, budgetMs, queryValueAllowlist, apiKey, edgeOutcome) {
1884
1906
  const attemptId = extractAttemptId(req);
1885
1907
  const declaredSource = normalizeDeclaredSource(headerValue(req, "x-astra-source"));
1886
1908
  const userAgent = headerValue(req, "user-agent");
@@ -1907,7 +1929,10 @@ async function emitBeacon(options, req, classification, budgetMs, queryValueAllo
1907
1929
  // caller.
1908
1930
  observedMetadata: buildObservedMetadata(req, queryValueAllowlist),
1909
1931
  // Capture time — batched delivery skews createdAt by the flush delay.
1910
- observedAt: (/* @__PURE__ */ new Date()).toISOString()
1932
+ observedAt: (/* @__PURE__ */ new Date()).toISOString(),
1933
+ // Round 31 — the edge's own verdict, so enforce-mode denies are
1934
+ // recorded as denies rather than passes.
1935
+ ...edgeOutcome && { edgeDecision: edgeOutcome.decision, edgeMode: edgeOutcome.mode }
1911
1936
  };
1912
1937
  for (const k of Object.keys(item)) if (item[k] === void 0) delete item[k];
1913
1938
  const buffer = getBeaconBuffer();
@@ -1927,7 +1952,8 @@ async function emitBeacon(options, req, classification, budgetMs, queryValueAllo
1927
1952
  userAgent ?? "",
1928
1953
  req.method,
1929
1954
  req.uri,
1930
- attemptId ?? ""
1955
+ attemptId ?? "",
1956
+ edgeOutcome?.decision ?? ""
1931
1957
  ].join("\0") : void 0
1932
1958
  );
1933
1959
  const flushing = buffer.flush();
@@ -2101,12 +2127,15 @@ async function runTier(options, req, classification, policy, apiKey, capture) {
2101
2127
  }
2102
2128
  return outcomeFromVerifyResult(classification, result);
2103
2129
  }
2104
- await emitBeacon(options, req, classification, beaconMs, queryValueAllowlist, apiKey);
2105
2130
  const outcome = baseOutcome(classification);
2106
2131
  if (policy.mode === "enforce" && policy.depth !== "classify") {
2107
2132
  outcome.decision = "deny";
2108
2133
  outcome.reasons = ["agent is not registered with AstraSync"];
2109
2134
  }
2135
+ await emitBeacon(options, req, classification, beaconMs, queryValueAllowlist, apiKey, {
2136
+ decision: outcome.decision === "deny" ? "deny" : "allow",
2137
+ mode: policy.mode
2138
+ });
2110
2139
  return outcome;
2111
2140
  }
2112
2141
  case "anonymous-bot": {
@@ -2117,7 +2146,8 @@ async function runTier(options, req, classification, policy, apiKey, capture) {
2117
2146
  { ...classification, protocol: classification.protocol ?? "ua-heuristic" },
2118
2147
  beaconMs,
2119
2148
  queryValueAllowlist,
2120
- apiKey
2149
+ apiKey,
2150
+ { decision: "allow", mode: policy.mode }
2121
2151
  );
2122
2152
  }
2123
2153
  return baseOutcome(classification);