@astrasyncai/verification-gateway 5.18.1 → 5.19.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/CHANGELOG.md +149 -0
- package/README.md +168 -4
- package/dist/adapters/express.d.mts +9 -1
- package/dist/adapters/express.d.ts +9 -1
- package/dist/adapters/express.js +96 -37
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +96 -37
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/http-pdlss.d.mts +7 -1
- package/dist/adapters/http-pdlss.d.ts +7 -1
- package/dist/adapters/http-pdlss.js +18 -2
- package/dist/adapters/http-pdlss.js.map +1 -1
- package/dist/adapters/http-pdlss.mjs +16 -1
- package/dist/adapters/http-pdlss.mjs.map +1 -1
- package/dist/adapters/kit-express.d.mts +93 -1
- package/dist/adapters/kit-express.d.ts +93 -1
- package/dist/adapters/kit-express.js +181 -2
- package/dist/adapters/kit-express.js.map +1 -1
- package/dist/adapters/kit-express.mjs +180 -2
- package/dist/adapters/kit-express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +80 -9
- package/dist/adapters/mcp.d.ts +80 -9
- package/dist/adapters/mcp.js +153 -5
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +151 -5
- 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 -4
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +41 -4
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +44 -1
- package/dist/adapters/sdk.d.ts +44 -1
- package/dist/adapters/sdk.js +76 -2
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +76 -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 +46 -6
- package/dist/bin/astrasync-codex-hook.js +46 -6
- package/dist/bin/astrasync-guard.js +46 -6
- package/dist/bin/astrasync.js +77 -5
- package/dist/browser/background.js +46 -6
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +46 -6
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +46 -6
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +46 -6
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +46 -6
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +46 -6
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/edge-config.js +1 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +1 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +1 -1
- package/dist/edge-core/index.d.ts +1 -1
- package/dist/edge-core/index.js +21 -2
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +21 -2
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +46 -6
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +46 -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 +541 -29
- package/dist/index.d.ts +541 -29
- package/dist/index.js +1171 -183
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1157 -173
- package/dist/index.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 +3 -2
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +3 -2
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-3ObBpsnf.d.mts → types-BoGjyon0.d.mts} +81 -2
- package/dist/{types-Cns4l8gX.d.mts → types-DqWPkiYl.d.mts} +90 -12
- package/dist/{types-Cns4l8gX.d.ts → types-DqWPkiYl.d.ts} +90 -12
- package/dist/{types-BoxZEYPS.d.ts → types-eWyZuz-3.d.ts} +81 -2
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +23 -2
- package/dist/verify.d.ts +23 -2
- package/dist/verify.js +23 -4
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +23 -4
- package/dist/verify.mjs.map +1 -1
- package/dist/webhooks.d.mts +16 -3
- package/dist/webhooks.d.ts +16 -3
- package/dist/webhooks.js +24 -13
- package/dist/webhooks.js.map +1 -1
- package/dist/webhooks.mjs +24 -13
- package/dist/webhooks.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -452,7 +452,7 @@ function routePolicyOf(route) {
|
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
// src/version.ts
|
|
455
|
-
var SDK_VERSION = "5.
|
|
455
|
+
var SDK_VERSION = "5.19.0";
|
|
456
456
|
|
|
457
457
|
// src/http.ts
|
|
458
458
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -770,7 +770,12 @@ function getCacheKey(request, counterpartyId) {
|
|
|
770
770
|
// its start_checkout quote was served the cached quote-leg grant (no
|
|
771
771
|
// settlementOutcome) and never reached the backend. Same F-A1-07 bug class.
|
|
772
772
|
request.commercePhase || "",
|
|
773
|
-
request.checkoutSessionId || ""
|
|
773
|
+
request.checkoutSessionId || "",
|
|
774
|
+
// 5.19.0: a route_config purpose claim is checked server-side against
|
|
775
|
+
// the stored rule for this method + path, so it changes the verdict.
|
|
776
|
+
request.purposeSource || "",
|
|
777
|
+
request.requestMethod || "",
|
|
778
|
+
request.requestPath || ""
|
|
774
779
|
].join("|");
|
|
775
780
|
}
|
|
776
781
|
function getCachedResult(request, counterpartyId) {
|
|
@@ -978,6 +983,11 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
978
983
|
if (requestData.buyerEmail) body.buyerEmail = requestData.buyerEmail;
|
|
979
984
|
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
980
985
|
if (requestData.attemptId) body.attemptId = requestData.attemptId;
|
|
986
|
+
if (requestData.purposeSource) body.purposeSource = requestData.purposeSource;
|
|
987
|
+
if (requestData.agentArtifacts) body.agentArtifacts = requestData.agentArtifacts;
|
|
988
|
+
if (requestData.metadata) body.metadata = requestData.metadata;
|
|
989
|
+
if (requestData.requestMethod) body.requestMethod = requestData.requestMethod;
|
|
990
|
+
if (requestData.requestPath) body.requestPath = requestData.requestPath;
|
|
981
991
|
if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
|
|
982
992
|
body.sdkVersion = SDK_VERSION;
|
|
983
993
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
@@ -1167,9 +1177,18 @@ async function verify(config, request, options) {
|
|
|
1167
1177
|
if (!apiResponse.access?.allowed) {
|
|
1168
1178
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
1169
1179
|
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
|
|
1180
|
+
const denyAgent = idVerifiedFromBackend && apiResponse.agent ? {
|
|
1181
|
+
astraId: apiResponse.agent.astraId,
|
|
1182
|
+
name: apiResponse.agent.name,
|
|
1183
|
+
trustScore: apiResponse.agent.trustScore,
|
|
1184
|
+
trustLevel: getTrustLevel(apiResponse.agent.trustScore),
|
|
1185
|
+
blockchainAnchored: apiResponse.agent.blockchainStatus === "anchored",
|
|
1186
|
+
status: apiResponse.agent.agentStatus
|
|
1187
|
+
} : void 0;
|
|
1170
1188
|
const result2 = {
|
|
1171
1189
|
identityVerified: idVerifiedFromBackend,
|
|
1172
1190
|
policyAllowed: false,
|
|
1191
|
+
...denyAgent && { agent: denyAgent },
|
|
1173
1192
|
// 3.6.0: the server now emits top-level denialReasons on every deny
|
|
1174
1193
|
// path — prefer it verbatim; the failure-message reconstruction remains
|
|
1175
1194
|
// as the fallback for older backends.
|
|
@@ -1319,7 +1338,7 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
1319
1338
|
});
|
|
1320
1339
|
}
|
|
1321
1340
|
var refusedPolicyReads = /* @__PURE__ */ new Set();
|
|
1322
|
-
async function fetchRoutes(config, counterpartyId) {
|
|
1341
|
+
async function fetchRoutes(config, counterpartyId, options = {}) {
|
|
1323
1342
|
if (!counterpartyId) return null;
|
|
1324
1343
|
const headers = { "Content-Type": "application/json" };
|
|
1325
1344
|
if (config.apiKey) {
|
|
@@ -1328,7 +1347,7 @@ async function fetchRoutes(config, counterpartyId) {
|
|
|
1328
1347
|
}
|
|
1329
1348
|
try {
|
|
1330
1349
|
const response = await sdkFetch(
|
|
1331
|
-
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes
|
|
1350
|
+
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes` + (options.codeGates?.length ? `?codeGates=${options.codeGates.map(encodeURIComponent).join(",")}` : ""),
|
|
1332
1351
|
{ method: "GET", headers }
|
|
1333
1352
|
);
|
|
1334
1353
|
if (!response.ok) {
|
|
@@ -1374,6 +1393,42 @@ async function reportCounterpartyPreCheckFailure(config, data) {
|
|
|
1374
1393
|
});
|
|
1375
1394
|
}
|
|
1376
1395
|
|
|
1396
|
+
// src/adapters/routes-cache.ts
|
|
1397
|
+
var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
1398
|
+
function createRoutesCache(config, opts = {}) {
|
|
1399
|
+
const refreshMs = opts.refreshMs ?? DEFAULT_ROUTES_REFRESH_MS;
|
|
1400
|
+
let cached = [];
|
|
1401
|
+
let lastFetchAt = 0;
|
|
1402
|
+
let refreshing = null;
|
|
1403
|
+
async function refresh() {
|
|
1404
|
+
if (!config.counterpartyId) {
|
|
1405
|
+
opts.onNoCounterparty?.();
|
|
1406
|
+
return;
|
|
1407
|
+
}
|
|
1408
|
+
const fetched = await fetchRoutes(config, config.counterpartyId, opts.fetchOptions);
|
|
1409
|
+
if (fetched) {
|
|
1410
|
+
cached = fetched;
|
|
1411
|
+
lastFetchAt = Date.now();
|
|
1412
|
+
opts.onFetched?.(fetched);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
function start() {
|
|
1416
|
+
refreshing = refresh().catch(() => void 0).finally(() => {
|
|
1417
|
+
refreshing = null;
|
|
1418
|
+
});
|
|
1419
|
+
}
|
|
1420
|
+
start();
|
|
1421
|
+
return {
|
|
1422
|
+
async current() {
|
|
1423
|
+
if (refreshing) await refreshing.catch(() => {
|
|
1424
|
+
});
|
|
1425
|
+
if (config.counterpartyId && Date.now() - lastFetchAt > refreshMs) start();
|
|
1426
|
+
return cached;
|
|
1427
|
+
},
|
|
1428
|
+
peek: () => cached
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1377
1432
|
// src/transport/http.ts
|
|
1378
1433
|
var HEADER_PREFIX = "X-Astra-";
|
|
1379
1434
|
function extractHttpCredentials(headers) {
|
|
@@ -1523,6 +1578,20 @@ function resolveHttpPdlss(input) {
|
|
|
1523
1578
|
}
|
|
1524
1579
|
return { purpose, action, purposeSource, actionSource };
|
|
1525
1580
|
}
|
|
1581
|
+
function wirePurposeSource(source) {
|
|
1582
|
+
switch (source) {
|
|
1583
|
+
case "route_config":
|
|
1584
|
+
return "route_config";
|
|
1585
|
+
case "header":
|
|
1586
|
+
case "legacy_header":
|
|
1587
|
+
case "query":
|
|
1588
|
+
return "header";
|
|
1589
|
+
case "custom_extractor":
|
|
1590
|
+
return "body";
|
|
1591
|
+
default:
|
|
1592
|
+
return "default";
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1526
1595
|
|
|
1527
1596
|
// src/adapters/approval-gate.ts
|
|
1528
1597
|
var APPROVAL_REASON = "Transaction is above the autonomous limit and requires human approval. The agent owner can approve or deny this transaction in the AstraSync dashboard.";
|
|
@@ -2323,7 +2392,6 @@ function defaultOnDenied(result, _req, res) {
|
|
|
2323
2392
|
}
|
|
2324
2393
|
});
|
|
2325
2394
|
}
|
|
2326
|
-
var DEFAULT_ROUTES_REFRESH_MS = 5 * 60 * 1e3;
|
|
2327
2395
|
function createMiddleware(options) {
|
|
2328
2396
|
if ("routes" in options) {
|
|
2329
2397
|
console.warn(
|
|
@@ -2339,7 +2407,7 @@ function createMiddleware(options) {
|
|
|
2339
2407
|
recordDecisions,
|
|
2340
2408
|
enableRuntimeChallenge = true,
|
|
2341
2409
|
routesRefreshMs = DEFAULT_ROUTES_REFRESH_MS,
|
|
2342
|
-
failOnError = "
|
|
2410
|
+
failOnError = "closed",
|
|
2343
2411
|
caseInsensitiveRouteMatch = false,
|
|
2344
2412
|
anonymousBeacon = true,
|
|
2345
2413
|
trustVerifiedHop = false,
|
|
@@ -2363,26 +2431,19 @@ function createMiddleware(options) {
|
|
|
2363
2431
|
rawHeaders: req.headers
|
|
2364
2432
|
});
|
|
2365
2433
|
} : void 0;
|
|
2366
|
-
let cachedRoutes = [];
|
|
2367
|
-
let lastFetchAt = 0;
|
|
2368
|
-
let refreshing = null;
|
|
2369
2434
|
let warnedNoCounterparty = false;
|
|
2370
2435
|
let warnedEmptyRoutes = false;
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
);
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
if (fetched) {
|
|
2383
|
-
cachedRoutes = fetched;
|
|
2384
|
-
lastFetchAt = Date.now();
|
|
2385
|
-
if (cachedRoutes.length === 0 && !warnedEmptyRoutes) {
|
|
2436
|
+
const routesCache = createRoutesCache(config, {
|
|
2437
|
+
refreshMs: routesRefreshMs,
|
|
2438
|
+
onNoCounterparty: () => {
|
|
2439
|
+
if (warnedNoCounterparty) return;
|
|
2440
|
+
console.warn(
|
|
2441
|
+
"[VerificationGateway] No counterpartyId configured \u2014 falling through (allow all). Per-route policy lives in the AstraSync dashboard now; register the endpoint and set counterpartyId in your middleware config to enforce policy."
|
|
2442
|
+
);
|
|
2443
|
+
warnedNoCounterparty = true;
|
|
2444
|
+
},
|
|
2445
|
+
onFetched: (routes) => {
|
|
2446
|
+
if (routes.length === 0 && !warnedEmptyRoutes) {
|
|
2386
2447
|
const dashboard = config.dashboardUrl ?? "https://astrasync.ai/dashboard";
|
|
2387
2448
|
console.warn(
|
|
2388
2449
|
`[VerificationGateway] No route policy configured for ${config.counterpartyId}. Gateway is in pass-through mode for ALL traffic until you add at least one route. Configure at ${dashboard}/dashboard/endpoints/${config.counterpartyId}/routes`
|
|
@@ -2390,9 +2451,6 @@ function createMiddleware(options) {
|
|
|
2390
2451
|
warnedEmptyRoutes = true;
|
|
2391
2452
|
}
|
|
2392
2453
|
}
|
|
2393
|
-
}
|
|
2394
|
-
refreshing = refreshRoutes().finally(() => {
|
|
2395
|
-
refreshing = null;
|
|
2396
2454
|
});
|
|
2397
2455
|
return async (req, res, next) => {
|
|
2398
2456
|
try {
|
|
@@ -2400,15 +2458,9 @@ function createMiddleware(options) {
|
|
|
2400
2458
|
if (shouldSkip) {
|
|
2401
2459
|
return next();
|
|
2402
2460
|
}
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
}
|
|
2407
|
-
if (config.counterpartyId && Date.now() - lastFetchAt > routesRefreshMs) {
|
|
2408
|
-
refreshing = refreshRoutes().finally(() => {
|
|
2409
|
-
refreshing = null;
|
|
2410
|
-
});
|
|
2411
|
-
}
|
|
2461
|
+
const cachedRoutes = (await routesCache.current()).filter(
|
|
2462
|
+
(r) => typeof r.pattern === "string" && !r.tool
|
|
2463
|
+
);
|
|
2412
2464
|
const correlationId = req.headers["x-request-id"] || req.headers["x-correlation-id"];
|
|
2413
2465
|
const matchedRoute = findRouteConfig(cachedRoutes, req.path, req.method, {
|
|
2414
2466
|
caseInsensitive: caseInsensitiveRouteMatch,
|
|
@@ -2532,6 +2584,12 @@ function createMiddleware(options) {
|
|
|
2532
2584
|
...commerceArtifacts && { commerceArtifacts },
|
|
2533
2585
|
purpose,
|
|
2534
2586
|
action: pdlssPair.action,
|
|
2587
|
+
// 5.19.0: the source + the request line let verify-access check a
|
|
2588
|
+
// route purpose against the stored rule (item 20: an MPP paid leg
|
|
2589
|
+
// keeps `shopping.purchase` instead of `commerce.payment.execute`).
|
|
2590
|
+
purposeSource: wirePurposeSource(pdlssPair.purposeSource),
|
|
2591
|
+
requestMethod: req.method,
|
|
2592
|
+
requestPath: req.path,
|
|
2535
2593
|
resource: req.path,
|
|
2536
2594
|
createSession: shouldRecordDecisions,
|
|
2537
2595
|
counterpartyUrl,
|
|
@@ -2609,7 +2667,8 @@ function createMiddleware(options) {
|
|
|
2609
2667
|
return;
|
|
2610
2668
|
}
|
|
2611
2669
|
if (routeConfig.minTrustScore && result.agent) {
|
|
2612
|
-
|
|
2670
|
+
const score = result.agent.trustScore;
|
|
2671
|
+
if (typeof score !== "number" || score < routeConfig.minTrustScore) {
|
|
2613
2672
|
const trustFailure = {
|
|
2614
2673
|
dimension: "endpoint.trust",
|
|
2615
2674
|
message: "Trust below the route requirement for this endpoint.",
|