@astrasyncai/verification-gateway 3.8.0 → 3.10.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 (114) hide show
  1. package/dist/adapter-interface/interface.d.mts +3 -2
  2. package/dist/adapter-interface/interface.d.ts +3 -2
  3. package/dist/adapters/express.d.mts +3 -2
  4. package/dist/adapters/express.d.ts +3 -2
  5. package/dist/adapters/express.js +152 -2
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +152 -2
  8. package/dist/adapters/express.mjs.map +1 -1
  9. package/dist/adapters/http-pdlss.d.mts +81 -0
  10. package/dist/adapters/http-pdlss.d.ts +81 -0
  11. package/dist/adapters/http-pdlss.js +117 -0
  12. package/dist/adapters/http-pdlss.js.map +1 -0
  13. package/dist/adapters/http-pdlss.mjs +87 -0
  14. package/dist/adapters/http-pdlss.mjs.map +1 -0
  15. package/dist/adapters/mcp.d.mts +2 -1
  16. package/dist/adapters/mcp.d.ts +2 -1
  17. package/dist/adapters/mcp.js +2 -1
  18. package/dist/adapters/mcp.js.map +1 -1
  19. package/dist/adapters/mcp.mjs +2 -1
  20. package/dist/adapters/mcp.mjs.map +1 -1
  21. package/dist/adapters/nextjs.d.mts +3 -2
  22. package/dist/adapters/nextjs.d.ts +3 -2
  23. package/dist/adapters/nextjs.js +152 -2
  24. package/dist/adapters/nextjs.js.map +1 -1
  25. package/dist/adapters/nextjs.mjs +152 -2
  26. package/dist/adapters/nextjs.mjs.map +1 -1
  27. package/dist/adapters/sdk.d.mts +3 -2
  28. package/dist/adapters/sdk.d.ts +3 -2
  29. package/dist/adapters/sdk.js +2 -1
  30. package/dist/adapters/sdk.js.map +1 -1
  31. package/dist/adapters/sdk.mjs +2 -1
  32. package/dist/adapters/sdk.mjs.map +1 -1
  33. package/dist/agent/index.d.mts +3 -2
  34. package/dist/agent/index.d.ts +3 -2
  35. package/dist/bin/astrasync-claude-hook.js +17 -1
  36. package/dist/bin/astrasync-guard.js +17 -1
  37. package/dist/bin/astrasync.js +43 -1
  38. package/dist/browser/background.js +17 -1
  39. package/dist/browser/background.js.map +1 -1
  40. package/dist/browser/background.mjs +17 -1
  41. package/dist/browser/background.mjs.map +1 -1
  42. package/dist/browser/browser-adapter.d.mts +3 -2
  43. package/dist/browser/browser-adapter.d.ts +3 -2
  44. package/dist/claude-code/claude-code-adapter.d.mts +3 -2
  45. package/dist/claude-code/claude-code-adapter.d.ts +3 -2
  46. package/dist/cli/index.d.mts +3 -2
  47. package/dist/cli/index.d.ts +3 -2
  48. package/dist/cursor/cursor-adapter.d.mts +3 -2
  49. package/dist/cursor/cursor-adapter.d.ts +3 -2
  50. package/dist/cursor/extension.d.mts +3 -2
  51. package/dist/cursor/extension.d.ts +3 -2
  52. package/dist/cursor/extension.js +17 -1
  53. package/dist/cursor/extension.js.map +1 -1
  54. package/dist/cursor/extension.mjs +17 -1
  55. package/dist/cursor/extension.mjs.map +1 -1
  56. package/dist/edge-config.d.mts +131 -0
  57. package/dist/edge-config.d.ts +131 -0
  58. package/dist/edge-config.js +162 -0
  59. package/dist/edge-config.js.map +1 -0
  60. package/dist/edge-config.mjs +131 -0
  61. package/dist/edge-config.mjs.map +1 -0
  62. package/dist/{express-C8nJGi5P.d.ts → express-ClNtDhhc.d.ts} +1 -1
  63. package/dist/{express-Di_hnZZS.d.mts → express-DCXa1oqj.d.mts} +1 -1
  64. package/dist/gateway/gateway.d.mts +3 -2
  65. package/dist/gateway/gateway.d.ts +3 -2
  66. package/dist/gateway/gateway.js +17 -1
  67. package/dist/gateway/gateway.js.map +1 -1
  68. package/dist/gateway/gateway.mjs +17 -1
  69. package/dist/gateway/gateway.mjs.map +1 -1
  70. package/dist/git-trigger/git-hooks.d.mts +3 -2
  71. package/dist/git-trigger/git-hooks.d.ts +3 -2
  72. package/dist/{index-CXcvO9Au.d.mts → index-BrNKDmiR.d.mts} +1 -1
  73. package/dist/{index-CuCkjT7B.d.ts → index-CfHurO1P.d.ts} +1 -1
  74. package/dist/{index-CBQr4FGs.d.ts → index-D2ztkumS.d.ts} +1 -1
  75. package/dist/{index-DALAqct7.d.mts → index-Dr_XiN65.d.mts} +1 -1
  76. package/dist/index.d.mts +27 -82
  77. package/dist/index.d.ts +27 -82
  78. package/dist/index.js +435 -12
  79. package/dist/index.js.map +1 -1
  80. package/dist/index.mjs +417 -12
  81. package/dist/index.mjs.map +1 -1
  82. package/dist/local-evaluator/evaluator.d.mts +3 -2
  83. package/dist/local-evaluator/evaluator.d.ts +3 -2
  84. package/dist/metadata-capture.d.mts +87 -0
  85. package/dist/metadata-capture.d.ts +87 -0
  86. package/dist/metadata-capture.js +184 -0
  87. package/dist/metadata-capture.js.map +1 -0
  88. package/dist/metadata-capture.mjs +154 -0
  89. package/dist/metadata-capture.mjs.map +1 -0
  90. package/dist/{nextjs-IyXWW2KL.d.ts → nextjs-CEBVBsdi.d.ts} +1 -1
  91. package/dist/{nextjs-BMAe8ode.d.mts → nextjs-DcQIk6Zj.d.mts} +1 -1
  92. package/dist/platform-signatures.d.mts +97 -0
  93. package/dist/platform-signatures.d.ts +97 -0
  94. package/dist/platform-signatures.js +116 -0
  95. package/dist/platform-signatures.js.map +1 -0
  96. package/dist/platform-signatures.mjs +89 -0
  97. package/dist/platform-signatures.mjs.map +1 -0
  98. package/dist/{sdk-Cn4KcZ5G.d.mts → sdk-CZkbSOeO.d.mts} +1 -1
  99. package/dist/{sdk-ThdA_NtL.d.ts → sdk-H0JCLW2y.d.ts} +1 -1
  100. package/dist/transport/index.d.mts +3 -2
  101. package/dist/transport/index.d.ts +3 -2
  102. package/dist/{types-DedAJbNI.d.mts → types-9tns4wyl.d.ts} +88 -1
  103. package/dist/{types-CSFci5zD.d.mts → types-D0lCtFQ7.d.mts} +1 -1
  104. package/dist/{types-D1kyMiml.d.ts → types-YbiXYKx1.d.ts} +1 -1
  105. package/dist/{types-DedAJbNI.d.ts → types-sy3tq8lp.d.mts} +88 -1
  106. package/dist/ui/index.d.mts +2 -1
  107. package/dist/ui/index.d.ts +2 -1
  108. package/dist/verify.d.mts +151 -0
  109. package/dist/verify.d.ts +151 -0
  110. package/dist/verify.js +593 -0
  111. package/dist/verify.js.map +1 -0
  112. package/dist/verify.mjs +557 -0
  113. package/dist/verify.mjs.map +1 -0
  114. package/package.json +26 -1
package/dist/index.js CHANGED
@@ -37,35 +37,53 @@ __export(src_exports, {
37
37
  AstraSyncError: () => AstraSyncError,
38
38
  AuthenticationError: () => AuthenticationError,
39
39
  ChallengeHandler: () => ChallengeHandler,
40
+ DEFAULT_EDGE_CONFIG: () => DEFAULT_EDGE_CONFIG,
40
41
  DEFAULT_TRUST_THRESHOLDS: () => DEFAULT_TRUST_THRESHOLDS,
41
42
  KYDRequiredError: () => KYDRequiredError,
43
+ MAX_HEADERS: () => MAX_HEADERS,
44
+ MAX_HEADER_VALUE_BYTES: () => MAX_HEADER_VALUE_BYTES,
45
+ MAX_TOTAL_BYTES: () => MAX_TOTAL_BYTES,
46
+ PLATFORM_AGENT_SIGNATURES: () => PLATFORM_AGENT_SIGNATURES,
42
47
  RegistrationDeniedError: () => RegistrationDeniedError,
43
48
  RegistrationExpiredError: () => RegistrationExpiredError,
44
49
  RegistrationTimeoutError: () => RegistrationTimeoutError,
45
50
  TRUST_LEVEL_RANGES: () => TRUST_LEVEL_RANGES,
46
- VERSION: () => VERSION,
51
+ VERSION: () => SDK_VERSION,
52
+ _resetEdgeConfigCache: () => _resetEdgeConfigCache,
47
53
  agent: () => agent_exports,
48
54
  authorizeSettlement: () => authorizeSettlement,
49
55
  awaitStepUpApproval: () => awaitStepUpApproval,
50
56
  buildGuidance: () => buildGuidance,
51
57
  clearCache: () => clearCache,
52
58
  createMcpMiddleware: () => createMcpMiddleware,
59
+ degradeToObserve: () => degradeToObserve,
60
+ detectPlatformFingerprint: () => detectPlatformFingerprint,
53
61
  determineAccessLevel: () => determineAccessLevel,
54
62
  express: () => express_exports,
63
+ extractApiKeyFormat: () => extractApiKeyFormat,
55
64
  extractCredentials: () => extractCredentials,
56
65
  extractMcpCredentials: () => extractMcpCredentials,
66
+ extractPlatformHeaders: () => extractPlatformHeaders,
67
+ fetchEdgeConfig: () => fetchEdgeConfig,
68
+ fetchRoutes: () => fetchRoutes,
57
69
  getAccessLevelForScore: () => getAccessLevelForScore,
58
70
  getCachedWellKnownUrls: () => getCachedWellKnownUrls,
59
71
  getCapabilities: () => getCapabilities,
72
+ getEdgeConfig: () => getEdgeConfig,
60
73
  getTrustLevel: () => getTrustLevel,
61
74
  getWellKnownUrls: () => getWellKnownUrls,
62
75
  hasCredentials: () => hasCredentials,
63
76
  hasMinimumAccess: () => hasMinimumAccess,
77
+ isEdgeConfig: () => isEdgeConfig,
78
+ matchEdgePathRule: () => matchEdgePathRule,
79
+ matchPlatformSignature: () => matchPlatformSignature,
64
80
  nextjs: () => nextjs_exports,
65
81
  pollStepUpStatus: () => pollStepUpStatus,
66
82
  prefetchWellKnown: () => prefetchWellKnown,
67
83
  quickVerify: () => quickVerify,
68
84
  recordDecision: () => recordDecision2,
85
+ reportUnregisteredAttempt: () => reportUnregisteredAttempt,
86
+ sanitizeHeaders: () => sanitizeHeaders,
69
87
  sdk: () => sdk_exports,
70
88
  setMcpMeta: () => setMcpMeta,
71
89
  transport: () => transport_exports,
@@ -195,7 +213,7 @@ function getCapabilities(accessLevel) {
195
213
  }
196
214
 
197
215
  // src/version.ts
198
- var SDK_VERSION = "3.7.1";
216
+ var SDK_VERSION = "3.10.0";
199
217
 
200
218
  // src/well-known.ts
201
219
  var CACHE_TTL_MS = 60 * 60 * 1e3;
@@ -482,6 +500,7 @@ async function callVerifyAccessAPI(config, request) {
482
500
  if (requestData.runtimeChallengeOptions)
483
501
  body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
484
502
  if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
503
+ if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
485
504
  body.sdkVersion = SDK_VERSION;
486
505
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
487
506
  const meta = {
@@ -730,6 +749,21 @@ async function fetchRoutes(config, counterpartyId) {
730
749
  return null;
731
750
  }
732
751
  }
752
+ async function reportUnregisteredAttempt(config, data) {
753
+ const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
754
+ const { counterpartyUrl, ...rest } = data;
755
+ const body = {
756
+ ...rest,
757
+ ...counterpartyUrl && { counterpartyUrl },
758
+ ...config.counterpartyId && { counterpartyId: config.counterpartyId }
759
+ };
760
+ await fetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
761
+ method: "POST",
762
+ headers: { "Content-Type": "application/json" },
763
+ body: JSON.stringify(body)
764
+ }).catch(() => {
765
+ });
766
+ }
733
767
  async function reportCounterpartyPreCheckFailure(config, data) {
734
768
  const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
735
769
  await fetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {
@@ -1076,6 +1110,152 @@ function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
1076
1110
  return failures;
1077
1111
  }
1078
1112
 
1113
+ // src/metadata-capture.ts
1114
+ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
1115
+ "cookie",
1116
+ "set-cookie",
1117
+ "x-csrf-token",
1118
+ "proxy-authorization",
1119
+ "x-astrasync-signature",
1120
+ "x-astrasync-secret",
1121
+ "x-hub-signature",
1122
+ "x-hub-signature-256"
1123
+ ]);
1124
+ var SECRET_HEADER_PREFIXES = ["x-astrasync-", "kya-", "kya_"];
1125
+ var CREDENTIAL_HEADER_NAMES = /* @__PURE__ */ new Set([
1126
+ "authorization",
1127
+ "x-api-key",
1128
+ "x-goog-api-key",
1129
+ "api-key"
1130
+ ]);
1131
+ function isSignatureHeader(name) {
1132
+ return name === "signature" || name.endsWith("-signature") || name.endsWith("-signature-256");
1133
+ }
1134
+ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
1135
+ "openai-organization",
1136
+ "openai-project",
1137
+ "openai-version",
1138
+ "openai-processing-ms",
1139
+ "anthropic-version",
1140
+ "anthropic-beta",
1141
+ "x-goog-user-project",
1142
+ "x-goog-api-client",
1143
+ "user-agent",
1144
+ "x-agent-card-url",
1145
+ "x-agent-provider"
1146
+ ]);
1147
+ var PLATFORM_HEADER_PREFIXES = ["x-goog-", "x-stainless-", "x-anthropic-", "x-openai-"];
1148
+ var KEY_FORMAT_PREFIXES = [
1149
+ "sk-ant-api03",
1150
+ "sk-ant-api",
1151
+ "sk-ant",
1152
+ "sk-proj",
1153
+ "sk-svcacct",
1154
+ "sk-or-v1",
1155
+ "sk-or",
1156
+ "sk-lf",
1157
+ "sk-",
1158
+ "gsk_",
1159
+ "aiza",
1160
+ "ya29",
1161
+ "ghp_",
1162
+ "gho_",
1163
+ "github_pat_",
1164
+ "xai-",
1165
+ "pplx-",
1166
+ "r8_",
1167
+ "hf_",
1168
+ "astra-",
1169
+ "astrae-"
1170
+ ];
1171
+ var MAX_HEADERS = 64;
1172
+ var MAX_HEADER_VALUE_BYTES = 1024;
1173
+ var MAX_TOTAL_BYTES = 16 * 1024;
1174
+ function byteLength(s) {
1175
+ let bytes = 0;
1176
+ for (let i = 0; i < s.length; i++) {
1177
+ const code = s.charCodeAt(i);
1178
+ if (code < 128) bytes += 1;
1179
+ else if (code < 2048) bytes += 2;
1180
+ else if (code >= 55296 && code <= 56319) {
1181
+ bytes += 4;
1182
+ i++;
1183
+ } else bytes += 3;
1184
+ }
1185
+ return bytes;
1186
+ }
1187
+ function extractApiKeyFormat(rawValue) {
1188
+ if (!rawValue) return void 0;
1189
+ let value = rawValue.trim();
1190
+ const spaceIdx = value.indexOf(" ");
1191
+ if (spaceIdx > 0) {
1192
+ const scheme = value.slice(0, spaceIdx).toLowerCase();
1193
+ if (scheme === "bearer" || scheme === "basic" || scheme === "token") {
1194
+ value = value.slice(spaceIdx + 1).trim();
1195
+ }
1196
+ }
1197
+ const lower = value.toLowerCase();
1198
+ for (const prefix of KEY_FORMAT_PREFIXES) {
1199
+ if (lower.startsWith(prefix)) {
1200
+ return prefix;
1201
+ }
1202
+ }
1203
+ return void 0;
1204
+ }
1205
+ function isSecretHeader(name) {
1206
+ if (SECRET_HEADER_NAMES.has(name)) return true;
1207
+ if (SECRET_HEADER_PREFIXES.some((p) => name.startsWith(p))) return true;
1208
+ if (isSignatureHeader(name)) return true;
1209
+ return false;
1210
+ }
1211
+ function isPlatformHeader(name) {
1212
+ if (PLATFORM_HEADER_NAMES.has(name)) return true;
1213
+ return PLATFORM_HEADER_PREFIXES.some((p) => name.startsWith(p));
1214
+ }
1215
+ function sanitizeHeaders(raw) {
1216
+ const headers = {};
1217
+ const platformHeaders = {};
1218
+ let apiKeyFormat;
1219
+ let totalBytes = 0;
1220
+ let count = 0;
1221
+ if (!raw) return { headers };
1222
+ for (const rawName of Object.keys(raw)) {
1223
+ if (count >= MAX_HEADERS) break;
1224
+ const name = rawName.toLowerCase();
1225
+ const rawValue = raw[rawName];
1226
+ if (rawValue === void 0) continue;
1227
+ const joined = Array.isArray(rawValue) ? rawValue.join(", ") : String(rawValue);
1228
+ if (CREDENTIAL_HEADER_NAMES.has(name)) {
1229
+ const fmt = extractApiKeyFormat(joined);
1230
+ if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
1231
+ continue;
1232
+ }
1233
+ if (isSecretHeader(name)) continue;
1234
+ let value = joined;
1235
+ if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
1236
+ value = value.slice(0, MAX_HEADER_VALUE_BYTES);
1237
+ }
1238
+ const entryBytes = byteLength(name) + byteLength(value);
1239
+ if (totalBytes + entryBytes > MAX_TOTAL_BYTES) continue;
1240
+ totalBytes += entryBytes;
1241
+ count++;
1242
+ headers[name] = value;
1243
+ if (isPlatformHeader(name)) platformHeaders[name] = value;
1244
+ }
1245
+ const result = { headers };
1246
+ if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
1247
+ if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
1248
+ return result;
1249
+ }
1250
+ function extractPlatformHeaders(sanitized) {
1251
+ const out = {};
1252
+ if (!sanitized) return out;
1253
+ for (const name of Object.keys(sanitized)) {
1254
+ if (isPlatformHeader(name.toLowerCase())) out[name.toLowerCase()] = sanitized[name];
1255
+ }
1256
+ return out;
1257
+ }
1258
+
1079
1259
  // src/adapters/express.ts
1080
1260
  function defaultExtractCredentials(req) {
1081
1261
  return extractCredentials(
@@ -1342,7 +1522,18 @@ function createMiddleware(options) {
1342
1522
  referer: req.headers.referer,
1343
1523
  host: req.headers.host,
1344
1524
  forwardedFor: forwardedForStr,
1345
- agentCardUrl
1525
+ agentCardUrl,
1526
+ // Workstream D — capture EVERY inbound header (SDK-only merchants
1527
+ // have no edge to do it upstream). Local string work, secrets
1528
+ // stripped; out of the verify cache key so it doesn't defeat caching.
1529
+ observedMetadata: (() => {
1530
+ const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(req.headers);
1531
+ return {
1532
+ headers,
1533
+ ...apiKeyFormat && { apiKeyFormat },
1534
+ ...platformHeaders && { platformHeaders }
1535
+ };
1536
+ })()
1346
1537
  }
1347
1538
  };
1348
1539
  let result = await verify(config, verificationRequest);
@@ -1822,7 +2013,18 @@ function createMiddleware2(options) {
1822
2013
  referer: request.headers.get("referer") || void 0,
1823
2014
  host: request.headers.get("host") || void 0,
1824
2015
  forwardedFor,
1825
- agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
2016
+ agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0,
2017
+ // Workstream D — full sanitised header capture (Web Headers → plain map).
2018
+ observedMetadata: (() => {
2019
+ const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(
2020
+ Object.fromEntries(request.headers.entries())
2021
+ );
2022
+ return {
2023
+ headers,
2024
+ ...apiKeyFormat && { apiKeyFormat },
2025
+ ...platformHeaders && { platformHeaders }
2026
+ };
2027
+ })()
1826
2028
  }
1827
2029
  };
1828
2030
  let result = await verify(config, verificationRequest);
@@ -4495,7 +4697,7 @@ async function exportJwkFromKeyLike(keyLike) {
4495
4697
 
4496
4698
  // src/transport/registry/mastercard.ts
4497
4699
  function createMastercardRegistry(options = {}) {
4498
- const cache2 = /* @__PURE__ */ new Map();
4700
+ const cache3 = /* @__PURE__ */ new Map();
4499
4701
  const ttlSec = options.cacheTtlSec ?? 3600;
4500
4702
  const fetchFn = options.fetch ?? globalThis.fetch;
4501
4703
  let warned = false;
@@ -4512,7 +4714,7 @@ function createMastercardRegistry(options = {}) {
4512
4714
  }
4513
4715
  return null;
4514
4716
  }
4515
- const cached = cache2.get(kid);
4717
+ const cached = cache3.get(kid);
4516
4718
  if (cached && cached.expiresAt > Date.now()) return cached.jwk;
4517
4719
  try {
4518
4720
  const res = await fetchFn(options.registryUrl);
@@ -4521,7 +4723,7 @@ function createMastercardRegistry(options = {}) {
4521
4723
  const keys = body.keys ?? [];
4522
4724
  for (const k of keys) {
4523
4725
  if (k.kid === kid) {
4524
- cache2.set(kid, { jwk: k, expiresAt: Date.now() + ttlSec * 1e3 });
4726
+ cache3.set(kid, { jwk: k, expiresAt: Date.now() + ttlSec * 1e3 });
4525
4727
  return k;
4526
4728
  }
4527
4729
  }
@@ -4536,7 +4738,7 @@ function createMastercardRegistry(options = {}) {
4536
4738
  // src/transport/registry/web-bot-auth.ts
4537
4739
  var DIRECTORY_PATH = "/.well-known/http-message-signatures-directory";
4538
4740
  function createWebBotAuthRegistry(options = {}) {
4539
- const cache2 = /* @__PURE__ */ new Map();
4741
+ const cache3 = /* @__PURE__ */ new Map();
4540
4742
  const ttlSec = options.cacheTtlSec ?? 3600;
4541
4743
  const fetchFn = options.fetch ?? globalThis.fetch;
4542
4744
  return {
@@ -4545,7 +4747,7 @@ function createWebBotAuthRegistry(options = {}) {
4545
4747
  if (!kid) return null;
4546
4748
  const directoryUrl = resolveDirectoryUrl(options.directoryUrl, context?.origin);
4547
4749
  if (!directoryUrl) return null;
4548
- const cached = cache2.get(directoryUrl);
4750
+ const cached = cache3.get(directoryUrl);
4549
4751
  const now = Date.now();
4550
4752
  if (cached && cached.expiresAt > now) {
4551
4753
  return findKeyByKid(cached.keys, kid);
@@ -4555,7 +4757,7 @@ function createWebBotAuthRegistry(options = {}) {
4555
4757
  if (!res.ok) return null;
4556
4758
  const body = await res.json();
4557
4759
  const keys = body.keys ?? [];
4558
- cache2.set(directoryUrl, { keys, expiresAt: now + ttlSec * 1e3 });
4760
+ cache3.set(directoryUrl, { keys, expiresAt: now + ttlSec * 1e3 });
4559
4761
  return findKeyByKid(keys, kid);
4560
4762
  } catch {
4561
4763
  return null;
@@ -5724,8 +5926,211 @@ async function recordDecision2(config, params) {
5724
5926
  };
5725
5927
  }
5726
5928
 
5727
- // src/index.ts
5728
- var VERSION = "3.4.0";
5929
+ // src/edge-config.ts
5930
+ var DEFAULT_EDGE_CONFIG = Object.freeze({
5931
+ version: 1,
5932
+ mode: "observe",
5933
+ depth: "classify",
5934
+ pathRules: [],
5935
+ sampling: Object.freeze({ anonymousBeaconRate: 0.1 }),
5936
+ failurePosture: "open"
5937
+ });
5938
+ var EDGE_MODES = ["observe", "enforce"];
5939
+ var EDGE_DEPTHS = ["classify", "authenticate", "authorize"];
5940
+ function isEdgeConfig(value) {
5941
+ if (typeof value !== "object" || value === null) return false;
5942
+ const v = value;
5943
+ if (v.version !== 1) return false;
5944
+ if (!EDGE_MODES.includes(v.mode)) return false;
5945
+ if (!EDGE_DEPTHS.includes(v.depth)) return false;
5946
+ if (!Array.isArray(v.pathRules)) return false;
5947
+ for (const rule of v.pathRules) {
5948
+ if (typeof rule !== "object" || rule === null) return false;
5949
+ const r = rule;
5950
+ if (typeof r.pattern !== "string" || r.pattern.length === 0) return false;
5951
+ if (r.mode !== void 0 && !EDGE_MODES.includes(r.mode)) return false;
5952
+ if (r.depth !== void 0 && !EDGE_DEPTHS.includes(r.depth)) return false;
5953
+ }
5954
+ const sampling = v.sampling;
5955
+ if (typeof sampling !== "object" || sampling === null || typeof sampling.anonymousBeaconRate !== "number" || sampling.anonymousBeaconRate < 0 || sampling.anonymousBeaconRate > 1) {
5956
+ return false;
5957
+ }
5958
+ return v.failurePosture === "open";
5959
+ }
5960
+ async function fetchEdgeConfig(config, counterpartyId, opts) {
5961
+ if (!counterpartyId) return null;
5962
+ const headers = { Accept: "application/json" };
5963
+ if (config.apiKey) {
5964
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
5965
+ headers["X-API-Key"] = config.apiKey;
5966
+ }
5967
+ if (opts?.etag) headers["If-None-Match"] = opts.etag;
5968
+ try {
5969
+ const response = await fetch(
5970
+ `${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/edge-config`,
5971
+ { method: "GET", headers, signal: AbortSignal.timeout(opts?.timeoutMs ?? 5e3) }
5972
+ );
5973
+ if (response.status === 304) return { notModified: true };
5974
+ if (!response.ok) return null;
5975
+ const body = await response.json();
5976
+ const edgeConfig = body.data?.edgeConfig;
5977
+ if (!isEdgeConfig(edgeConfig)) return null;
5978
+ return { edgeConfig, etag: response.headers.get("etag") ?? void 0 };
5979
+ } catch {
5980
+ return null;
5981
+ }
5982
+ }
5983
+ var DEFAULT_TTL_MS = 60 * 1e3;
5984
+ var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
5985
+ var cache2 = /* @__PURE__ */ new Map();
5986
+ var inflight2 = /* @__PURE__ */ new Map();
5987
+ function cacheKey(apiBaseUrl, counterpartyId) {
5988
+ return `${apiBaseUrl}|${counterpartyId}`;
5989
+ }
5990
+ function degradeToObserve(config) {
5991
+ if (config.mode !== "enforce" && !config.pathRules.some((r) => r.mode === "enforce")) {
5992
+ return config;
5993
+ }
5994
+ return {
5995
+ ...config,
5996
+ mode: "observe",
5997
+ pathRules: config.pathRules.map((r) => r.mode === "enforce" ? { ...r, mode: "observe" } : r)
5998
+ };
5999
+ }
6000
+ async function revalidate(config, counterpartyId) {
6001
+ const key = cacheKey(config.apiBaseUrl, counterpartyId);
6002
+ const existing = inflight2.get(key);
6003
+ if (existing) return existing;
6004
+ const promise = fetchEdgeConfig(config, counterpartyId, { etag: cache2.get(key)?.etag }).then((result) => {
6005
+ if (result === null) return;
6006
+ const now = Date.now();
6007
+ if ("notModified" in result) {
6008
+ const entry = cache2.get(key);
6009
+ if (entry) entry.lastSuccessAt = now;
6010
+ return;
6011
+ }
6012
+ cache2.set(key, { config: result.edgeConfig, etag: result.etag, lastSuccessAt: now });
6013
+ }).finally(() => {
6014
+ inflight2.delete(key);
6015
+ });
6016
+ inflight2.set(key, promise);
6017
+ return promise;
6018
+ }
6019
+ async function getEdgeConfig(config, counterpartyId, opts) {
6020
+ const ttlMs = opts?.ttlMs ?? DEFAULT_TTL_MS;
6021
+ const maxStaleMs = opts?.maxStaleMs ?? DEFAULT_MAX_STALE_MS;
6022
+ const key = cacheKey(config.apiBaseUrl, counterpartyId);
6023
+ const entry = cache2.get(key);
6024
+ if (entry) {
6025
+ const age = Date.now() - entry.lastSuccessAt;
6026
+ if (age > ttlMs) {
6027
+ revalidate(config, counterpartyId).catch(() => {
6028
+ });
6029
+ }
6030
+ return age > maxStaleMs ? degradeToObserve(entry.config) : entry.config;
6031
+ }
6032
+ await revalidate(config, counterpartyId).catch(() => {
6033
+ });
6034
+ return cache2.get(key)?.config ?? DEFAULT_EDGE_CONFIG;
6035
+ }
6036
+ function matchEdgePathRule(rules, path) {
6037
+ for (const rule of rules) {
6038
+ if (globToRegExp(rule.pattern).test(path)) return rule;
6039
+ }
6040
+ return void 0;
6041
+ }
6042
+ function globToRegExp(pattern) {
6043
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
6044
+ return new RegExp(`^${escaped}$`, "i");
6045
+ }
6046
+ function _resetEdgeConfigCache() {
6047
+ cache2.clear();
6048
+ inflight2.clear();
6049
+ }
6050
+
6051
+ // src/platform-signatures.ts
6052
+ var PLATFORM_AGENT_SIGNATURES = [
6053
+ {
6054
+ vendor: "claude",
6055
+ displayName: "Anthropic Claude",
6056
+ uaPatterns: [/claude/i, /anthropic/i],
6057
+ agentCardPatterns: [/anthropic\.com/i, /claude\.ai/i],
6058
+ apiKeyFormatPatterns: [/^sk-ant/i],
6059
+ headerPatterns: [/^anthropic-version/i, /^anthropic-beta/i, /^x-anthropic-/i]
6060
+ },
6061
+ {
6062
+ vendor: "chatgpt",
6063
+ displayName: "OpenAI ChatGPT",
6064
+ uaPatterns: [/chatgpt/i, /openai/i, /gpt-?\d/i],
6065
+ agentCardPatterns: [/openai\.com/i, /chatgpt\.com/i],
6066
+ apiKeyFormatPatterns: [/^sk-proj/i, /^sk-svcacct/i],
6067
+ headerPatterns: [/^openai-organization/i, /^openai-project/i, /^openai-version/i]
6068
+ },
6069
+ {
6070
+ vendor: "gemini",
6071
+ displayName: "Google Gemini",
6072
+ uaPatterns: [/gemini/i, /google-gemini/i, /bard/i],
6073
+ agentCardPatterns: [/gemini\.google\.com/i, /ai\.google\.dev/i],
6074
+ apiKeyFormatPatterns: [/^aiza/i],
6075
+ headerPatterns: [/^x-goog-user-project/i, /^x-goog-api-client/i]
6076
+ },
6077
+ {
6078
+ vendor: "cursor",
6079
+ displayName: "Cursor",
6080
+ uaPatterns: [/cursor/i],
6081
+ agentCardPatterns: [/cursor\.sh/i, /cursor\.com/i]
6082
+ },
6083
+ {
6084
+ vendor: "goose",
6085
+ displayName: "Block Goose",
6086
+ uaPatterns: [/goose/i, /block-goose/i],
6087
+ agentCardPatterns: [/block\.xyz\/goose/i, /goose\.tools/i]
6088
+ },
6089
+ {
6090
+ vendor: "perplexity",
6091
+ displayName: "Perplexity",
6092
+ uaPatterns: [/perplexity/i],
6093
+ agentCardPatterns: [/perplexity\.ai/i],
6094
+ apiKeyFormatPatterns: [/^pplx-/i]
6095
+ }
6096
+ ];
6097
+ function matchPlatformSignature(signatures, input) {
6098
+ const ua = input.userAgent ?? "";
6099
+ const cardUrl = input.agentCardUrl ?? "";
6100
+ const apiKeyFormat = input.apiKeyFormat ?? "";
6101
+ const headerLines = [];
6102
+ if (input.platformHeaders) {
6103
+ for (const [name, value] of Object.entries(input.platformHeaders)) {
6104
+ headerLines.push(name, `${name}: ${value}`);
6105
+ }
6106
+ }
6107
+ for (const sig of signatures) {
6108
+ const uaMatch = sig.uaPatterns?.some((p) => p.test(ua));
6109
+ const cardMatch = sig.agentCardPatterns?.some((p) => p.test(cardUrl));
6110
+ const keyMatch = apiKeyFormat.length > 0 && sig.apiKeyFormatPatterns?.some((p) => p.test(apiKeyFormat));
6111
+ const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
6112
+ if (uaMatch || cardMatch || keyMatch || headerMatch) {
6113
+ const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
6114
+ const cardHost = (() => {
6115
+ try {
6116
+ return cardUrl ? new URL(cardUrl).host : "";
6117
+ } catch {
6118
+ return "";
6119
+ }
6120
+ })();
6121
+ const keyBasis = uaBase || cardHost || apiKeyFormat || "unknown";
6122
+ return {
6123
+ vendor: sig.vendor,
6124
+ fingerprintKey: `${sig.vendor}:${keyBasis}`,
6125
+ displayName: sig.displayName
6126
+ };
6127
+ }
6128
+ }
6129
+ return void 0;
6130
+ }
6131
+ function detectPlatformFingerprint(input) {
6132
+ return matchPlatformSignature(PLATFORM_AGENT_SIGNATURES, input);
6133
+ }
5729
6134
  // Annotate the CommonJS export names for ESM import in node:
5730
6135
  0 && (module.exports = {
5731
6136
  ACCESS_LEVEL_DESCRIPTIONS,
@@ -5735,35 +6140,53 @@ var VERSION = "3.4.0";
5735
6140
  AstraSyncError,
5736
6141
  AuthenticationError,
5737
6142
  ChallengeHandler,
6143
+ DEFAULT_EDGE_CONFIG,
5738
6144
  DEFAULT_TRUST_THRESHOLDS,
5739
6145
  KYDRequiredError,
6146
+ MAX_HEADERS,
6147
+ MAX_HEADER_VALUE_BYTES,
6148
+ MAX_TOTAL_BYTES,
6149
+ PLATFORM_AGENT_SIGNATURES,
5740
6150
  RegistrationDeniedError,
5741
6151
  RegistrationExpiredError,
5742
6152
  RegistrationTimeoutError,
5743
6153
  TRUST_LEVEL_RANGES,
5744
6154
  VERSION,
6155
+ _resetEdgeConfigCache,
5745
6156
  agent,
5746
6157
  authorizeSettlement,
5747
6158
  awaitStepUpApproval,
5748
6159
  buildGuidance,
5749
6160
  clearCache,
5750
6161
  createMcpMiddleware,
6162
+ degradeToObserve,
6163
+ detectPlatformFingerprint,
5751
6164
  determineAccessLevel,
5752
6165
  express,
6166
+ extractApiKeyFormat,
5753
6167
  extractCredentials,
5754
6168
  extractMcpCredentials,
6169
+ extractPlatformHeaders,
6170
+ fetchEdgeConfig,
6171
+ fetchRoutes,
5755
6172
  getAccessLevelForScore,
5756
6173
  getCachedWellKnownUrls,
5757
6174
  getCapabilities,
6175
+ getEdgeConfig,
5758
6176
  getTrustLevel,
5759
6177
  getWellKnownUrls,
5760
6178
  hasCredentials,
5761
6179
  hasMinimumAccess,
6180
+ isEdgeConfig,
6181
+ matchEdgePathRule,
6182
+ matchPlatformSignature,
5762
6183
  nextjs,
5763
6184
  pollStepUpStatus,
5764
6185
  prefetchWellKnown,
5765
6186
  quickVerify,
5766
6187
  recordDecision,
6188
+ reportUnregisteredAttempt,
6189
+ sanitizeHeaders,
5767
6190
  sdk,
5768
6191
  setMcpMeta,
5769
6192
  transport,