@astrasyncai/verification-gateway 2.4.3 → 2.4.5
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 +90 -0
- package/dist/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +35 -7
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +35 -7
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +61 -2
- package/dist/adapters/mcp.d.ts +61 -2
- package/dist/adapters/mcp.js +95 -18
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +95 -18
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +5 -0
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +5 -0
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +2 -2
- package/dist/adapters/sdk.d.ts +2 -2
- package/dist/adapters/sdk.js +5 -0
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +5 -0
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/bin/astrasync.js +10 -2
- package/dist/browser/background.js +5 -0
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +5 -0
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +2 -2
- package/dist/browser/browser-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cursor/cursor-adapter.d.mts +2 -2
- package/dist/cursor/cursor-adapter.d.ts +2 -2
- package/dist/cursor/extension.d.mts +2 -2
- package/dist/cursor/extension.d.ts +2 -2
- package/dist/cursor/extension.js +5 -0
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +5 -0
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/{express-DneHiMhu.d.mts → express-D5hAJ2Gv.d.mts} +1 -1
- package/dist/{express-DsiaQRFt.d.ts → express-XCkk7BsJ.d.ts} +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +5 -0
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +5 -0
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +2 -2
- package/dist/git-trigger/git-hooks.d.ts +2 -2
- package/dist/{index-NZiKvrtE.d.ts → index-Bstl43HI.d.ts} +1 -1
- package/dist/{index-Dd4alF0l.d.ts → index-CH4TfcbL.d.ts} +1 -1
- package/dist/{index-C9yWlQ2Y.d.mts → index-TS4SGvf4.d.mts} +1 -1
- package/dist/{index-DAGm-Sgf.d.mts → index-u08qcXq9.d.mts} +1 -1
- package/dist/index.d.mts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +35 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -7
- 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/{nextjs-vUuVCaBP.d.mts → nextjs-CFA0J_4x.d.mts} +1 -1
- package/dist/{nextjs-B4WmoiVm.d.ts → nextjs-DP2EpI-4.d.ts} +1 -1
- package/dist/registration/index.d.mts +25 -0
- package/dist/registration/index.d.ts +25 -0
- package/dist/registration/index.js +10 -2
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +10 -2
- package/dist/registration/index.mjs.map +1 -1
- package/dist/{sdk-Cixo6pTV.d.mts → sdk-C8W54WZS.d.mts} +1 -1
- package/dist/{sdk-BvWp4q2q.d.ts → sdk-CwwCGDzK.d.ts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/{types-DLai3jly.d.mts → types-CbZOkIr-.d.mts} +29 -0
- package/dist/{types-DLai3jly.d.ts → types-CbZOkIr-.d.ts} +29 -0
- package/dist/{types-IUzu-A4u.d.ts → types-DXNkr61h.d.ts} +1 -1
- package/dist/{types-C_e1IZdU.d.mts → types-tBNFSbw_.d.mts} +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/adapters/mcp.mjs
CHANGED
|
@@ -17,6 +17,9 @@ function hasMinimumAccess(actual, required) {
|
|
|
17
17
|
return ACCESS_LEVEL_HIERARCHY[actual] >= ACCESS_LEVEL_HIERARCHY[required];
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
// src/version.ts
|
|
21
|
+
var SDK_VERSION = "2.4.5";
|
|
22
|
+
|
|
20
23
|
// src/verify.ts
|
|
21
24
|
var DEFAULT_CONFIG = {
|
|
22
25
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -174,6 +177,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
174
177
|
if (config.counterpartyId) body.counterpartyId = config.counterpartyId;
|
|
175
178
|
if (requestData.runtimeChallengeOptions)
|
|
176
179
|
body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
|
|
180
|
+
if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
|
|
181
|
+
body.sdkVersion = SDK_VERSION;
|
|
177
182
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
178
183
|
const meta = {
|
|
179
184
|
...requestData.clientIp && { sourceIp: requestData.clientIp },
|
|
@@ -457,15 +462,17 @@ function parseMcpJsonRpc(body) {
|
|
|
457
462
|
if (method === "initialize" && params && typeof params.protocolVersion === "string") {
|
|
458
463
|
protocolVersion = params.protocolVersion;
|
|
459
464
|
}
|
|
460
|
-
let agentIdFromBody;
|
|
461
465
|
const meta = params?._meta;
|
|
462
466
|
const astrasyncMeta = meta?.astrasync;
|
|
467
|
+
const args = params?.arguments;
|
|
468
|
+
let agentIdFromBody;
|
|
463
469
|
if (astrasyncMeta && typeof astrasyncMeta.agentId === "string") {
|
|
464
470
|
agentIdFromBody = astrasyncMeta.agentId;
|
|
465
|
-
} else {
|
|
466
|
-
|
|
467
|
-
if (args && typeof args.agent_id === "string") agentIdFromBody = args.agent_id;
|
|
471
|
+
} else if (args && typeof args.agent_id === "string") {
|
|
472
|
+
agentIdFromBody = args.agent_id;
|
|
468
473
|
}
|
|
474
|
+
const purposeBodyResult = extractFromMcpBody(astrasyncMeta, args, "purpose");
|
|
475
|
+
const actionBodyResult = extractFromMcpBody(astrasyncMeta, args, "action");
|
|
469
476
|
const isInitialize = method === "initialize";
|
|
470
477
|
const isToolCall = method === "tools/call";
|
|
471
478
|
const isIntrospection = method === "tools/list" || method === "prompts/list" || method === "resources/list" || method === "ping" || method === "notifications/initialized";
|
|
@@ -474,19 +481,51 @@ function parseMcpJsonRpc(body) {
|
|
|
474
481
|
...toolName ? { toolName } : {},
|
|
475
482
|
...protocolVersion ? { protocolVersion } : {},
|
|
476
483
|
...agentIdFromBody ? { agentIdFromBody } : {},
|
|
484
|
+
...purposeBodyResult.value ? { purposeFromBody: purposeBodyResult.value } : {},
|
|
485
|
+
...purposeBodyResult.source ? { purposeSourceFromBody: purposeBodyResult.source } : {},
|
|
486
|
+
...actionBodyResult.value ? { actionFromBody: actionBodyResult.value } : {},
|
|
487
|
+
...actionBodyResult.source ? { actionSourceFromBody: actionBodyResult.source } : {},
|
|
477
488
|
isInitialize,
|
|
478
489
|
isToolCall,
|
|
479
490
|
isIntrospection
|
|
480
491
|
};
|
|
481
492
|
}
|
|
482
|
-
function
|
|
483
|
-
|
|
493
|
+
function extractFromMcpBody(astrasyncMeta, args, key) {
|
|
494
|
+
if (astrasyncMeta && typeof astrasyncMeta[key] === "string") {
|
|
495
|
+
return { value: astrasyncMeta[key], source: "meta" };
|
|
496
|
+
}
|
|
497
|
+
if (args && typeof args[key] === "string") {
|
|
498
|
+
return { value: args[key], source: "tool_argument" };
|
|
499
|
+
}
|
|
500
|
+
return { value: void 0, source: void 0 };
|
|
501
|
+
}
|
|
502
|
+
function mcpToPdlss(parsed, headerPurpose, headerAction) {
|
|
484
503
|
const resource = parsed.toolName ? `mcp:tool/${parsed.toolName}` : `mcp:method/${parsed.method}`;
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
504
|
+
let purpose;
|
|
505
|
+
let purposeSource;
|
|
506
|
+
if (headerPurpose) {
|
|
507
|
+
purpose = headerPurpose;
|
|
508
|
+
purposeSource = "header";
|
|
509
|
+
} else if (parsed.purposeFromBody && parsed.purposeSourceFromBody) {
|
|
510
|
+
purpose = parsed.purposeFromBody;
|
|
511
|
+
purposeSource = parsed.purposeSourceFromBody;
|
|
512
|
+
} else {
|
|
513
|
+
purpose = "mcp_invoke";
|
|
514
|
+
purposeSource = "default_mcp_invoke";
|
|
515
|
+
}
|
|
516
|
+
let action;
|
|
517
|
+
let actionSource;
|
|
518
|
+
if (headerAction) {
|
|
519
|
+
action = headerAction;
|
|
520
|
+
actionSource = "header";
|
|
521
|
+
} else if (parsed.actionFromBody && parsed.actionSourceFromBody) {
|
|
522
|
+
action = parsed.actionFromBody;
|
|
523
|
+
actionSource = parsed.actionSourceFromBody;
|
|
524
|
+
} else {
|
|
525
|
+
action = parsed.toolName ? `${parsed.method}:${parsed.toolName}` : parsed.method;
|
|
526
|
+
actionSource = "transport_layer";
|
|
527
|
+
}
|
|
528
|
+
return { purpose, action, resource, purposeSource, actionSource };
|
|
490
529
|
}
|
|
491
530
|
function mcpRiskTier(parsed) {
|
|
492
531
|
if (parsed.isInitialize || parsed.method === "notifications/initialized") return "none";
|
|
@@ -497,6 +536,11 @@ function mcpRiskTier(parsed) {
|
|
|
497
536
|
}
|
|
498
537
|
|
|
499
538
|
// src/adapters/mcp.ts
|
|
539
|
+
function readSingleHeader(value) {
|
|
540
|
+
if (typeof value === "string") return value;
|
|
541
|
+
if (Array.isArray(value)) return value[0];
|
|
542
|
+
return void 0;
|
|
543
|
+
}
|
|
500
544
|
function defaultMcpDenied(result, req, res) {
|
|
501
545
|
const id = req.body?.id ?? null;
|
|
502
546
|
const status = result.verified ? 403 : 401;
|
|
@@ -591,19 +635,30 @@ function createMcpMiddleware(options) {
|
|
|
591
635
|
toolGates,
|
|
592
636
|
methodGates
|
|
593
637
|
});
|
|
594
|
-
|
|
638
|
+
const credentials = extractCredentials(
|
|
639
|
+
req.headers,
|
|
640
|
+
req.query
|
|
641
|
+
);
|
|
642
|
+
if (effectiveAstraId) credentials.astraId = effectiveAstraId;
|
|
643
|
+
const shouldEnforce = minAccessLevel !== "none";
|
|
644
|
+
if (minAccessLevel === "none" && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
|
|
595
645
|
if (config.setPassThroughHeader) {
|
|
596
646
|
res.setHeader("X-Astra-Gateway-Mode", "unenforced");
|
|
597
647
|
res.setHeader("X-Astra-Gateway-Reason", "mcp-tier-none");
|
|
598
648
|
}
|
|
599
649
|
return next();
|
|
600
650
|
}
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
)
|
|
605
|
-
|
|
606
|
-
|
|
651
|
+
const headerPurpose = readSingleHeader(req.headers["x-astra-purpose"]);
|
|
652
|
+
const headerAction = readSingleHeader(req.headers["x-astra-action"]);
|
|
653
|
+
const pdlss = mcpToPdlss(parsed, headerPurpose, headerAction);
|
|
654
|
+
if (config.debug) {
|
|
655
|
+
console.debug("[mcp-middleware] pdlss resolved", {
|
|
656
|
+
purpose_source: pdlss.purposeSource,
|
|
657
|
+
resolved_purpose: pdlss.purpose,
|
|
658
|
+
action_source: pdlss.actionSource,
|
|
659
|
+
resolved_action: pdlss.action
|
|
660
|
+
});
|
|
661
|
+
}
|
|
607
662
|
const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get("host")}${req.path}`;
|
|
608
663
|
const shouldRecordDecisions = recordDecisions !== false;
|
|
609
664
|
const result = await verify(config, {
|
|
@@ -611,6 +666,10 @@ function createMcpMiddleware(options) {
|
|
|
611
666
|
purpose: pdlss.purpose,
|
|
612
667
|
action: pdlss.action,
|
|
613
668
|
resource: pdlss.resource,
|
|
669
|
+
// Round-12 (F19): mark transport protocol separately from intent.
|
|
670
|
+
// The MCP middleware always sets this to 'mcp'; non-MCP callers
|
|
671
|
+
// leave it unset (server-side default is 'rest').
|
|
672
|
+
invocationProtocol: "mcp",
|
|
614
673
|
createSession: shouldRecordDecisions,
|
|
615
674
|
counterpartyUrl,
|
|
616
675
|
counterpartyType: config.counterpartyType || "mcp_server",
|
|
@@ -632,7 +691,25 @@ function createMcpMiddleware(options) {
|
|
|
632
691
|
onDenied(result, req, res);
|
|
633
692
|
return;
|
|
634
693
|
}
|
|
694
|
+
if (!shouldEnforce) {
|
|
695
|
+
if (config.setPassThroughHeader) {
|
|
696
|
+
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
697
|
+
res.setHeader("X-Astra-Gateway-Reason", "evaluated-not-enforced");
|
|
698
|
+
}
|
|
699
|
+
if (shouldRecordDecisions && sessionId) {
|
|
700
|
+
recordDecision(config, sessionId, "granted").catch(() => {
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
return next();
|
|
704
|
+
}
|
|
635
705
|
if (!hasMinimumAccess(result.accessLevel, minAccessLevel)) {
|
|
706
|
+
const insufficientFailure = {
|
|
707
|
+
dimension: "access_level.insufficient",
|
|
708
|
+
message: `Tool requires accessLevel '${minAccessLevel}'; agent has '${result.accessLevel}'.`,
|
|
709
|
+
guidance: "Request elevated access via step-up verification (coming soon \u2014 ships this month). Step-up lets the agent owner approve a one-time elevation for this specific counterparty + purpose without changing the agent's baseline trust score."
|
|
710
|
+
};
|
|
711
|
+
result.failures = [...result.failures ?? [], insufficientFailure];
|
|
712
|
+
result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
|
|
636
713
|
if (shouldRecordDecisions) {
|
|
637
714
|
const overrideKind = gateSource === "toolGate" ? "toolGate" : gateSource === "methodGate" ? "methodGate" : "other";
|
|
638
715
|
const override = {
|