@astrasyncai/verification-gateway 2.1.0 → 2.2.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.
Files changed (77) hide show
  1. package/dist/adapter-interface/interface.d.mts +2 -2
  2. package/dist/adapter-interface/interface.d.ts +2 -2
  3. package/dist/adapters/express.d.mts +2 -2
  4. package/dist/adapters/express.d.ts +2 -2
  5. package/dist/adapters/express.js +42 -20
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +42 -20
  8. package/dist/adapters/express.mjs.map +1 -1
  9. package/dist/adapters/nextjs.d.mts +2 -2
  10. package/dist/adapters/nextjs.d.ts +2 -2
  11. package/dist/adapters/nextjs.js +43 -20
  12. package/dist/adapters/nextjs.js.map +1 -1
  13. package/dist/adapters/nextjs.mjs +43 -20
  14. package/dist/adapters/nextjs.mjs.map +1 -1
  15. package/dist/adapters/sdk.d.mts +2 -2
  16. package/dist/adapters/sdk.d.ts +2 -2
  17. package/dist/adapters/sdk.js +25 -16
  18. package/dist/adapters/sdk.js.map +1 -1
  19. package/dist/adapters/sdk.mjs +25 -16
  20. package/dist/adapters/sdk.mjs.map +1 -1
  21. package/dist/agent/index.d.mts +2 -2
  22. package/dist/agent/index.d.ts +2 -2
  23. package/dist/agent/index.js +67 -1
  24. package/dist/agent/index.js.map +1 -1
  25. package/dist/agent/index.mjs +65 -1
  26. package/dist/agent/index.mjs.map +1 -1
  27. package/dist/browser/background.js +25 -16
  28. package/dist/browser/background.js.map +1 -1
  29. package/dist/browser/background.mjs +25 -16
  30. package/dist/browser/background.mjs.map +1 -1
  31. package/dist/browser/browser-adapter.d.mts +2 -2
  32. package/dist/browser/browser-adapter.d.ts +2 -2
  33. package/dist/cli/index.d.mts +2 -2
  34. package/dist/cli/index.d.ts +2 -2
  35. package/dist/cursor/cursor-adapter.d.mts +2 -2
  36. package/dist/cursor/cursor-adapter.d.ts +2 -2
  37. package/dist/cursor/extension.d.mts +2 -2
  38. package/dist/cursor/extension.d.ts +2 -2
  39. package/dist/cursor/extension.js +25 -16
  40. package/dist/cursor/extension.js.map +1 -1
  41. package/dist/cursor/extension.mjs +25 -16
  42. package/dist/cursor/extension.mjs.map +1 -1
  43. package/dist/{express-CtwDIZyF.d.mts → express-C9KqJNWV.d.mts} +1 -1
  44. package/dist/{express-Bcl-uBUE.d.ts → express-DpwYW08E.d.ts} +1 -1
  45. package/dist/gateway/gateway.d.mts +2 -2
  46. package/dist/gateway/gateway.d.ts +2 -2
  47. package/dist/gateway/gateway.js +25 -16
  48. package/dist/gateway/gateway.js.map +1 -1
  49. package/dist/gateway/gateway.mjs +25 -16
  50. package/dist/gateway/gateway.mjs.map +1 -1
  51. package/dist/git-trigger/git-hooks.d.mts +2 -2
  52. package/dist/git-trigger/git-hooks.d.ts +2 -2
  53. package/dist/{index-BY8yQ8N8.d.mts → index-BMZdjGT4.d.mts} +46 -3
  54. package/dist/{index-3NRaBNvp.d.mts → index-DlsYN3Et.d.mts} +1 -1
  55. package/dist/{index-CtYSYwn3.d.ts → index-Dm2xA6j1.d.ts} +46 -3
  56. package/dist/{index-CME6r4uH.d.ts → index-gM-lgX_X.d.ts} +1 -1
  57. package/dist/index.d.mts +7 -7
  58. package/dist/index.d.ts +7 -7
  59. package/dist/index.js +125 -25
  60. package/dist/index.js.map +1 -1
  61. package/dist/index.mjs +125 -25
  62. package/dist/index.mjs.map +1 -1
  63. package/dist/local-evaluator/evaluator.d.mts +2 -2
  64. package/dist/local-evaluator/evaluator.d.ts +2 -2
  65. package/dist/{nextjs-BQyMCSx_.d.mts → nextjs-BEqidT0U.d.mts} +1 -1
  66. package/dist/{nextjs-CEldnIJ9.d.ts → nextjs-yNzimC3a.d.ts} +1 -1
  67. package/dist/{sdk-BhvuJSrH.d.mts → sdk-7fa9H0qa.d.mts} +1 -1
  68. package/dist/{sdk-BlyVSC_S.d.ts → sdk-CP9C9Qu0.d.ts} +1 -1
  69. package/dist/transport/index.d.mts +2 -2
  70. package/dist/transport/index.d.ts +2 -2
  71. package/dist/{types-CxQwJKbd.d.mts → types-CrVMq_Td.d.mts} +30 -3
  72. package/dist/{types-CxQwJKbd.d.ts → types-CrVMq_Td.d.ts} +30 -3
  73. package/dist/{types-jJnPXStc.d.mts → types-DE0ooQJ6.d.mts} +1 -1
  74. package/dist/{types-79qS7aON.d.ts → types-rigu2bH3.d.ts} +1 -1
  75. package/dist/ui/index.d.mts +1 -1
  76. package/dist/ui/index.d.ts +1 -1
  77. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -226,21 +226,33 @@ async function callVerifyAccessAPI(config, request) {
226
226
  if (requestData.isSubAgentRequest) body.isSubAgentRequest = requestData.isSubAgentRequest;
227
227
  if (requestData.parentAgentId) body.parentAgentId = requestData.parentAgentId;
228
228
  if (requestData.subAgentDepth !== void 0) body.subAgentDepth = requestData.subAgentDepth;
229
- if (requestData.enableRuntimeChallenge) body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
229
+ if (requestData.enableRuntimeChallenge)
230
+ body.enableRuntimeChallenge = requestData.enableRuntimeChallenge;
230
231
  if (requestData.createSession) body.createSession = requestData.createSession;
231
232
  if (requestData.durationRequired) body.durationRequired = requestData.durationRequired;
232
233
  if (requestData.counterpartyType) body.counterpartyType = requestData.counterpartyType;
233
234
  if (requestData.counterpartyUrl) body.counterpartyUrl = requestData.counterpartyUrl;
234
- if (requestData.runtimeChallengeOptions) body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
235
+ if (requestData.runtimeChallengeOptions)
236
+ body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
237
+ if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
238
+ const meta = {
239
+ ...requestData.clientIp && { sourceIp: requestData.clientIp },
240
+ ...requestData.userAgent && { userAgent: requestData.userAgent },
241
+ ...requestData.callerMetadata
242
+ };
243
+ if (Object.keys(meta).length > 0) body.callerMetadata = meta;
244
+ }
235
245
  const headers = {
236
246
  "Content-Type": "application/json",
237
247
  ...config.customHeaders
238
248
  };
239
- if (config.apiKey) {
240
- headers["X-API-Key"] = config.apiKey;
241
- }
242
249
  if (credentials.authorizationHeader) {
243
250
  headers["Authorization"] = credentials.authorizationHeader;
251
+ } else if (config.apiKey) {
252
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
253
+ }
254
+ if (config.apiKey) {
255
+ headers["X-API-Key"] = config.apiKey;
244
256
  }
245
257
  try {
246
258
  const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
@@ -341,16 +353,11 @@ async function verify(config, request) {
341
353
  } : void 0;
342
354
  const trustScore = agent?.trustScore || 0;
343
355
  const isOrgMember = false;
344
- const accessLevel = determineAccessLevel(
345
- true,
346
- trustScore,
347
- isOrgMember,
348
- {
349
- "read-only": 20,
350
- standard: mergedConfig.minTrustScore || 40,
351
- full: mergedConfig.minTrustScoreForFull || 70
352
- }
353
- );
356
+ const accessLevel = determineAccessLevel(true, trustScore, isOrgMember, {
357
+ "read-only": 20,
358
+ standard: mergedConfig.minTrustScore || 40,
359
+ full: mergedConfig.minTrustScoreForFull || 70
360
+ });
354
361
  const result = {
355
362
  verified: true,
356
363
  accessLevel,
@@ -372,7 +379,9 @@ async function verify(config, request) {
372
379
  if (result.recommendation === "deny") {
373
380
  result.verified = false;
374
381
  result.accessLevel = "none";
375
- result.denialReasons = result.recommendationReasons || ["Access denied by AstraSync recommendation"];
382
+ result.denialReasons = result.recommendationReasons || [
383
+ "Access denied by AstraSync recommendation"
384
+ ];
376
385
  if (result.runtimeChallenge) {
377
386
  result.guidance = {
378
387
  message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
@@ -394,7 +403,10 @@ async function verify(config, request) {
394
403
  }
395
404
  async function recordDecision(config, sessionId, decision, reason) {
396
405
  const headers = { "Content-Type": "application/json" };
397
- if (config.apiKey) headers["X-API-Key"] = config.apiKey;
406
+ if (config.apiKey) {
407
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
408
+ headers["X-API-Key"] = config.apiKey;
409
+ }
398
410
  await fetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
399
411
  method: "POST",
400
412
  headers,
@@ -692,18 +704,28 @@ function createMiddleware(options) {
692
704
  return;
693
705
  }
694
706
  const shouldRecordDecisions = recordDecisions !== false;
707
+ const forwardedFor = req.headers["x-forwarded-for"];
708
+ const forwardedForStr = Array.isArray(forwardedFor) ? forwardedFor.join(", ") : forwardedFor;
709
+ const originalClientIp = forwardedForStr ? forwardedForStr.split(",")[0].trim() : req.ip;
710
+ const agentCardUrl = typeof req.headers["x-astrasync-agent-card"] === "string" ? req.headers["x-astrasync-agent-card"] : void 0;
695
711
  const result = await verify(config, {
696
712
  credentials,
697
713
  purpose,
698
714
  action: req.method.toLowerCase(),
699
715
  resource: req.path,
700
- clientIp: req.ip,
701
- userAgent: req.headers["user-agent"],
702
716
  createSession: shouldRecordDecisions,
703
717
  counterpartyUrl,
704
718
  counterpartyType: config.counterpartyType || "api",
705
719
  enableRuntimeChallenge,
706
- durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration
720
+ durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration,
721
+ callerMetadata: {
722
+ sourceIp: originalClientIp,
723
+ userAgent: req.headers["user-agent"],
724
+ referer: req.headers.referer,
725
+ host: req.headers.host,
726
+ forwardedFor: forwardedForStr,
727
+ agentCardUrl
728
+ }
707
729
  });
708
730
  req.agentVerification = result;
709
731
  const sessionId = result.sessionId;
@@ -975,7 +997,13 @@ function generateCommerceShieldHtml(result, options) {
975
997
  `.trim();
976
998
  }
977
999
  function createMiddleware2(options) {
978
- const { routes = [], skipPaths = [], showCommerceShield = true, enableRuntimeChallenge = true, ...config } = options;
1000
+ const {
1001
+ routes = [],
1002
+ skipPaths = [],
1003
+ showCommerceShield = true,
1004
+ enableRuntimeChallenge = true,
1005
+ ...config
1006
+ } = options;
979
1007
  return async function middleware(request) {
980
1008
  const { NextResponse } = await import("next/server");
981
1009
  const pathname = request.nextUrl.pathname;
@@ -1087,17 +1115,25 @@ function createMiddleware2(options) {
1087
1115
  }
1088
1116
  return NextResponse.redirect(new URL("/unauthorized", request.url));
1089
1117
  }
1118
+ const forwardedFor = request.headers.get("x-forwarded-for") || void 0;
1119
+ const originalClientIp = forwardedFor?.split(",")[0]?.trim();
1090
1120
  const result = await verify(config, {
1091
1121
  credentials,
1092
1122
  purpose,
1093
1123
  action: request.method.toLowerCase(),
1094
1124
  resource: pathname,
1095
- clientIp: request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || void 0,
1096
- userAgent: request.headers.get("user-agent") || void 0,
1097
1125
  counterpartyUrl,
1098
1126
  counterpartyType: config.counterpartyType || "website",
1099
1127
  enableRuntimeChallenge,
1100
- durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration
1128
+ durationRequired: astraCreds?.pdlss?.duration?.maxSessionDuration,
1129
+ callerMetadata: {
1130
+ sourceIp: originalClientIp,
1131
+ userAgent: request.headers.get("user-agent") || void 0,
1132
+ referer: request.headers.get("referer") || void 0,
1133
+ host: request.headers.get("host") || void 0,
1134
+ forwardedFor,
1135
+ agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
1136
+ }
1101
1137
  });
1102
1138
  if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
1103
1139
  if (pathname.startsWith("/api/")) {
@@ -3722,14 +3758,35 @@ function extractCredentialsFromProtocol(protocol, context) {
3722
3758
  var agent_exports = {};
3723
3759
  __export(agent_exports, {
3724
3760
  AgentClient: () => AgentClient,
3761
+ AstraSyncSdkError: () => AstraSyncSdkError,
3725
3762
  ChallengeHandler: () => ChallengeHandler,
3763
+ OwnershipMismatchError: () => OwnershipMismatchError,
3726
3764
  formatPDLSSForTransport: () => formatPDLSSForTransport,
3727
3765
  parsePDLSSFromTransport: () => parsePDLSSFromTransport,
3728
3766
  recordDecision: () => recordDecision2
3729
3767
  });
3730
3768
 
3769
+ // src/agent/errors.ts
3770
+ var AstraSyncSdkError = class extends Error {
3771
+ constructor(code, message) {
3772
+ super(message);
3773
+ this.name = "AstraSyncSdkError";
3774
+ this.code = code;
3775
+ }
3776
+ };
3777
+ var OwnershipMismatchError = class extends AstraSyncSdkError {
3778
+ constructor(astraId) {
3779
+ super(
3780
+ "ownership_mismatch",
3781
+ `The configured API key does not own agent ${astraId}. Refusing to initialise.`
3782
+ );
3783
+ this.name = "OwnershipMismatchError";
3784
+ this.astraId = astraId;
3785
+ }
3786
+ };
3787
+
3731
3788
  // src/agent/client.ts
3732
- var AgentClient = class {
3789
+ var AgentClient = class _AgentClient {
3733
3790
  constructor(config) {
3734
3791
  this.credentials = {
3735
3792
  agentId: config.agentId,
@@ -3737,6 +3794,49 @@ var AgentClient = class {
3737
3794
  challengeUrl: config.challengeUrl,
3738
3795
  pdlss: config.pdlss
3739
3796
  };
3797
+ this.apiBaseUrl = config.apiBaseUrl ?? "https://api.astrasync.ai";
3798
+ this.apiKey = config.apiKey;
3799
+ }
3800
+ /**
3801
+ * Async factory that validates the API key's account owns the configured
3802
+ * ASTRA-id before returning a usable client. Refuses to initialise on
3803
+ * mismatch so a stolen ASTRA-id cannot be paired with a valid (different)
3804
+ * API key.
3805
+ *
3806
+ * Set env `ASTRASYNC_SKIP_OWNERSHIP_CHECK=true` to bypass — intended for
3807
+ * test environments only.
3808
+ */
3809
+ static async create(config) {
3810
+ const client = new _AgentClient(config);
3811
+ const skip = typeof process !== "undefined" && process.env?.ASTRASYNC_SKIP_OWNERSHIP_CHECK === "true";
3812
+ if (skip) return client;
3813
+ if (!config.apiKey) {
3814
+ throw new OwnershipMismatchError(config.agentId);
3815
+ }
3816
+ const owned = await client.verifyOwnership();
3817
+ if (!owned) throw new OwnershipMismatchError(config.agentId);
3818
+ return client;
3819
+ }
3820
+ /**
3821
+ * Calls GET /api/agents/:astraId/ownership with the configured API key.
3822
+ * Returns true only when the backend confirms this API key's account
3823
+ * owns the configured agent.
3824
+ */
3825
+ async verifyOwnership() {
3826
+ if (!this.apiKey) return false;
3827
+ const url = `${this.apiBaseUrl.replace(/\/+$/, "")}/api/agents/${encodeURIComponent(
3828
+ this.credentials.agentId
3829
+ )}/ownership`;
3830
+ const resp = await fetch(url, {
3831
+ method: "GET",
3832
+ headers: {
3833
+ Authorization: `Bearer ${this.apiKey}`,
3834
+ "Content-Type": "application/json"
3835
+ }
3836
+ });
3837
+ if (!resp.ok) return false;
3838
+ const body = await resp.json().catch(() => null);
3839
+ return Boolean(body?.data?.owned);
3740
3840
  }
3741
3841
  /**
3742
3842
  * Make an HTTP request with AstraSync headers automatically injected.