@astrasyncai/verification-gateway 5.21.1 → 5.22.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 (87) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +19 -7
  3. package/dist/adapters/express.js +75 -9
  4. package/dist/adapters/express.js.map +1 -1
  5. package/dist/adapters/express.mjs +75 -9
  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 +75 -9
  12. package/dist/adapters/nextjs.js.map +1 -1
  13. package/dist/adapters/nextjs.mjs +75 -9
  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 +60 -13
  50. package/dist/edge-core/index.js.map +1 -1
  51. package/dist/edge-core/index.mjs +60 -13
  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 +27 -6
  58. package/dist/index.d.ts +27 -6
  59. package/dist/index.js +75 -9
  60. package/dist/index.js.map +1 -1
  61. package/dist/index.mjs +75 -9
  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 +20 -1
  70. package/dist/platform-signatures.d.ts +20 -1
  71. package/dist/platform-signatures.js +41 -6
  72. package/dist/platform-signatures.js.map +1 -1
  73. package/dist/platform-signatures.mjs +41 -6
  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.1";
2
+ var SDK_VERSION = "5.22.0";
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,31 @@ 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]
298
+ },
299
+ // Round 30.1: xAI's documented crawlers (GrokBot/1.0, xAI-Grok/1.0,
300
+ // Grok-DeepSearch/1.0). Anchored, versioned tokens — never in a stock UA.
301
+ {
302
+ vendor: "grok",
303
+ displayName: "xAI Grok",
304
+ uaPatterns: [/\bGrokBot\//i, /\bxAI-Grok\//i, /\bGrok-DeepSearch\//i],
305
+ agentCardPatterns: [/\bx\.ai\b/i, /grok\.com/i],
306
+ apiKeyFormatPatterns: [/^xai-/i],
307
+ wafLabelPatterns: [/\bgrok/i, /\bxai\b/i]
308
+ },
309
+ // Round 30.1: Meta AI's index and fetch crawlers. facebookexternalhit
310
+ // (link previews) is deliberately NOT here — it stays a generic crawler.
311
+ {
312
+ vendor: "meta-ai",
313
+ displayName: "Meta AI",
314
+ uaPatterns: [/\bMeta-WebIndexer\b/i, /\bMeta-ExternalFetcher\b/i],
315
+ agentCardPatterns: [/meta\.ai/i],
316
+ wafLabelPatterns: [
317
+ /\bmeta-webindexer\b/i,
318
+ /\bmeta-externalfetcher\b/i,
319
+ /\bmeta-externalagent\b/i
320
+ ]
284
321
  },
285
322
  // Agentic browsers — versioned-token patterns ONLY (a stock Chrome UA must
286
323
  // never match). Distinct vendor keys (not 'chatgpt'/'perplexity'): the
@@ -328,6 +365,7 @@ function matchPlatformSignature(signatures, input) {
328
365
  const apiKeyFormat = input.apiKeyFormat ?? "";
329
366
  const ja4 = input.ja4 ?? "";
330
367
  const asn = input.asn ?? "";
368
+ const wafLabels = input.wafLabels ?? [];
331
369
  const headerLines = [];
332
370
  if (input.platformHeaders) {
333
371
  for (const [name, value] of Object.entries(input.platformHeaders)) {
@@ -341,7 +379,8 @@ function matchPlatformSignature(signatures, input) {
341
379
  const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
342
380
  const ja4Match = ja4.length > 0 && sig.ja4Patterns?.some((p) => p.test(ja4));
343
381
  const asnMatch = asn.length > 0 && sig.asnList?.includes(asn);
344
- 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) {
345
384
  const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
346
385
  const cardHost = (() => {
347
386
  try {
@@ -350,7 +389,7 @@ function matchPlatformSignature(signatures, input) {
350
389
  return "";
351
390
  }
352
391
  })();
353
- 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";
354
393
  return {
355
394
  vendor: sig.vendor,
356
395
  fingerprintKey: `${sig.vendor}:${keyBasis}`,
@@ -1863,7 +1902,7 @@ function resetBeaconBuffer(options) {
1863
1902
  beaconBuffer = new BeaconBuffer(options);
1864
1903
  return beaconBuffer;
1865
1904
  }
1866
- async function emitBeacon(options, req, classification, budgetMs, queryValueAllowlist, apiKey) {
1905
+ async function emitBeacon(options, req, classification, budgetMs, queryValueAllowlist, apiKey, edgeOutcome) {
1867
1906
  const attemptId = extractAttemptId(req);
1868
1907
  const declaredSource = normalizeDeclaredSource(headerValue(req, "x-astra-source"));
1869
1908
  const userAgent = headerValue(req, "user-agent");
@@ -1890,7 +1929,10 @@ async function emitBeacon(options, req, classification, budgetMs, queryValueAllo
1890
1929
  // caller.
1891
1930
  observedMetadata: buildObservedMetadata(req, queryValueAllowlist),
1892
1931
  // Capture time — batched delivery skews createdAt by the flush delay.
1893
- 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 }
1894
1936
  };
1895
1937
  for (const k of Object.keys(item)) if (item[k] === void 0) delete item[k];
1896
1938
  const buffer = getBeaconBuffer();
@@ -1910,7 +1952,8 @@ async function emitBeacon(options, req, classification, budgetMs, queryValueAllo
1910
1952
  userAgent ?? "",
1911
1953
  req.method,
1912
1954
  req.uri,
1913
- attemptId ?? ""
1955
+ attemptId ?? "",
1956
+ edgeOutcome?.decision ?? ""
1914
1957
  ].join("\0") : void 0
1915
1958
  );
1916
1959
  const flushing = buffer.flush();
@@ -2084,12 +2127,15 @@ async function runTier(options, req, classification, policy, apiKey, capture) {
2084
2127
  }
2085
2128
  return outcomeFromVerifyResult(classification, result);
2086
2129
  }
2087
- await emitBeacon(options, req, classification, beaconMs, queryValueAllowlist, apiKey);
2088
2130
  const outcome = baseOutcome(classification);
2089
2131
  if (policy.mode === "enforce" && policy.depth !== "classify") {
2090
2132
  outcome.decision = "deny";
2091
2133
  outcome.reasons = ["agent is not registered with AstraSync"];
2092
2134
  }
2135
+ await emitBeacon(options, req, classification, beaconMs, queryValueAllowlist, apiKey, {
2136
+ decision: outcome.decision === "deny" ? "deny" : "allow",
2137
+ mode: policy.mode
2138
+ });
2093
2139
  return outcome;
2094
2140
  }
2095
2141
  case "anonymous-bot": {
@@ -2100,7 +2146,8 @@ async function runTier(options, req, classification, policy, apiKey, capture) {
2100
2146
  { ...classification, protocol: classification.protocol ?? "ua-heuristic" },
2101
2147
  beaconMs,
2102
2148
  queryValueAllowlist,
2103
- apiKey
2149
+ apiKey,
2150
+ { decision: "allow", mode: policy.mode }
2104
2151
  );
2105
2152
  }
2106
2153
  return baseOutcome(classification);