@astrasyncai/verification-gateway 5.7.0 → 5.9.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.
- package/README.md +37 -1
- package/dist/adapters/express.d.mts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +41 -7
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +41 -7
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.d.ts +1 -1
- package/dist/adapters/mcp.js +2 -2
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +2 -2
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +1 -1
- package/dist/adapters/nextjs.d.ts +1 -1
- package/dist/adapters/nextjs.js +41 -7
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +41 -7
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +1 -1
- package/dist/adapters/sdk.d.ts +1 -1
- package/dist/adapters/sdk.js +2 -2
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +2 -2
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +14 -6
- package/dist/bin/astrasync-codex-hook.js +14 -6
- package/dist/bin/astrasync-guard.js +14 -6
- package/dist/bin/astrasync.js +15 -6
- package/dist/browser/background.js +14 -6
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +14 -6
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +12 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +12 -4
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +14 -6
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +14 -6
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +14 -6
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +14 -6
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +24 -1
- package/dist/edge-config.d.ts +24 -1
- package/dist/edge-config.js +13 -5
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +13 -5
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +14 -6
- package/dist/edge-core/index.d.ts +14 -6
- package/dist/edge-core/index.js +110 -16
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +110 -16
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +14 -6
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +14 -6
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +1 -1
- package/dist/git-trigger/git-hooks.d.ts +1 -1
- package/dist/index.d.mts +80 -6
- package/dist/index.d.ts +80 -6
- package/dist/index.js +54 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +52 -7
- package/dist/index.mjs.map +1 -1
- package/dist/metadata-capture.d.mts +18 -1
- package/dist/metadata-capture.d.ts +18 -1
- package/dist/metadata-capture.js +10 -0
- package/dist/metadata-capture.js.map +1 -1
- package/dist/metadata-capture.mjs +8 -0
- package/dist/metadata-capture.mjs.map +1 -1
- package/dist/platform-signatures.d.mts +1 -1
- package/dist/platform-signatures.d.ts +1 -1
- package/dist/platform-signatures.js +24 -1
- package/dist/platform-signatures.js.map +1 -1
- package/dist/platform-signatures.mjs +24 -1
- package/dist/platform-signatures.mjs.map +1 -1
- package/dist/registration/index.js +1 -1
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +1 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/transport/index.js +1 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +1 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-BK_pRNSs.d.mts → types-CTmUpNpS.d.mts} +25 -2
- package/dist/{types-BK_pRNSs.d.ts → types-CTmUpNpS.d.ts} +25 -2
- package/dist/{types-CwY5IY-0.d.ts → types-CtFXmDzm.d.ts} +17 -2
- package/dist/{types-BCmHFdkJ.d.mts → types-DQrn_kei.d.mts} +17 -2
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +13 -1
- package/dist/verify.d.ts +13 -1
- package/dist/verify.js +2 -2
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +2 -2
- package/dist/verify.mjs.map +1 -1
- package/package.json +3 -3
package/dist/edge-core/index.js
CHANGED
|
@@ -43,7 +43,7 @@ __export(edge_core_exports, {
|
|
|
43
43
|
module.exports = __toCommonJS(edge_core_exports);
|
|
44
44
|
|
|
45
45
|
// src/version.ts
|
|
46
|
-
var SDK_VERSION = "5.
|
|
46
|
+
var SDK_VERSION = "5.9.0";
|
|
47
47
|
|
|
48
48
|
// src/http.ts
|
|
49
49
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -69,7 +69,7 @@ var DEFAULT_EDGE_CONFIG = Object.freeze({
|
|
|
69
69
|
mode: "observe",
|
|
70
70
|
depth: "classify",
|
|
71
71
|
pathRules: [],
|
|
72
|
-
sampling: Object.freeze({ anonymousBeaconRate:
|
|
72
|
+
sampling: Object.freeze({ anonymousBeaconRate: 1 }),
|
|
73
73
|
failurePosture: "open"
|
|
74
74
|
});
|
|
75
75
|
var DEFAULT_TTL_MS = 60 * 1e3;
|
|
@@ -155,6 +155,12 @@ var KEY_FORMAT_PREFIXES = [
|
|
|
155
155
|
var MAX_HEADERS = 64;
|
|
156
156
|
var MAX_HEADER_VALUE_BYTES = 1024;
|
|
157
157
|
var MAX_TOTAL_BYTES = 16 * 1024;
|
|
158
|
+
var DECLARED_SOURCE_MAX = 64;
|
|
159
|
+
var DECLARED_SOURCE_PATTERN = /^[a-z0-9][a-z0-9 ._/-]{0,63}$/;
|
|
160
|
+
function normalizeDeclaredSource(value) {
|
|
161
|
+
const trimmed = value?.trim().slice(0, DECLARED_SOURCE_MAX).toLowerCase();
|
|
162
|
+
return trimmed && DECLARED_SOURCE_PATTERN.test(trimmed) ? trimmed : void 0;
|
|
163
|
+
}
|
|
158
164
|
function byteLength(s) {
|
|
159
165
|
let bytes = 0;
|
|
160
166
|
for (let i = 0; i < s.length; i++) {
|
|
@@ -258,7 +264,20 @@ var PLATFORM_AGENT_SIGNATURES = [
|
|
|
258
264
|
{
|
|
259
265
|
vendor: "gemini",
|
|
260
266
|
displayName: "Google Gemini",
|
|
261
|
-
uaPatterns: [
|
|
267
|
+
uaPatterns: [
|
|
268
|
+
/gemini/i,
|
|
269
|
+
/google-gemini/i,
|
|
270
|
+
/bard/i,
|
|
271
|
+
// Google's AI/agent fetcher tokens (VI uplift 1.3). These are the
|
|
272
|
+
// AI-training/agent crawlers, NOT the Search crawler — googlebot IP
|
|
273
|
+
// ranges attribute Search and are deliberately absent from
|
|
274
|
+
// vendor-ip-ranges. Anchored tokens: none appears in stock browser
|
|
275
|
+
// UAs, and `-` counts as a \b boundary so GoogleOther-Image/-Video
|
|
276
|
+
// match too.
|
|
277
|
+
/\bGoogle-Extended\b/i,
|
|
278
|
+
/\bGoogleOther\b/i,
|
|
279
|
+
/\bGoogle-CloudVertexBot\b/i
|
|
280
|
+
],
|
|
262
281
|
agentCardPatterns: [/gemini\.google\.com/i, /ai\.google\.dev/i],
|
|
263
282
|
apiKeyFormatPatterns: [/^aiza/i],
|
|
264
283
|
headerPatterns: [/^x-goog-user-project/i, /^x-goog-api-client/i]
|
|
@@ -304,6 +323,16 @@ var PLATFORM_AGENT_SIGNATURES = [
|
|
|
304
323
|
uaPatterns: [/\bcomet\/\d/i],
|
|
305
324
|
headerPatterns: [/^sec-ch-ua: .*comet/i]
|
|
306
325
|
},
|
|
326
|
+
// The MCP bridge's own catalog fetches (VI uplift 1.5). Deliberately a
|
|
327
|
+
// DISTINCT UA from `astrasync-sdk/`: bridge fetches are buyer-agent
|
|
328
|
+
// traffic merchants should see (identified · unregistered), so this
|
|
329
|
+
// vendor is kept OUT of the self-traffic filter and the edge's SELF
|
|
330
|
+
// short-circuit.
|
|
331
|
+
{
|
|
332
|
+
vendor: "astrasync-bridge",
|
|
333
|
+
displayName: "AstraSync MCP bridge (buyer-agent catalog fetch)",
|
|
334
|
+
uaPatterns: [/^astrasync-bridge\//i]
|
|
335
|
+
},
|
|
307
336
|
// Our own SDK self-identifies (sdkFetch stamps this UA) — first-party
|
|
308
337
|
// traffic must never pollute the unknown/anonymous pool it exists to audit.
|
|
309
338
|
{
|
|
@@ -834,7 +863,7 @@ async function verify(config, request, options) {
|
|
|
834
863
|
name: apiResponse.agent.name,
|
|
835
864
|
trustScore: apiResponse.agent.trustScore,
|
|
836
865
|
trustLevel: getTrustLevel(apiResponse.agent.trustScore),
|
|
837
|
-
|
|
866
|
+
blockchainAnchored: apiResponse.agent.blockchainStatus === "anchored",
|
|
838
867
|
status: apiResponse.agent.agentStatus
|
|
839
868
|
} : void 0;
|
|
840
869
|
const developer = apiResponse.developer ? {
|
|
@@ -934,10 +963,24 @@ function requestUrl(req, host) {
|
|
|
934
963
|
const qs = req.querystring ? `?${req.querystring}` : "";
|
|
935
964
|
return `https://${host}${req.uri}${qs}`;
|
|
936
965
|
}
|
|
937
|
-
|
|
966
|
+
var ATTEMPT_ID_RE = /^att_[0-9a-f]{32}$/;
|
|
967
|
+
function extractAttemptId(req) {
|
|
968
|
+
const header = headerValue(req, "x-astra-attempt-id");
|
|
969
|
+
if (header && ATTEMPT_ID_RE.test(header)) return header;
|
|
970
|
+
if (req.querystring) {
|
|
971
|
+
try {
|
|
972
|
+
const fromQuery = new URLSearchParams(req.querystring).get("astra_attempt");
|
|
973
|
+
if (fromQuery && ATTEMPT_ID_RE.test(fromQuery)) return fromQuery;
|
|
974
|
+
} catch {
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
return void 0;
|
|
978
|
+
}
|
|
979
|
+
function buildObservedMetadata(req, queryValueAllowlist) {
|
|
938
980
|
const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(req.headers);
|
|
939
981
|
const connection = req.connection ?? {};
|
|
940
982
|
const queryKeys = extractQueryKeys(req.querystring);
|
|
983
|
+
const queryParams = extractAllowlistedQueryParams(req.querystring, queryValueAllowlist);
|
|
941
984
|
return {
|
|
942
985
|
headers,
|
|
943
986
|
...apiKeyFormat && { apiKeyFormat },
|
|
@@ -945,6 +988,7 @@ function buildObservedMetadata(req) {
|
|
|
945
988
|
...Object.keys(connection).length > 0 && { connection },
|
|
946
989
|
...cookieCount !== void 0 && { cookieCount },
|
|
947
990
|
...queryKeys && { queryKeys },
|
|
991
|
+
...queryParams && { queryParams },
|
|
948
992
|
schemaVersion: CAPTURE_SCHEMA_VERSION
|
|
949
993
|
};
|
|
950
994
|
}
|
|
@@ -968,6 +1012,29 @@ function extractQueryKeys(querystring) {
|
|
|
968
1012
|
}
|
|
969
1013
|
return keys.length > 0 ? keys : void 0;
|
|
970
1014
|
}
|
|
1015
|
+
var MAX_QUERY_PARAMS = 16;
|
|
1016
|
+
var MAX_QUERY_VALUE_CHARS = 256;
|
|
1017
|
+
function extractAllowlistedQueryParams(querystring, allowlist) {
|
|
1018
|
+
if (!querystring || !allowlist || allowlist.length === 0) return void 0;
|
|
1019
|
+
let params;
|
|
1020
|
+
try {
|
|
1021
|
+
params = new URLSearchParams(querystring);
|
|
1022
|
+
} catch {
|
|
1023
|
+
return void 0;
|
|
1024
|
+
}
|
|
1025
|
+
const matches = (name) => allowlist.some(
|
|
1026
|
+
(entry) => entry.endsWith("*") ? name.startsWith(entry.slice(0, -1)) : name === entry
|
|
1027
|
+
);
|
|
1028
|
+
const out = {};
|
|
1029
|
+
let count = 0;
|
|
1030
|
+
for (const [key, value] of params.entries()) {
|
|
1031
|
+
const name = key.toLowerCase().slice(0, MAX_QUERY_KEY_CHARS);
|
|
1032
|
+
if (!name || out[name] !== void 0 || !matches(name)) continue;
|
|
1033
|
+
out[name] = value.slice(0, MAX_QUERY_VALUE_CHARS);
|
|
1034
|
+
if (++count >= MAX_QUERY_PARAMS) break;
|
|
1035
|
+
}
|
|
1036
|
+
return count > 0 ? out : void 0;
|
|
1037
|
+
}
|
|
971
1038
|
|
|
972
1039
|
// src/edge-core/detect.ts
|
|
973
1040
|
var SD_JWT_PATTERN = /^eyJ[\w-]+\.[\w-]*\.[\w-]+~/;
|
|
@@ -1127,7 +1194,8 @@ function resolvePolicy(config, path) {
|
|
|
1127
1194
|
return {
|
|
1128
1195
|
mode: rule.mode ?? config.mode,
|
|
1129
1196
|
depth: rule.depth ?? config.depth,
|
|
1130
|
-
skip: rule.skip === true
|
|
1197
|
+
skip: rule.skip === true,
|
|
1198
|
+
...rule.sampling && { sampling: rule.sampling }
|
|
1131
1199
|
};
|
|
1132
1200
|
}
|
|
1133
1201
|
function classify(req, host, depth) {
|
|
@@ -1421,7 +1489,9 @@ async function withBudget(promise, ms) {
|
|
|
1421
1489
|
if (timer) clearTimeout(timer);
|
|
1422
1490
|
}
|
|
1423
1491
|
}
|
|
1424
|
-
async function emitBeacon(options, req, classification, budgetMs) {
|
|
1492
|
+
async function emitBeacon(options, req, classification, budgetMs, queryValueAllowlist) {
|
|
1493
|
+
const attemptId = extractAttemptId(req);
|
|
1494
|
+
const declaredSource = normalizeDeclaredSource(headerValue(req, "x-astra-source"));
|
|
1425
1495
|
const budgeted = withBudget(
|
|
1426
1496
|
reportUnregisteredAttempt(
|
|
1427
1497
|
{ apiBaseUrl: options.apiBaseUrl, counterpartyId: options.counterpartyId },
|
|
@@ -1432,12 +1502,20 @@ async function emitBeacon(options, req, classification, budgetMs) {
|
|
|
1432
1502
|
userAgent: headerValue(req, "user-agent"),
|
|
1433
1503
|
requestPath: req.uri,
|
|
1434
1504
|
requestMethod: req.method,
|
|
1505
|
+
// Attempt-chain handle (header or ?astra_attempt= deep link) — joins
|
|
1506
|
+
// this beacon into the agent's research chain via pe_attempt_idx.
|
|
1507
|
+
...attemptId && { attemptId },
|
|
1508
|
+
// First-class referer + accept: traffic-source and surface-classifier
|
|
1509
|
+
// inputs (previously buried inside observedMetadata.headers).
|
|
1510
|
+
referer: headerValue(req, "referer"),
|
|
1511
|
+
accept: headerValue(req, "accept"),
|
|
1512
|
+
...declaredSource && { declaredSource },
|
|
1435
1513
|
// Evidence fields the backend persists into the event record.
|
|
1436
1514
|
protocol: classification.protocol,
|
|
1437
1515
|
evidence: classification.evidence,
|
|
1438
1516
|
// The full sanitized header + connection capture for the
|
|
1439
1517
|
// unregistered caller (fire-and-forget, so free).
|
|
1440
|
-
observedMetadata: buildObservedMetadata(req)
|
|
1518
|
+
observedMetadata: buildObservedMetadata(req, queryValueAllowlist)
|
|
1441
1519
|
}
|
|
1442
1520
|
),
|
|
1443
1521
|
budgetMs
|
|
@@ -1463,13 +1541,14 @@ function baseOutcome(classification) {
|
|
|
1463
1541
|
protocol: classification.protocol
|
|
1464
1542
|
};
|
|
1465
1543
|
}
|
|
1466
|
-
function buildVerificationRequest(options, req, classification, includeArtifacts) {
|
|
1544
|
+
function buildVerificationRequest(options, req, classification, includeArtifacts, queryValueAllowlist) {
|
|
1467
1545
|
const pdlss = resolveHttpPdlss({
|
|
1468
1546
|
method: req.method,
|
|
1469
1547
|
astraPurpose: headerValue(req, "x-astra-purpose"),
|
|
1470
1548
|
astraAction: headerValue(req, "x-astra-action")
|
|
1471
1549
|
});
|
|
1472
1550
|
const attemptId = headerValue(req, "x-astra-attempt-id");
|
|
1551
|
+
const declaredSource = normalizeDeclaredSource(headerValue(req, "x-astra-source"));
|
|
1473
1552
|
return {
|
|
1474
1553
|
...attemptId && /^att_[0-9a-f]{32}$/.test(attemptId) && { attemptId },
|
|
1475
1554
|
credentials: extractCredentials(req.headers, {}),
|
|
@@ -1484,10 +1563,11 @@ function buildVerificationRequest(options, req, classification, includeArtifacts
|
|
|
1484
1563
|
userAgent: headerValue(req, "user-agent"),
|
|
1485
1564
|
referer: headerValue(req, "referer"),
|
|
1486
1565
|
host: headerValue(req, "host"),
|
|
1566
|
+
...declaredSource && { declaredSource },
|
|
1487
1567
|
// The full sanitized header + connection capture. The backend stores
|
|
1488
1568
|
// it fire-and-forget (zero decision latency) and uses the key-format
|
|
1489
1569
|
// / platform headers for attribution.
|
|
1490
|
-
observedMetadata: buildObservedMetadata(req)
|
|
1570
|
+
observedMetadata: buildObservedMetadata(req, queryValueAllowlist)
|
|
1491
1571
|
},
|
|
1492
1572
|
...includeArtifacts && classification.artifacts && { commerceArtifacts: classification.artifacts }
|
|
1493
1573
|
};
|
|
@@ -1534,7 +1614,8 @@ function unavailableOutcome(classification, policy, reason, correlationId) {
|
|
|
1534
1614
|
function isApiErrorResult(result) {
|
|
1535
1615
|
return (result.failures ?? []).some((f) => f.dimension === "verify_access.api_error") === true && !result.misconfigured;
|
|
1536
1616
|
}
|
|
1537
|
-
async function runTier(options, req, classification, policy, apiKey,
|
|
1617
|
+
async function runTier(options, req, classification, policy, apiKey, capture) {
|
|
1618
|
+
const { sampling, queryValueAllowlist } = capture;
|
|
1538
1619
|
const budgets = options.budgets ?? {};
|
|
1539
1620
|
const beaconMs = budgets.beaconMs ?? 300;
|
|
1540
1621
|
const verifyMs = policy.mode === "enforce" ? budgets.verifyEnforceMs ?? 3e3 : budgets.verifyObserveMs ?? 1500;
|
|
@@ -1555,7 +1636,13 @@ async function runTier(options, req, classification, policy, apiKey, sampling) {
|
|
|
1555
1636
|
const result = await withBudget(
|
|
1556
1637
|
verify(
|
|
1557
1638
|
gatewayConfig,
|
|
1558
|
-
buildVerificationRequest(
|
|
1639
|
+
buildVerificationRequest(
|
|
1640
|
+
options,
|
|
1641
|
+
req,
|
|
1642
|
+
classification,
|
|
1643
|
+
policy.depth === "authorize",
|
|
1644
|
+
queryValueAllowlist
|
|
1645
|
+
)
|
|
1559
1646
|
),
|
|
1560
1647
|
verifyMs
|
|
1561
1648
|
);
|
|
@@ -1579,7 +1666,10 @@ async function runTier(options, req, classification, policy, apiKey, sampling) {
|
|
|
1579
1666
|
case "identified": {
|
|
1580
1667
|
if (policy.depth === "authorize" && classification.artifacts) {
|
|
1581
1668
|
const result = await withBudget(
|
|
1582
|
-
verify(
|
|
1669
|
+
verify(
|
|
1670
|
+
gatewayConfig,
|
|
1671
|
+
buildVerificationRequest(options, req, classification, true, queryValueAllowlist)
|
|
1672
|
+
),
|
|
1583
1673
|
verifyMs
|
|
1584
1674
|
);
|
|
1585
1675
|
if (!result) {
|
|
@@ -1599,7 +1689,7 @@ async function runTier(options, req, classification, policy, apiKey, sampling) {
|
|
|
1599
1689
|
}
|
|
1600
1690
|
return outcomeFromVerifyResult(classification, result);
|
|
1601
1691
|
}
|
|
1602
|
-
await emitBeacon(options, req, classification, beaconMs);
|
|
1692
|
+
await emitBeacon(options, req, classification, beaconMs, queryValueAllowlist);
|
|
1603
1693
|
const outcome = baseOutcome(classification);
|
|
1604
1694
|
if (policy.mode === "enforce" && policy.depth !== "classify") {
|
|
1605
1695
|
outcome.decision = "deny";
|
|
@@ -1613,7 +1703,8 @@ async function runTier(options, req, classification, policy, apiKey, sampling) {
|
|
|
1613
1703
|
options,
|
|
1614
1704
|
req,
|
|
1615
1705
|
{ ...classification, protocol: classification.protocol ?? "ua-heuristic" },
|
|
1616
|
-
beaconMs
|
|
1706
|
+
beaconMs,
|
|
1707
|
+
queryValueAllowlist
|
|
1617
1708
|
);
|
|
1618
1709
|
}
|
|
1619
1710
|
return baseOutcome(classification);
|
|
@@ -1640,7 +1731,10 @@ async function evaluateEdgeRequest(options, req, config, apiKey) {
|
|
|
1640
1731
|
if (classification.tier === "human" || classification.tier === "self") {
|
|
1641
1732
|
return { policy, classification, application: passUntouched() };
|
|
1642
1733
|
}
|
|
1643
|
-
const outcome = await runTier(options, req, classification, policy, apiKey,
|
|
1734
|
+
const outcome = await runTier(options, req, classification, policy, apiKey, {
|
|
1735
|
+
sampling: policy.sampling ?? config.sampling,
|
|
1736
|
+
queryValueAllowlist: config.queryValueAllowlist
|
|
1737
|
+
});
|
|
1644
1738
|
if (outcome.decision !== "allow") {
|
|
1645
1739
|
options.log?.(
|
|
1646
1740
|
"info",
|