@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
@@ -50,6 +50,9 @@ function hasMinimumAccess(actual, required) {
50
50
  return ACCESS_LEVEL_HIERARCHY[actual] >= ACCESS_LEVEL_HIERARCHY[required];
51
51
  }
52
52
 
53
+ // src/version.ts
54
+ var SDK_VERSION = "2.4.5";
55
+
53
56
  // src/verify.ts
54
57
  var DEFAULT_CONFIG = {
55
58
  apiBaseUrl: "https://astrasync.ai/api",
@@ -207,6 +210,8 @@ async function callVerifyAccessAPI(config, request) {
207
210
  if (config.counterpartyId) body.counterpartyId = config.counterpartyId;
208
211
  if (requestData.runtimeChallengeOptions)
209
212
  body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
213
+ if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
214
+ body.sdkVersion = SDK_VERSION;
210
215
  if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
211
216
  const meta = {
212
217
  ...requestData.clientIp && { sourceIp: requestData.clientIp },
@@ -490,15 +495,17 @@ function parseMcpJsonRpc(body) {
490
495
  if (method === "initialize" && params && typeof params.protocolVersion === "string") {
491
496
  protocolVersion = params.protocolVersion;
492
497
  }
493
- let agentIdFromBody;
494
498
  const meta = params?._meta;
495
499
  const astrasyncMeta = meta?.astrasync;
500
+ const args = params?.arguments;
501
+ let agentIdFromBody;
496
502
  if (astrasyncMeta && typeof astrasyncMeta.agentId === "string") {
497
503
  agentIdFromBody = astrasyncMeta.agentId;
498
- } else {
499
- const args = params?.arguments;
500
- if (args && typeof args.agent_id === "string") agentIdFromBody = args.agent_id;
504
+ } else if (args && typeof args.agent_id === "string") {
505
+ agentIdFromBody = args.agent_id;
501
506
  }
507
+ const purposeBodyResult = extractFromMcpBody(astrasyncMeta, args, "purpose");
508
+ const actionBodyResult = extractFromMcpBody(astrasyncMeta, args, "action");
502
509
  const isInitialize = method === "initialize";
503
510
  const isToolCall = method === "tools/call";
504
511
  const isIntrospection = method === "tools/list" || method === "prompts/list" || method === "resources/list" || method === "ping" || method === "notifications/initialized";
@@ -507,19 +514,51 @@ function parseMcpJsonRpc(body) {
507
514
  ...toolName ? { toolName } : {},
508
515
  ...protocolVersion ? { protocolVersion } : {},
509
516
  ...agentIdFromBody ? { agentIdFromBody } : {},
517
+ ...purposeBodyResult.value ? { purposeFromBody: purposeBodyResult.value } : {},
518
+ ...purposeBodyResult.source ? { purposeSourceFromBody: purposeBodyResult.source } : {},
519
+ ...actionBodyResult.value ? { actionFromBody: actionBodyResult.value } : {},
520
+ ...actionBodyResult.source ? { actionSourceFromBody: actionBodyResult.source } : {},
510
521
  isInitialize,
511
522
  isToolCall,
512
523
  isIntrospection
513
524
  };
514
525
  }
515
- function mcpToPdlss(parsed) {
516
- const action = parsed.toolName ? `${parsed.method}:${parsed.toolName}` : parsed.method;
526
+ function extractFromMcpBody(astrasyncMeta, args, key) {
527
+ if (astrasyncMeta && typeof astrasyncMeta[key] === "string") {
528
+ return { value: astrasyncMeta[key], source: "meta" };
529
+ }
530
+ if (args && typeof args[key] === "string") {
531
+ return { value: args[key], source: "tool_argument" };
532
+ }
533
+ return { value: void 0, source: void 0 };
534
+ }
535
+ function mcpToPdlss(parsed, headerPurpose, headerAction) {
517
536
  const resource = parsed.toolName ? `mcp:tool/${parsed.toolName}` : `mcp:method/${parsed.method}`;
518
- return {
519
- purpose: "mcp_invoke",
520
- action,
521
- resource
522
- };
537
+ let purpose;
538
+ let purposeSource;
539
+ if (headerPurpose) {
540
+ purpose = headerPurpose;
541
+ purposeSource = "header";
542
+ } else if (parsed.purposeFromBody && parsed.purposeSourceFromBody) {
543
+ purpose = parsed.purposeFromBody;
544
+ purposeSource = parsed.purposeSourceFromBody;
545
+ } else {
546
+ purpose = "mcp_invoke";
547
+ purposeSource = "default_mcp_invoke";
548
+ }
549
+ let action;
550
+ let actionSource;
551
+ if (headerAction) {
552
+ action = headerAction;
553
+ actionSource = "header";
554
+ } else if (parsed.actionFromBody && parsed.actionSourceFromBody) {
555
+ action = parsed.actionFromBody;
556
+ actionSource = parsed.actionSourceFromBody;
557
+ } else {
558
+ action = parsed.toolName ? `${parsed.method}:${parsed.toolName}` : parsed.method;
559
+ actionSource = "transport_layer";
560
+ }
561
+ return { purpose, action, resource, purposeSource, actionSource };
523
562
  }
524
563
  function mcpRiskTier(parsed) {
525
564
  if (parsed.isInitialize || parsed.method === "notifications/initialized") return "none";
@@ -530,6 +569,11 @@ function mcpRiskTier(parsed) {
530
569
  }
531
570
 
532
571
  // src/adapters/mcp.ts
572
+ function readSingleHeader(value) {
573
+ if (typeof value === "string") return value;
574
+ if (Array.isArray(value)) return value[0];
575
+ return void 0;
576
+ }
533
577
  function defaultMcpDenied(result, req, res) {
534
578
  const id = req.body?.id ?? null;
535
579
  const status = result.verified ? 403 : 401;
@@ -624,19 +668,30 @@ function createMcpMiddleware(options) {
624
668
  toolGates,
625
669
  methodGates
626
670
  });
627
- if (minAccessLevel === "none") {
671
+ const credentials = extractCredentials(
672
+ req.headers,
673
+ req.query
674
+ );
675
+ if (effectiveAstraId) credentials.astraId = effectiveAstraId;
676
+ const shouldEnforce = minAccessLevel !== "none";
677
+ if (minAccessLevel === "none" && (!config.evaluateAlwaysIfCredentialed || !credentials.astraId)) {
628
678
  if (config.setPassThroughHeader) {
629
679
  res.setHeader("X-Astra-Gateway-Mode", "unenforced");
630
680
  res.setHeader("X-Astra-Gateway-Reason", "mcp-tier-none");
631
681
  }
632
682
  return next();
633
683
  }
634
- const credentials = extractCredentials(
635
- req.headers,
636
- req.query
637
- );
638
- if (effectiveAstraId) credentials.astraId = effectiveAstraId;
639
- const pdlss = mcpToPdlss(parsed);
684
+ const headerPurpose = readSingleHeader(req.headers["x-astra-purpose"]);
685
+ const headerAction = readSingleHeader(req.headers["x-astra-action"]);
686
+ const pdlss = mcpToPdlss(parsed, headerPurpose, headerAction);
687
+ if (config.debug) {
688
+ console.debug("[mcp-middleware] pdlss resolved", {
689
+ purpose_source: pdlss.purposeSource,
690
+ resolved_purpose: pdlss.purpose,
691
+ action_source: pdlss.actionSource,
692
+ resolved_action: pdlss.action
693
+ });
694
+ }
640
695
  const counterpartyUrl = config.counterpartyUrl || `${req.protocol}://${req.get("host")}${req.path}`;
641
696
  const shouldRecordDecisions = recordDecisions !== false;
642
697
  const result = await verify(config, {
@@ -644,6 +699,10 @@ function createMcpMiddleware(options) {
644
699
  purpose: pdlss.purpose,
645
700
  action: pdlss.action,
646
701
  resource: pdlss.resource,
702
+ // Round-12 (F19): mark transport protocol separately from intent.
703
+ // The MCP middleware always sets this to 'mcp'; non-MCP callers
704
+ // leave it unset (server-side default is 'rest').
705
+ invocationProtocol: "mcp",
647
706
  createSession: shouldRecordDecisions,
648
707
  counterpartyUrl,
649
708
  counterpartyType: config.counterpartyType || "mcp_server",
@@ -665,7 +724,25 @@ function createMcpMiddleware(options) {
665
724
  onDenied(result, req, res);
666
725
  return;
667
726
  }
727
+ if (!shouldEnforce) {
728
+ if (config.setPassThroughHeader) {
729
+ res.setHeader("X-Astra-Gateway-Mode", "enforced");
730
+ res.setHeader("X-Astra-Gateway-Reason", "evaluated-not-enforced");
731
+ }
732
+ if (shouldRecordDecisions && sessionId) {
733
+ recordDecision(config, sessionId, "granted").catch(() => {
734
+ });
735
+ }
736
+ return next();
737
+ }
668
738
  if (!hasMinimumAccess(result.accessLevel, minAccessLevel)) {
739
+ const insufficientFailure = {
740
+ dimension: "access_level.insufficient",
741
+ message: `Tool requires accessLevel '${minAccessLevel}'; agent has '${result.accessLevel}'.`,
742
+ 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."
743
+ };
744
+ result.failures = [...result.failures ?? [], insufficientFailure];
745
+ result.denialReasons = [...result.denialReasons ?? [], insufficientFailure.message];
669
746
  if (shouldRecordDecisions) {
670
747
  const overrideKind = gateSource === "toolGate" ? "toolGate" : gateSource === "methodGate" ? "methodGate" : "other";
671
748
  const override = {