@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.
Files changed (87) hide show
  1. package/README.md +90 -0
  2. package/dist/adapter-interface/interface.d.mts +2 -2
  3. package/dist/adapter-interface/interface.d.ts +2 -2
  4. package/dist/adapters/express.d.mts +2 -2
  5. package/dist/adapters/express.d.ts +2 -2
  6. package/dist/adapters/express.js +35 -7
  7. package/dist/adapters/express.js.map +1 -1
  8. package/dist/adapters/express.mjs +35 -7
  9. package/dist/adapters/express.mjs.map +1 -1
  10. package/dist/adapters/mcp.d.mts +61 -2
  11. package/dist/adapters/mcp.d.ts +61 -2
  12. package/dist/adapters/mcp.js +95 -18
  13. package/dist/adapters/mcp.js.map +1 -1
  14. package/dist/adapters/mcp.mjs +95 -18
  15. package/dist/adapters/mcp.mjs.map +1 -1
  16. package/dist/adapters/nextjs.d.mts +2 -2
  17. package/dist/adapters/nextjs.d.ts +2 -2
  18. package/dist/adapters/nextjs.js +5 -0
  19. package/dist/adapters/nextjs.js.map +1 -1
  20. package/dist/adapters/nextjs.mjs +5 -0
  21. package/dist/adapters/nextjs.mjs.map +1 -1
  22. package/dist/adapters/sdk.d.mts +2 -2
  23. package/dist/adapters/sdk.d.ts +2 -2
  24. package/dist/adapters/sdk.js +5 -0
  25. package/dist/adapters/sdk.js.map +1 -1
  26. package/dist/adapters/sdk.mjs +5 -0
  27. package/dist/adapters/sdk.mjs.map +1 -1
  28. package/dist/agent/index.d.mts +2 -2
  29. package/dist/agent/index.d.ts +2 -2
  30. package/dist/bin/astrasync.js +10 -2
  31. package/dist/browser/background.js +5 -0
  32. package/dist/browser/background.js.map +1 -1
  33. package/dist/browser/background.mjs +5 -0
  34. package/dist/browser/background.mjs.map +1 -1
  35. package/dist/browser/browser-adapter.d.mts +2 -2
  36. package/dist/browser/browser-adapter.d.ts +2 -2
  37. package/dist/cli/index.d.mts +2 -2
  38. package/dist/cli/index.d.ts +2 -2
  39. package/dist/cursor/cursor-adapter.d.mts +2 -2
  40. package/dist/cursor/cursor-adapter.d.ts +2 -2
  41. package/dist/cursor/extension.d.mts +2 -2
  42. package/dist/cursor/extension.d.ts +2 -2
  43. package/dist/cursor/extension.js +5 -0
  44. package/dist/cursor/extension.js.map +1 -1
  45. package/dist/cursor/extension.mjs +5 -0
  46. package/dist/cursor/extension.mjs.map +1 -1
  47. package/dist/{express-DneHiMhu.d.mts → express-D5hAJ2Gv.d.mts} +1 -1
  48. package/dist/{express-DsiaQRFt.d.ts → express-XCkk7BsJ.d.ts} +1 -1
  49. package/dist/gateway/gateway.d.mts +2 -2
  50. package/dist/gateway/gateway.d.ts +2 -2
  51. package/dist/gateway/gateway.js +5 -0
  52. package/dist/gateway/gateway.js.map +1 -1
  53. package/dist/gateway/gateway.mjs +5 -0
  54. package/dist/gateway/gateway.mjs.map +1 -1
  55. package/dist/git-trigger/git-hooks.d.mts +2 -2
  56. package/dist/git-trigger/git-hooks.d.ts +2 -2
  57. package/dist/{index-NZiKvrtE.d.ts → index-Bstl43HI.d.ts} +1 -1
  58. package/dist/{index-Dd4alF0l.d.ts → index-CH4TfcbL.d.ts} +1 -1
  59. package/dist/{index-C9yWlQ2Y.d.mts → index-TS4SGvf4.d.mts} +1 -1
  60. package/dist/{index-DAGm-Sgf.d.mts → index-u08qcXq9.d.mts} +1 -1
  61. package/dist/index.d.mts +7 -7
  62. package/dist/index.d.ts +7 -7
  63. package/dist/index.js +35 -7
  64. package/dist/index.js.map +1 -1
  65. package/dist/index.mjs +35 -7
  66. package/dist/index.mjs.map +1 -1
  67. package/dist/local-evaluator/evaluator.d.mts +2 -2
  68. package/dist/local-evaluator/evaluator.d.ts +2 -2
  69. package/dist/{nextjs-vUuVCaBP.d.mts → nextjs-CFA0J_4x.d.mts} +1 -1
  70. package/dist/{nextjs-B4WmoiVm.d.ts → nextjs-DP2EpI-4.d.ts} +1 -1
  71. package/dist/registration/index.d.mts +25 -0
  72. package/dist/registration/index.d.ts +25 -0
  73. package/dist/registration/index.js +10 -2
  74. package/dist/registration/index.js.map +1 -1
  75. package/dist/registration/index.mjs +10 -2
  76. package/dist/registration/index.mjs.map +1 -1
  77. package/dist/{sdk-Cixo6pTV.d.mts → sdk-C8W54WZS.d.mts} +1 -1
  78. package/dist/{sdk-BvWp4q2q.d.ts → sdk-CwwCGDzK.d.ts} +1 -1
  79. package/dist/transport/index.d.mts +2 -2
  80. package/dist/transport/index.d.ts +2 -2
  81. package/dist/{types-DLai3jly.d.mts → types-CbZOkIr-.d.mts} +29 -0
  82. package/dist/{types-DLai3jly.d.ts → types-CbZOkIr-.d.ts} +29 -0
  83. package/dist/{types-IUzu-A4u.d.ts → types-DXNkr61h.d.ts} +1 -1
  84. package/dist/{types-C_e1IZdU.d.mts → types-tBNFSbw_.d.mts} +1 -1
  85. package/dist/ui/index.d.mts +1 -1
  86. package/dist/ui/index.d.ts +1 -1
  87. package/package.json +1 -1
@@ -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
- const args = params?.arguments;
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 mcpToPdlss(parsed) {
483
- const action = parsed.toolName ? `${parsed.method}:${parsed.toolName}` : parsed.method;
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
- return {
486
- purpose: "mcp_invoke",
487
- action,
488
- resource
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
- if (minAccessLevel === "none") {
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 credentials = extractCredentials(
602
- req.headers,
603
- req.query
604
- );
605
- if (effectiveAstraId) credentials.astraId = effectiveAstraId;
606
- const pdlss = mcpToPdlss(parsed);
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 = {