@astrasyncai/verification-gateway 4.3.0 → 4.5.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/dist/adapters/express.js +104 -28
  2. package/dist/adapters/express.js.map +1 -1
  3. package/dist/adapters/express.mjs +104 -28
  4. package/dist/adapters/express.mjs.map +1 -1
  5. package/dist/adapters/mcp.js +63 -21
  6. package/dist/adapters/mcp.js.map +1 -1
  7. package/dist/adapters/mcp.mjs +63 -21
  8. package/dist/adapters/mcp.mjs.map +1 -1
  9. package/dist/adapters/nextjs.js +103 -27
  10. package/dist/adapters/nextjs.js.map +1 -1
  11. package/dist/adapters/nextjs.mjs +103 -27
  12. package/dist/adapters/nextjs.mjs.map +1 -1
  13. package/dist/adapters/sdk.js +33 -12
  14. package/dist/adapters/sdk.js.map +1 -1
  15. package/dist/adapters/sdk.mjs +33 -12
  16. package/dist/adapters/sdk.mjs.map +1 -1
  17. package/dist/agent/index.js +24 -3
  18. package/dist/agent/index.js.map +1 -1
  19. package/dist/agent/index.mjs +24 -3
  20. package/dist/agent/index.mjs.map +1 -1
  21. package/dist/bin/astrasync-claude-hook.js +31 -10
  22. package/dist/bin/astrasync-codex-hook.js +31 -10
  23. package/dist/bin/astrasync-guard.js +35 -14
  24. package/dist/bin/astrasync.js +75 -29
  25. package/dist/browser/background.js +31 -10
  26. package/dist/browser/background.js.map +1 -1
  27. package/dist/browser/background.mjs +31 -10
  28. package/dist/browser/background.mjs.map +1 -1
  29. package/dist/cli/index.js +23 -2
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/cli/index.mjs +23 -2
  32. package/dist/cli/index.mjs.map +1 -1
  33. package/dist/codex/index.js +31 -10
  34. package/dist/codex/index.js.map +1 -1
  35. package/dist/codex/index.mjs +31 -10
  36. package/dist/codex/index.mjs.map +1 -1
  37. package/dist/cursor/extension.js +31 -10
  38. package/dist/cursor/extension.js.map +1 -1
  39. package/dist/cursor/extension.mjs +31 -10
  40. package/dist/cursor/extension.mjs.map +1 -1
  41. package/dist/edge-config.d.mts +11 -4
  42. package/dist/edge-config.d.ts +11 -4
  43. package/dist/edge-config.js +24 -1
  44. package/dist/edge-config.js.map +1 -1
  45. package/dist/edge-config.mjs +22 -1
  46. package/dist/edge-config.mjs.map +1 -1
  47. package/dist/edge-core/index.d.mts +21 -7
  48. package/dist/edge-core/index.d.ts +21 -7
  49. package/dist/edge-core/index.js +170 -25
  50. package/dist/edge-core/index.js.map +1 -1
  51. package/dist/edge-core/index.mjs +170 -25
  52. package/dist/edge-core/index.mjs.map +1 -1
  53. package/dist/gateway/gateway.js +31 -10
  54. package/dist/gateway/gateway.js.map +1 -1
  55. package/dist/gateway/gateway.mjs +31 -10
  56. package/dist/gateway/gateway.mjs.map +1 -1
  57. package/dist/index.d.mts +51 -2
  58. package/dist/index.d.ts +51 -2
  59. package/dist/index.js +169 -40
  60. package/dist/index.js.map +1 -1
  61. package/dist/index.mjs +165 -40
  62. package/dist/index.mjs.map +1 -1
  63. package/dist/metadata-capture.d.mts +17 -0
  64. package/dist/metadata-capture.d.ts +17 -0
  65. package/dist/metadata-capture.js +25 -4
  66. package/dist/metadata-capture.js.map +1 -1
  67. package/dist/metadata-capture.mjs +25 -4
  68. package/dist/metadata-capture.mjs.map +1 -1
  69. package/dist/platform-signatures.d.mts +18 -1
  70. package/dist/platform-signatures.d.ts +18 -1
  71. package/dist/platform-signatures.js +35 -2
  72. package/dist/platform-signatures.js.map +1 -1
  73. package/dist/platform-signatures.mjs +35 -2
  74. package/dist/platform-signatures.mjs.map +1 -1
  75. package/dist/registration/index.js +25 -4
  76. package/dist/registration/index.js.map +1 -1
  77. package/dist/registration/index.mjs +25 -4
  78. package/dist/registration/index.mjs.map +1 -1
  79. package/dist/transport/index.js +22 -1
  80. package/dist/transport/index.js.map +1 -1
  81. package/dist/transport/index.mjs +22 -1
  82. package/dist/transport/index.mjs.map +1 -1
  83. package/dist/verify.js +38 -17
  84. package/dist/verify.js.map +1 -1
  85. package/dist/verify.mjs +38 -17
  86. package/dist/verify.mjs.map +1 -1
  87. package/package.json +2 -2
@@ -1,3 +1,24 @@
1
+ // src/version.ts
2
+ var SDK_VERSION = "4.5.0";
3
+
4
+ // src/http.ts
5
+ var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
6
+ function withUserAgent(initHeaders) {
7
+ if (!initHeaders) return { "user-agent": SDK_USER_AGENT };
8
+ if (initHeaders instanceof Headers) {
9
+ const copy = new Headers(initHeaders);
10
+ if (!copy.has("user-agent")) copy.set("user-agent", SDK_USER_AGENT);
11
+ return copy;
12
+ }
13
+ if (Array.isArray(initHeaders)) {
14
+ const has2 = initHeaders.some(([name]) => name.toLowerCase() === "user-agent");
15
+ return has2 ? initHeaders : [...initHeaders, ["user-agent", SDK_USER_AGENT]];
16
+ }
17
+ const has = Object.keys(initHeaders).some((name) => name.toLowerCase() === "user-agent");
18
+ return has ? initHeaders : { "user-agent": SDK_USER_AGENT, ...initHeaders };
19
+ }
20
+ var sdkFetch = (input, init) => fetch(input, { ...init, headers: withUserAgent(init?.headers) });
21
+
1
22
  // src/adapters/stepup-poll.ts
2
23
  var DEFAULT_POLL_INTERVAL_MS = 3e3;
3
24
  var MIN_POLL_INTERVAL_MS = 250;
@@ -12,7 +33,7 @@ function resolvePollUrl(config, pollUrl) {
12
33
  async function pollStepUpStatus(config, approval) {
13
34
  if (!approval.pollUrl) return null;
14
35
  try {
15
- const res = await fetch(resolvePollUrl(config, approval.pollUrl), {
36
+ const res = await sdkFetch(resolvePollUrl(config, approval.pollUrl), {
16
37
  method: "GET",
17
38
  signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS)
18
39
  });
@@ -64,9 +85,6 @@ function getTrustLevel(score) {
64
85
  return "BRONZE";
65
86
  }
66
87
 
67
- // src/version.ts
68
- var SDK_VERSION = "4.1.0";
69
-
70
88
  // src/well-known.ts
71
89
  var CACHE_TTL_MS = 60 * 60 * 1e3;
72
90
  var cache = /* @__PURE__ */ new Map();
@@ -77,7 +95,7 @@ function wellKnownUrl(apiBaseUrl) {
77
95
  }
78
96
  async function fetchWellKnown(apiBaseUrl) {
79
97
  const url = wellKnownUrl(apiBaseUrl);
80
- const response = await fetch(url, {
98
+ const response = await sdkFetch(url, {
81
99
  method: "GET",
82
100
  headers: { Accept: "application/json" },
83
101
  signal: AbortSignal.timeout(5e3)
@@ -147,7 +165,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
147
165
  initCheckPerformed = true;
148
166
  try {
149
167
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
150
- const response = await fetch(probeUrl, { method: "HEAD" });
168
+ const response = await sdkFetch(probeUrl, { method: "HEAD" });
151
169
  const contentType = response.headers.get("content-type") ?? "";
152
170
  if (contentType.startsWith("text/html")) {
153
171
  const message = `[VerificationGateway] apiBaseUrl '${apiBaseUrl}' returned HTML (content-type: ${contentType}). This usually means apiBaseUrl is pointing at a marketing site instead of the API. Expected: 'https://astrasync.ai/api' (prod) or 'https://staging.astrasync.ai/api' (staging).`;
@@ -161,7 +179,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
161
179
  );
162
180
  }
163
181
  if (apiKey) {
164
- const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
182
+ const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
165
183
  headers: { Authorization: `Bearer ${apiKey}` }
166
184
  });
167
185
  if (selfCheck.status === 401) {
@@ -408,7 +426,7 @@ async function callVerifyAccessAPI(config, request) {
408
426
  headers["X-API-Key"] = config.apiKey;
409
427
  }
410
428
  try {
411
- const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
429
+ const response = await sdkFetch(`${config.apiBaseUrl}/agents/verify-access`, {
412
430
  method: "POST",
413
431
  headers,
414
432
  body: JSON.stringify(body),
@@ -590,12 +608,15 @@ async function verify(config, request, options) {
590
608
  const verificationContext = apiResponse.verificationContext;
591
609
  const accessLevel = apiResponse.access?.accessLevel ?? "standard";
592
610
  const result = {
593
- // Round-18 G4: backend allowed access. Identity is verified (we resolved
594
- // the caller to an agent) and policy passed all gates. Read idVerified
595
- // from verificationContext for symmetry with the deny branch; default true
596
- // on success path since `access.allowed === true` implies identity was
597
- // resolvable (anonymous-allow paths flow through createGuidanceResponse).
598
- identityVerified: apiResponse.verificationContext?.idVerified !== false,
611
+ // 4.5.0 (probe F1): read idVerified from verificationContext with the
612
+ // SAME absent⇒false default as the deny branch. The previous `!== false`
613
+ // default manufactured `identityVerified: true` for anonymous
614
+ // allow_full/allow_partial/audit responses (which allow access but omit
615
+ // verificationContext entirely) — the "anonymous caller labelled
616
+ // verified" defect. Every authenticated success response has carried
617
+ // `verificationContext.idVerified: true` since v2.2.4, so a truth claim
618
+ // this load-bearing must never be defaulted on.
619
+ identityVerified: apiResponse.verificationContext?.idVerified === true,
599
620
  policyAllowed: true,
600
621
  accessLevel,
601
622
  agent,
@@ -651,7 +672,7 @@ async function recordDecision(config, sessionId, decision, reason) {
651
672
  headers["Authorization"] = `Bearer ${config.apiKey}`;
652
673
  headers["X-API-Key"] = config.apiKey;
653
674
  }
654
- await fetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
675
+ await sdkFetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
655
676
  method: "POST",
656
677
  headers,
657
678
  body: JSON.stringify({ decision, reason })
@@ -666,7 +687,7 @@ async function fetchRoutes(config, counterpartyId) {
666
687
  headers["X-API-Key"] = config.apiKey;
667
688
  }
668
689
  try {
669
- const response = await fetch(
690
+ const response = await sdkFetch(
670
691
  `${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,
671
692
  { method: "GET", headers }
672
693
  );
@@ -685,7 +706,7 @@ async function reportUnregisteredAttempt(config, data) {
685
706
  ...counterpartyUrl && { counterpartyUrl },
686
707
  ...config.counterpartyId && { counterpartyId: config.counterpartyId }
687
708
  };
688
- await fetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
709
+ await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
689
710
  method: "POST",
690
711
  headers: { "Content-Type": "application/json" },
691
712
  body: JSON.stringify(body)
@@ -694,7 +715,7 @@ async function reportUnregisteredAttempt(config, data) {
694
715
  }
695
716
  async function reportCounterpartyPreCheckFailure(config, data) {
696
717
  const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
697
- await fetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {
718
+ await sdkFetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {
698
719
  method: "POST",
699
720
  headers: { "Content-Type": "application/json" },
700
721
  body: JSON.stringify(data)
@@ -950,7 +971,13 @@ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
950
971
  "x-agent-card-url",
951
972
  "x-agent-provider"
952
973
  ]);
953
- var PLATFORM_HEADER_PREFIXES = ["x-goog-", "x-stainless-", "x-anthropic-", "x-openai-"];
974
+ var PLATFORM_HEADER_PREFIXES = [
975
+ "x-goog-",
976
+ "x-stainless-",
977
+ "x-anthropic-",
978
+ "x-openai-",
979
+ "sec-ch-"
980
+ ];
954
981
  var KEY_FORMAT_PREFIXES = [
955
982
  "sk-ant-api03",
956
983
  "sk-ant-api",
@@ -1022,6 +1049,7 @@ function sanitizeHeaders(raw) {
1022
1049
  const headers = {};
1023
1050
  const platformHeaders = {};
1024
1051
  let apiKeyFormat;
1052
+ let cookieCount;
1025
1053
  let totalBytes = 0;
1026
1054
  let count = 0;
1027
1055
  if (!raw) return { headers };
@@ -1036,6 +1064,9 @@ function sanitizeHeaders(raw) {
1036
1064
  if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
1037
1065
  continue;
1038
1066
  }
1067
+ if (name === "cookie") {
1068
+ cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
1069
+ }
1039
1070
  if (isSecretHeader(name)) continue;
1040
1071
  let value = joined;
1041
1072
  if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
@@ -1051,6 +1082,7 @@ function sanitizeHeaders(raw) {
1051
1082
  const result = { headers };
1052
1083
  if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
1053
1084
  if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
1085
+ if (cookieCount !== void 0) result.cookieCount = cookieCount;
1054
1086
  return result;
1055
1087
  }
1056
1088
  var CONNECTION_HEADER_SOURCES = [
@@ -1062,6 +1094,9 @@ var CONNECTION_HEADER_SOURCES = [
1062
1094
  ["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
1063
1095
  ["countryRegionName", ["cloudfront-viewer-country-region-name"]],
1064
1096
  ["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
1097
+ ["latitude", ["x-vercel-ip-latitude", "cloudfront-viewer-latitude"]],
1098
+ ["longitude", ["x-vercel-ip-longitude", "cloudfront-viewer-longitude"]],
1099
+ ["postalCode", ["x-vercel-ip-postal-code", "cloudfront-viewer-postal-code"]],
1065
1100
  ["asn", ["cloudfront-viewer-asn"]],
1066
1101
  ["tlsVersion", ["cloudfront-viewer-tls"]],
1067
1102
  ["httpVersion", ["cloudfront-viewer-http-version"]],
@@ -1096,19 +1131,25 @@ function deriveConnectionFromHeaders(headers) {
1096
1131
  }
1097
1132
  }
1098
1133
  }
1099
- if (!connection.ip) {
1134
+ {
1100
1135
  const addr = lower["cloudfront-viewer-address"]?.trim();
1101
- if (addr) connection.ip = addr.replace(/:\d+$/, "");
1136
+ const portMatch = addr?.match(/:(\d+)$/);
1137
+ if (portMatch) connection.sourcePort = portMatch[1];
1138
+ if (!connection.ip && addr) connection.ip = addr.replace(/:\d+$/, "");
1102
1139
  }
1103
1140
  if (!connection.ip) {
1104
1141
  const xff = lower["x-forwarded-for"];
1105
1142
  const client = xff?.split(",")[0]?.trim();
1106
1143
  if (client) connection.ip = client;
1107
1144
  }
1145
+ if (!connection.tlsCipher) {
1146
+ const cipher = connection.tlsVersion?.split(":")[1];
1147
+ if (cipher) connection.tlsCipher = cipher;
1148
+ }
1108
1149
  return Object.keys(connection).length > 0 ? connection : void 0;
1109
1150
  }
1110
1151
  function buildSdkObservedMetadata(rawHeaders) {
1111
- const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(rawHeaders);
1152
+ const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(rawHeaders);
1112
1153
  const flat = {};
1113
1154
  if (rawHeaders) {
1114
1155
  for (const name of Object.keys(rawHeaders)) {
@@ -1123,6 +1164,7 @@ function buildSdkObservedMetadata(rawHeaders) {
1123
1164
  ...apiKeyFormat && { apiKeyFormat },
1124
1165
  ...platformHeaders && { platformHeaders },
1125
1166
  ...connection && { connection },
1167
+ ...cookieCount !== void 0 && { cookieCount },
1126
1168
  schemaVersion: CAPTURE_SCHEMA_VERSION
1127
1169
  };
1128
1170
  }
@@ -1167,7 +1209,7 @@ async function fetchEdgeConfig(config, counterpartyId, opts) {
1167
1209
  }
1168
1210
  if (opts?.etag) headers["If-None-Match"] = opts.etag;
1169
1211
  try {
1170
- const response = await fetch(
1212
+ const response = await sdkFetch(
1171
1213
  `${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/edge-config`,
1172
1214
  { method: "GET", headers, signal: AbortSignal.timeout(opts?.timeoutMs ?? 5e3) }
1173
1215
  );
@@ -1279,12 +1321,43 @@ var PLATFORM_AGENT_SIGNATURES = [
1279
1321
  uaPatterns: [/perplexity/i],
1280
1322
  agentCardPatterns: [/perplexity\.ai/i],
1281
1323
  apiKeyFormatPatterns: [/^pplx-/i]
1324
+ },
1325
+ // Agentic browsers — versioned-token patterns ONLY (a stock Chrome UA must
1326
+ // never match). Distinct vendor keys (not 'chatgpt'/'perplexity'): the
1327
+ // browser product is a different surface than the assistant service, and
1328
+ // the DB registry mirrors one row per vendor. These sit after the primary
1329
+ // vendor entries so a UA carrying an explicit vendor token keeps its
1330
+ // primary attribution; a browser-shaped UA with the agentic token is
1331
+ // caught here BEFORE classify's human tier, which is what makes these
1332
+ // visits observable at all. Token drift is real (some builds mimic Chrome
1333
+ // outright) — re-verify against captured events when a new browser ships,
1334
+ // and check `sec-ch-ua` platformHeaders for the real brand.
1335
+ {
1336
+ vendor: "chatgpt-atlas",
1337
+ displayName: "ChatGPT Atlas browser",
1338
+ uaPatterns: [/\batlas\/\d/i],
1339
+ headerPatterns: [/^sec-ch-ua: .*atlas/i]
1340
+ },
1341
+ {
1342
+ vendor: "perplexity-comet",
1343
+ displayName: "Perplexity Comet browser",
1344
+ uaPatterns: [/\bcomet\/\d/i],
1345
+ headerPatterns: [/^sec-ch-ua: .*comet/i]
1346
+ },
1347
+ // Our own SDK self-identifies (sdkFetch stamps this UA) — first-party
1348
+ // traffic must never pollute the unknown/anonymous pool it exists to audit.
1349
+ {
1350
+ vendor: "astrasync-sdk",
1351
+ displayName: "AstraSync SDK",
1352
+ uaPatterns: [/^astrasync-sdk\//i]
1282
1353
  }
1283
1354
  ];
1284
1355
  function matchPlatformSignature(signatures, input) {
1285
1356
  const ua = input.userAgent ?? "";
1286
1357
  const cardUrl = input.agentCardUrl ?? "";
1287
1358
  const apiKeyFormat = input.apiKeyFormat ?? "";
1359
+ const ja4 = input.ja4 ?? "";
1360
+ const asn = input.asn ?? "";
1288
1361
  const headerLines = [];
1289
1362
  if (input.platformHeaders) {
1290
1363
  for (const [name, value] of Object.entries(input.platformHeaders)) {
@@ -1296,7 +1369,9 @@ function matchPlatformSignature(signatures, input) {
1296
1369
  const cardMatch = sig.agentCardPatterns?.some((p) => p.test(cardUrl));
1297
1370
  const keyMatch = apiKeyFormat.length > 0 && sig.apiKeyFormatPatterns?.some((p) => p.test(apiKeyFormat));
1298
1371
  const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
1299
- if (uaMatch || cardMatch || keyMatch || headerMatch) {
1372
+ const ja4Match = ja4.length > 0 && sig.ja4Patterns?.some((p) => p.test(ja4));
1373
+ const asnMatch = asn.length > 0 && sig.asnList?.includes(asn);
1374
+ if (uaMatch || cardMatch || keyMatch || headerMatch || ja4Match || asnMatch) {
1300
1375
  const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
1301
1376
  const cardHost = (() => {
1302
1377
  try {
@@ -1305,7 +1380,7 @@ function matchPlatformSignature(signatures, input) {
1305
1380
  return "";
1306
1381
  }
1307
1382
  })();
1308
- const keyBasis = uaBase || cardHost || apiKeyFormat || "unknown";
1383
+ const keyBasis = uaBase || cardHost || apiKeyFormat || ja4 || asn && `asn${asn}` || "unknown";
1309
1384
  return {
1310
1385
  vendor: sig.vendor,
1311
1386
  fingerprintKey: `${sig.vendor}:${keyBasis}`,
@@ -1321,9 +1396,10 @@ function detectPlatformFingerprint(input) {
1321
1396
 
1322
1397
  // src/edge-core/classify.ts
1323
1398
  var STATIC_EXTENSIONS = /\.(css|js|mjs|map|png|jpe?g|gif|webp|avif|svg|ico|woff2?|ttf|otf|eot|mp4|webm|pdf|txt|xml)$/i;
1399
+ var SELF_UA_PATTERN = /^astrasync-sdk\//i;
1324
1400
  var BOT_UA_PATTERN = /curl|wget|python-requests|python-urllib|node-fetch|axios|got|okhttp|go-http-client|libwww|httpie|java\/|ruby|php|scrapy|headless|phantomjs|selenium|playwright|puppeteer|bot|crawler|spider|slurp/i;
1325
1401
  var BROWSER_UA_PATTERN = /mozilla\/\d/i;
1326
- var _patterns = { STATIC_EXTENSIONS, BOT_UA_PATTERN, BROWSER_UA_PATTERN };
1402
+ var _patterns = { STATIC_EXTENSIONS, BOT_UA_PATTERN, BROWSER_UA_PATTERN, SELF_UA_PATTERN };
1327
1403
 
1328
1404
  // src/edge-core/events.ts
1329
1405
  function sampled(rate, random = Math.random) {
@@ -1743,7 +1819,7 @@ function createMiddleware(options) {
1743
1819
  let result = await verify(config, verificationRequest);
1744
1820
  req.agentVerification = result;
1745
1821
  let sessionId = result.sessionId;
1746
- if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
1822
+ if (config.stepUpMaxWaitMs !== void 0 && result.policyAllowed && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
1747
1823
  const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
1748
1824
  res.setHeader("X-Astra-Step-Up", outcome);
1749
1825
  if (outcome === "approved") {
@@ -1754,7 +1830,7 @@ function createMiddleware(options) {
1754
1830
  result.stepUpOutcome = outcome;
1755
1831
  }
1756
1832
  }
1757
- if (!result.identityVerified || !result.policyAllowed) {
1833
+ if (!result.policyAllowed) {
1758
1834
  if (shouldRecordDecisions && sessionId) {
1759
1835
  recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
1760
1836
  });