@astrasyncai/verification-gateway 5.19.0 → 5.21.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 +130 -0
- package/README.md +53 -4
- package/dist/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +65 -16
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +65 -16
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +23 -1
- package/dist/adapters/mcp.d.ts +23 -1
- package/dist/adapters/mcp.js +91 -16
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +91 -16
- 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 +57 -11
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +57 -11
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +35 -2
- package/dist/adapters/sdk.d.ts +35 -2
- package/dist/adapters/sdk.js +110 -11
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +110 -11
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +1 -1
- package/dist/agent/index.d.ts +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 +50 -12
- package/dist/bin/astrasync-codex-hook.js +50 -12
- package/dist/bin/astrasync-guard.js +50 -12
- package/dist/bin/astrasync.js +65 -13
- package/dist/browser/background.js +50 -12
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +50 -12
- 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 +50 -12
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +50 -12
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +50 -12
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +50 -12
- 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 +49 -11
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +49 -11
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +50 -12
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +50 -12
- 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 +286 -8
- package/dist/index.d.ts +286 -8
- package/dist/index.js +532 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +522 -49
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +2 -2
- package/dist/local-evaluator/evaluator.d.ts +2 -2
- package/dist/registration/index.d.mts +11 -2
- package/dist/registration/index.d.ts +11 -2
- 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.d.mts +1 -1
- package/dist/transport/index.d.ts +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-BoGjyon0.d.mts → types-B4zhOAlq.d.mts} +30 -1
- package/dist/{types-BRz2U0Pn.d.ts → types-B_HLhZ9n.d.ts} +1 -1
- package/dist/{types-BfILnheI.d.mts → types-CU17R4Nr.d.mts} +11 -0
- package/dist/{types-BfILnheI.d.ts → types-CU17R4Nr.d.ts} +11 -0
- package/dist/{types-eWyZuz-3.d.ts → types-CtBXnWuV.d.ts} +30 -1
- package/dist/{types-DqWPkiYl.d.mts → types-DHHyXtuZ.d.mts} +30 -1
- package/dist/{types-DqWPkiYl.d.ts → types-DHHyXtuZ.d.ts} +30 -1
- package/dist/{types-CfBpm3w5.d.mts → types-Djpz-L0w.d.mts} +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +28 -3
- package/dist/verify.d.ts +28 -3
- package/dist/verify.js +71 -11
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +69 -11
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
package/dist/adapters/mcp.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var SDK_VERSION = "5.
|
|
2
|
+
var SDK_VERSION = "5.21.0";
|
|
3
3
|
|
|
4
4
|
// src/http.ts
|
|
5
5
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -438,6 +438,9 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
438
438
|
if (requestData.enableRuntimeChallenge)
|
|
439
439
|
body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
|
|
440
440
|
if (requestData.routePolicy) body.routePolicy = requestData.routePolicy;
|
|
441
|
+
if (config.actingProof?.connectorToken) {
|
|
442
|
+
body.actingProof = { connectorToken: config.actingProof.connectorToken };
|
|
443
|
+
}
|
|
441
444
|
if (requestData.approvalHeldByRoute) body.approvalHeldByRoute = true;
|
|
442
445
|
if (requestData.createSession) body.createSession = requestData.createSession;
|
|
443
446
|
if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
|
|
@@ -605,22 +608,46 @@ async function verify(config, request, options) {
|
|
|
605
608
|
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access decisions (verified ID + runtime challenge + PDLSS + trust score). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
|
|
606
609
|
);
|
|
607
610
|
}
|
|
608
|
-
const uncacheable = Boolean(request.commerceArtifacts);
|
|
611
|
+
const uncacheable = Boolean(request.commerceArtifacts) || Boolean(mergedConfig.actingProof);
|
|
609
612
|
if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache && !uncacheable) {
|
|
610
613
|
const cached = getCachedResult(request, mergedConfig.counterpartyId);
|
|
611
614
|
if (cached) {
|
|
612
615
|
if (mergedConfig.debug) {
|
|
613
616
|
console.log("[VerificationGateway] Returning cached result");
|
|
614
617
|
}
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
618
|
+
return sharedVerdict(cached, request);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache && !uncacheable) {
|
|
622
|
+
const key = getCacheKey(request, mergedConfig.counterpartyId);
|
|
623
|
+
const pending = inflightVerifies.get(key);
|
|
624
|
+
if (pending) return sharedVerdict(await pending, request);
|
|
625
|
+
const flight = verifyViaApi(mergedConfig, request, urls, uncacheable);
|
|
626
|
+
inflightVerifies.set(key, flight);
|
|
627
|
+
try {
|
|
628
|
+
return await flight;
|
|
629
|
+
} finally {
|
|
630
|
+
inflightVerifies.delete(key);
|
|
622
631
|
}
|
|
623
632
|
}
|
|
633
|
+
return verifyViaApi(mergedConfig, request, urls, uncacheable);
|
|
634
|
+
}
|
|
635
|
+
var inflightVerifies = /* @__PURE__ */ new Map();
|
|
636
|
+
var sharedVerdicts = /* @__PURE__ */ new WeakSet();
|
|
637
|
+
function isSharedVerdict(result) {
|
|
638
|
+
return sharedVerdicts.has(result);
|
|
639
|
+
}
|
|
640
|
+
function sharedVerdict(source, request) {
|
|
641
|
+
const hit = { ...source };
|
|
642
|
+
if (request.attemptId) {
|
|
643
|
+
hit.attemptId = request.attemptId;
|
|
644
|
+
} else {
|
|
645
|
+
delete hit.attemptId;
|
|
646
|
+
}
|
|
647
|
+
sharedVerdicts.add(hit);
|
|
648
|
+
return hit;
|
|
649
|
+
}
|
|
650
|
+
async function verifyViaApi(mergedConfig, request, urls, uncacheable) {
|
|
624
651
|
const enrichedRequest = { ...request };
|
|
625
652
|
if (!enrichedRequest.counterpartyUrl && mergedConfig.counterpartyUrl) {
|
|
626
653
|
enrichedRequest.counterpartyUrl = mergedConfig.counterpartyUrl;
|
|
@@ -699,7 +726,9 @@ async function verify(config, request, options) {
|
|
|
699
726
|
fulfilment: apiResponse.fulfilment,
|
|
700
727
|
mandates: apiResponse.mandates,
|
|
701
728
|
kyaToken: apiResponse.kyaToken,
|
|
702
|
-
aep: apiResponse.aep
|
|
729
|
+
aep: apiResponse.aep,
|
|
730
|
+
// 5.20.0 (round 29.1): non-fatal integration warnings (e.g. events_url_missing).
|
|
731
|
+
warnings: apiResponse.warnings
|
|
703
732
|
};
|
|
704
733
|
return result2;
|
|
705
734
|
}
|
|
@@ -767,7 +796,9 @@ async function verify(config, request, options) {
|
|
|
767
796
|
// 5.15.0: merchant-lane AP2 mandates + KYAPay identity token.
|
|
768
797
|
mandates: apiResponse.mandates,
|
|
769
798
|
kyaToken: apiResponse.kyaToken,
|
|
770
|
-
aep: apiResponse.aep
|
|
799
|
+
aep: apiResponse.aep,
|
|
800
|
+
// 5.20.0 (round 29.1): non-fatal integration warnings (e.g. events_url_missing).
|
|
801
|
+
warnings: apiResponse.warnings
|
|
771
802
|
};
|
|
772
803
|
if (result.recommendation === "deny") {
|
|
773
804
|
result.policyAllowed = false;
|
|
@@ -793,8 +824,18 @@ async function verify(config, request, options) {
|
|
|
793
824
|
cacheResult(request, result, mergedConfig.cacheTtl, mergedConfig.counterpartyId);
|
|
794
825
|
}
|
|
795
826
|
}
|
|
827
|
+
notifyVerificationListeners(request, result);
|
|
796
828
|
return result;
|
|
797
829
|
}
|
|
830
|
+
var verificationListeners = /* @__PURE__ */ new Set();
|
|
831
|
+
function notifyVerificationListeners(request, result) {
|
|
832
|
+
for (const listener of verificationListeners) {
|
|
833
|
+
try {
|
|
834
|
+
listener(result, request);
|
|
835
|
+
} catch {
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
798
839
|
async function recordDecision(config, sessionId, decision, reason) {
|
|
799
840
|
const headers = { "Content-Type": "application/json" };
|
|
800
841
|
if (config.apiKey) {
|
|
@@ -817,6 +858,7 @@ async function fetchRoutes(config, counterpartyId, options = {}) {
|
|
|
817
858
|
headers["X-API-Key"] = config.apiKey;
|
|
818
859
|
}
|
|
819
860
|
try {
|
|
861
|
+
headers["X-AstraSync-SDK-Version"] = SDK_VERSION;
|
|
820
862
|
const response = await sdkFetch(
|
|
821
863
|
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes` + (options.codeGates?.length ? `?codeGates=${options.codeGates.map(encodeURIComponent).join(",")}` : ""),
|
|
822
864
|
{ method: "GET", headers }
|
|
@@ -831,6 +873,13 @@ async function fetchRoutes(config, counterpartyId, options = {}) {
|
|
|
831
873
|
return null;
|
|
832
874
|
}
|
|
833
875
|
const body = await response.json();
|
|
876
|
+
const type = body.data?.counterpartyType;
|
|
877
|
+
if (typeof type === "string" && options.onEndpointType) {
|
|
878
|
+
try {
|
|
879
|
+
options.onEndpointType(type);
|
|
880
|
+
} catch {
|
|
881
|
+
}
|
|
882
|
+
}
|
|
834
883
|
return body.data?.routes ?? [];
|
|
835
884
|
} catch {
|
|
836
885
|
return null;
|
|
@@ -1479,16 +1528,30 @@ function createMcpMiddleware(options) {
|
|
|
1479
1528
|
failOnError = "closed",
|
|
1480
1529
|
toolGatePrecedence = "code",
|
|
1481
1530
|
routesRefreshMs,
|
|
1531
|
+
skipEvaluation,
|
|
1482
1532
|
...config
|
|
1483
1533
|
} = options;
|
|
1534
|
+
const skipTools = new Set(skipEvaluation?.tools ?? []);
|
|
1535
|
+
const skipMethods = new Set(skipEvaluation?.methods ?? []);
|
|
1484
1536
|
if (config.apiBaseUrl) {
|
|
1485
1537
|
prefetchWellKnown(config.apiBaseUrl).catch(() => {
|
|
1486
1538
|
});
|
|
1487
1539
|
}
|
|
1488
1540
|
const codeGatedTools = Object.entries(toolGates ?? {}).filter(([, g]) => g !== "observe").map(([name]) => name);
|
|
1541
|
+
let warnedEndpointType = false;
|
|
1542
|
+
const onEndpointType = (counterpartyType) => {
|
|
1543
|
+
if (counterpartyType === "mcp_server" || warnedEndpointType) return;
|
|
1544
|
+
warnedEndpointType = true;
|
|
1545
|
+
console.warn(
|
|
1546
|
+
`[VerificationGateway/MCP] counterpartyId ${config.counterpartyId} is a '${counterpartyType}' endpoint, not an 'mcp_server' endpoint. Dashboard tool rules are read from an mcp_server endpoint only: register a separate MCP endpoint for this server (same owner) and use its id here. See https://astrasync.ai/docs/mcp-integration#tool-rules.`
|
|
1547
|
+
);
|
|
1548
|
+
};
|
|
1489
1549
|
const rulesCache = config.apiKey && config.counterpartyId ? createRoutesCache(config, {
|
|
1490
1550
|
...routesRefreshMs !== void 0 && { refreshMs: routesRefreshMs },
|
|
1491
|
-
|
|
1551
|
+
fetchOptions: {
|
|
1552
|
+
...codeGatedTools.length && { codeGates: codeGatedTools },
|
|
1553
|
+
onEndpointType
|
|
1554
|
+
}
|
|
1492
1555
|
}) : void 0;
|
|
1493
1556
|
return async (req, res, next) => {
|
|
1494
1557
|
try {
|
|
@@ -1538,6 +1601,9 @@ function createMcpMiddleware(options) {
|
|
|
1538
1601
|
return next();
|
|
1539
1602
|
}
|
|
1540
1603
|
}
|
|
1604
|
+
if (!parsed.toolName && skipMethods.has(parsed.method) && methodGates?.[parsed.method] === void 0) {
|
|
1605
|
+
return next();
|
|
1606
|
+
}
|
|
1541
1607
|
const dashboardRules = rulesCache ? dashboardToolRules(await rulesCache.current()) : void 0;
|
|
1542
1608
|
const gateDecision = resolveGate(parsed, {
|
|
1543
1609
|
toolGates,
|
|
@@ -1545,6 +1611,9 @@ function createMcpMiddleware(options) {
|
|
|
1545
1611
|
dashboardRules,
|
|
1546
1612
|
toolGatePrecedence
|
|
1547
1613
|
});
|
|
1614
|
+
if (!gateDecision.enforce && (parsed.toolName && skipTools.has(parsed.toolName) || !parsed.toolName && skipMethods.has(parsed.method))) {
|
|
1615
|
+
return next();
|
|
1616
|
+
}
|
|
1548
1617
|
const credentials = extractCredentials(
|
|
1549
1618
|
req.headers,
|
|
1550
1619
|
req.query
|
|
@@ -1601,8 +1670,14 @@ function createMcpMiddleware(options) {
|
|
|
1601
1670
|
const forwardedFor = req.headers["x-forwarded-for"];
|
|
1602
1671
|
const forwardedForStr = Array.isArray(forwardedFor) ? forwardedFor.join(", ") : forwardedFor;
|
|
1603
1672
|
const sourceIp = req.ip ?? (forwardedForStr ? forwardedForStr.split(",")[0].trim() : void 0);
|
|
1673
|
+
const attemptRaw = readSingleHeader(req.headers["x-astra-attempt-id"]);
|
|
1674
|
+
const metaAttempt = req.body?.params?._meta?.astrasync?.attemptId;
|
|
1675
|
+
const attemptId = [attemptRaw, metaAttempt].find(
|
|
1676
|
+
(v) => typeof v === "string" && /^att_[0-9a-f]{32}$/.test(v)
|
|
1677
|
+
);
|
|
1604
1678
|
const verificationRequest = {
|
|
1605
1679
|
credentials,
|
|
1680
|
+
...attemptId && { attemptId },
|
|
1606
1681
|
purpose: pdlss.purpose,
|
|
1607
1682
|
action: pdlss.action,
|
|
1608
1683
|
resource: pdlss.resource,
|
|
@@ -1664,14 +1739,14 @@ function createMcpMiddleware(options) {
|
|
|
1664
1739
|
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
1665
1740
|
res.setHeader("X-Astra-Gateway-Reason", "evaluated-not-enforced");
|
|
1666
1741
|
}
|
|
1667
|
-
if (shouldRecordDecisions && sessionId) {
|
|
1742
|
+
if (shouldRecordDecisions && sessionId && !isSharedVerdict(result)) {
|
|
1668
1743
|
recordDecision(config, sessionId, "granted").catch(() => {
|
|
1669
1744
|
});
|
|
1670
1745
|
}
|
|
1671
1746
|
return next();
|
|
1672
1747
|
}
|
|
1673
1748
|
if (!result.policyAllowed) {
|
|
1674
|
-
if (shouldRecordDecisions && sessionId) {
|
|
1749
|
+
if (shouldRecordDecisions && sessionId && !isSharedVerdict(result)) {
|
|
1675
1750
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
1676
1751
|
});
|
|
1677
1752
|
}
|
|
@@ -1681,7 +1756,7 @@ function createMcpMiddleware(options) {
|
|
|
1681
1756
|
}
|
|
1682
1757
|
if (requiresHumanApproval(result)) {
|
|
1683
1758
|
annotateApprovalRequired(result);
|
|
1684
|
-
if (shouldRecordDecisions && sessionId) {
|
|
1759
|
+
if (shouldRecordDecisions && sessionId && !isSharedVerdict(result)) {
|
|
1685
1760
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
1686
1761
|
});
|
|
1687
1762
|
}
|
|
@@ -1699,7 +1774,7 @@ function createMcpMiddleware(options) {
|
|
|
1699
1774
|
})
|
|
1700
1775
|
);
|
|
1701
1776
|
}
|
|
1702
|
-
if (shouldRecordDecisions && sessionId) {
|
|
1777
|
+
if (shouldRecordDecisions && sessionId && !isSharedVerdict(result)) {
|
|
1703
1778
|
recordDecision(config, sessionId, "granted").catch(() => {
|
|
1704
1779
|
});
|
|
1705
1780
|
}
|