@astrasyncai/verification-gateway 2.4.12 → 2.5.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 (91) 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 +224 -42
  6. package/dist/adapters/express.js.map +1 -1
  7. package/dist/adapters/express.mjs +224 -42
  8. package/dist/adapters/express.mjs.map +1 -1
  9. package/dist/adapters/mcp.d.mts +101 -57
  10. package/dist/adapters/mcp.d.ts +101 -57
  11. package/dist/adapters/mcp.js +215 -44
  12. package/dist/adapters/mcp.js.map +1 -1
  13. package/dist/adapters/mcp.mjs +215 -44
  14. package/dist/adapters/mcp.mjs.map +1 -1
  15. package/dist/adapters/nextjs.d.mts +2 -2
  16. package/dist/adapters/nextjs.d.ts +2 -2
  17. package/dist/adapters/nextjs.js +87 -34
  18. package/dist/adapters/nextjs.js.map +1 -1
  19. package/dist/adapters/nextjs.mjs +87 -34
  20. package/dist/adapters/nextjs.mjs.map +1 -1
  21. package/dist/adapters/sdk.d.mts +2 -2
  22. package/dist/adapters/sdk.d.ts +2 -2
  23. package/dist/adapters/sdk.js +61 -28
  24. package/dist/adapters/sdk.js.map +1 -1
  25. package/dist/adapters/sdk.mjs +61 -28
  26. package/dist/adapters/sdk.mjs.map +1 -1
  27. package/dist/agent/index.d.mts +2 -2
  28. package/dist/agent/index.d.ts +2 -2
  29. package/dist/agent/index.js +29 -0
  30. package/dist/agent/index.js.map +1 -1
  31. package/dist/agent/index.mjs +29 -0
  32. package/dist/agent/index.mjs.map +1 -1
  33. package/dist/browser/background.js +102 -30
  34. package/dist/browser/background.js.map +1 -1
  35. package/dist/browser/background.mjs +102 -30
  36. package/dist/browser/background.mjs.map +1 -1
  37. package/dist/browser/browser-adapter.d.mts +2 -2
  38. package/dist/browser/browser-adapter.d.ts +2 -2
  39. package/dist/cli/index.d.mts +2 -2
  40. package/dist/cli/index.d.ts +2 -2
  41. package/dist/cursor/cursor-adapter.d.mts +2 -2
  42. package/dist/cursor/cursor-adapter.d.ts +2 -2
  43. package/dist/cursor/extension.d.mts +2 -2
  44. package/dist/cursor/extension.d.ts +2 -2
  45. package/dist/cursor/extension.js +102 -30
  46. package/dist/cursor/extension.js.map +1 -1
  47. package/dist/cursor/extension.mjs +102 -30
  48. package/dist/cursor/extension.mjs.map +1 -1
  49. package/dist/{express-C1ePFB7n.d.ts → express-CrfwoNAR.d.ts} +1 -1
  50. package/dist/{express-4WStX3PV.d.mts → express-ienhAXps.d.mts} +1 -1
  51. package/dist/gateway/gateway.d.mts +2 -2
  52. package/dist/gateway/gateway.d.ts +2 -2
  53. package/dist/gateway/gateway.js +102 -30
  54. package/dist/gateway/gateway.js.map +1 -1
  55. package/dist/gateway/gateway.mjs +102 -30
  56. package/dist/gateway/gateway.mjs.map +1 -1
  57. package/dist/git-trigger/git-hooks.d.mts +2 -2
  58. package/dist/git-trigger/git-hooks.d.ts +2 -2
  59. package/dist/{index-ChPX4WHl.d.mts → index-B5e2IDWU.d.mts} +1 -1
  60. package/dist/{index-CzJMCgEy.d.ts → index-CCdZxvAr.d.ts} +71 -6
  61. package/dist/{index-D8IEntil.d.mts → index-CEg_WG6y.d.mts} +71 -6
  62. package/dist/{index-Cjm-zBeZ.d.ts → index-DC5f8eoQ.d.ts} +1 -1
  63. package/dist/index.d.mts +39 -9
  64. package/dist/index.d.ts +39 -9
  65. package/dist/index.js +500 -94
  66. package/dist/index.js.map +1 -1
  67. package/dist/index.mjs +497 -94
  68. package/dist/index.mjs.map +1 -1
  69. package/dist/local-evaluator/evaluator.d.mts +2 -2
  70. package/dist/local-evaluator/evaluator.d.ts +2 -2
  71. package/dist/local-evaluator/evaluator.js +12 -2
  72. package/dist/local-evaluator/evaluator.js.map +1 -1
  73. package/dist/local-evaluator/evaluator.mjs +12 -2
  74. package/dist/local-evaluator/evaluator.mjs.map +1 -1
  75. package/dist/{nextjs-BIORS__0.d.ts → nextjs-66R1KW8e.d.ts} +1 -1
  76. package/dist/{nextjs-CjzHdaXA.d.mts → nextjs-DSpisQst.d.mts} +1 -1
  77. package/dist/{sdk-Chhz-FcT.d.mts → sdk-5U_CBRpr.d.mts} +1 -1
  78. package/dist/{sdk-CqTEQAc6.d.ts → sdk-Bm8np66n.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/transport/index.js +146 -28
  82. package/dist/transport/index.js.map +1 -1
  83. package/dist/transport/index.mjs +146 -28
  84. package/dist/transport/index.mjs.map +1 -1
  85. package/dist/{types-L15pYd2c.d.mts → types-B3USs-Kx.d.mts} +42 -1
  86. package/dist/{types-L15pYd2c.d.ts → types-B3USs-Kx.d.ts} +42 -1
  87. package/dist/{types-DNK2BgIf.d.mts → types-CgDCUfo8.d.mts} +1 -1
  88. package/dist/{types-DoWIuzfj.d.ts → types-R5N4ET6x.d.ts} +1 -1
  89. package/dist/ui/index.d.mts +1 -1
  90. package/dist/ui/index.d.ts +1 -1
  91. package/package.json +1 -1
@@ -346,7 +346,10 @@ var LocalEvaluator = class {
346
346
  }
347
347
  const depth = context.metadata?.subAgentDepth || 0;
348
348
  if (this.policy.selfInstantiation.maxDepth !== void 0 && depth >= this.policy.selfInstantiation.maxDepth) {
349
- return { recommendation: "DENY", reason: `Sub-agent depth ${depth} exceeds max depth ${this.policy.selfInstantiation.maxDepth}` };
349
+ return {
350
+ recommendation: "DENY",
351
+ reason: `Sub-agent depth ${depth} exceeds max depth ${this.policy.selfInstantiation.maxDepth}`
352
+ };
350
353
  }
351
354
  }
352
355
  if (purposeRule.requiresApproval) {
@@ -427,7 +430,10 @@ var LocalEvaluator = class {
427
430
  return { recommendation: "DENY", reason: `Risk score ${riskScore} exceeds block threshold` };
428
431
  }
429
432
  if (riskScore >= thresholds.requireApproval.min) {
430
- return { recommendation: "MANUAL_REVIEW", reason: `Risk score ${riskScore} requires approval` };
433
+ return {
434
+ recommendation: "MANUAL_REVIEW",
435
+ reason: `Risk score ${riskScore} requires approval`
436
+ };
431
437
  }
432
438
  return null;
433
439
  }
@@ -492,6 +498,10 @@ var LocalEvaluator = class {
492
498
  */
493
499
  matchGlob(value, pattern) {
494
500
  if (pattern === value) return true;
501
+ const starCount = (pattern.match(/\*/g) ?? []).length;
502
+ if (starCount > 8) {
503
+ return false;
504
+ }
495
505
  const regexStr = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
496
506
  try {
497
507
  return new RegExp(`^${regexStr}$`, "i").test(value);
@@ -3295,7 +3305,14 @@ function getTrustLevel(score) {
3295
3305
  }
3296
3306
 
3297
3307
  // src/version.ts
3298
- var SDK_VERSION = "2.4.12";
3308
+ var SDK_VERSION = "2.4.13";
3309
+
3310
+ // src/well-known.ts
3311
+ var CACHE_TTL_MS = 60 * 60 * 1e3;
3312
+ var cache = /* @__PURE__ */ new Map();
3313
+ function getCachedWellKnownUrls(apiBaseUrl) {
3314
+ return cache.get(apiBaseUrl)?.data;
3315
+ }
3299
3316
 
3300
3317
  // src/verify.ts
3301
3318
  var DEFAULT_CONFIG = {
@@ -3314,22 +3331,27 @@ var DEFAULT_CONFIG = {
3314
3331
  };
3315
3332
  var initCheckPerformed = false;
3316
3333
  var deprecationWarningShown = false;
3317
- async function performInitCheck(apiBaseUrl, debug) {
3334
+ async function performInitCheck(apiBaseUrl, debug, strictInit) {
3318
3335
  initCheckPerformed = true;
3319
3336
  try {
3320
3337
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
3321
3338
  const response = await fetch(probeUrl, { method: "HEAD" });
3322
3339
  const contentType = response.headers.get("content-type") ?? "";
3323
3340
  if (contentType.startsWith("text/html")) {
3324
- console.warn(
3325
- `[VerificationGateway] apiBaseUrl '${apiBaseUrl}' returned HTML (content-type: ${contentType}). This usually means apiBaseUrl is pointing at a marketing site instead of the API. Expected: 'https://astrasync.ai/api' (prod) or 'https://staging.astrasync.ai/api' (staging). Set disableInitChecks: true on GatewayConfig to silence this warning.`
3326
- );
3341
+ const message = `[VerificationGateway] apiBaseUrl '${apiBaseUrl}' returned HTML (content-type: ${contentType}). This usually means apiBaseUrl is pointing at a marketing site instead of the API. Expected: 'https://astrasync.ai/api' (prod) or 'https://staging.astrasync.ai/api' (staging).`;
3342
+ if (strictInit) {
3343
+ throw new Error(`${message} (strictInit=true)`);
3344
+ }
3345
+ console.warn(`${message} Set disableInitChecks: true on GatewayConfig to silence.`);
3327
3346
  } else if (debug) {
3328
3347
  console.log(
3329
3348
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
3330
3349
  );
3331
3350
  }
3332
3351
  } catch (err) {
3352
+ if (strictInit) {
3353
+ throw err;
3354
+ }
3333
3355
  if (debug) {
3334
3356
  console.log(`[VerificationGateway] init check failed (non-blocking): ${String(err)}`);
3335
3357
  }
@@ -3353,7 +3375,23 @@ function getCacheKey(request) {
3353
3375
  request.counterpartyType || "",
3354
3376
  request.isSubAgentRequest ? "1" : "0",
3355
3377
  request.parentAgentId || "",
3356
- request.subAgentDepth ?? ""
3378
+ request.subAgentDepth ?? "",
3379
+ // Audit F-A1-07: previously-missing dimensions that DO affect the
3380
+ // backend verdict. Without these, two requests with different
3381
+ // durations (e.g. 60s vs 86400s) collided on the same cache key and
3382
+ // the shorter-duration allow served the longer-duration request.
3383
+ request.durationRequired ?? "",
3384
+ request.invocationProtocol || "",
3385
+ request.enableRuntimeChallenge ? "1" : "0",
3386
+ // callerMetadata fields contribute to risk model; include the ones
3387
+ // backend reads. sourceIp/userAgent/forwardedFor change per-request
3388
+ // so their inclusion effectively forces a re-check for any varying
3389
+ // client (the right behavior — IP-driven anomaly scoring shouldn't
3390
+ // be cached across IPs).
3391
+ request.callerMetadata?.sourceIp || "",
3392
+ request.callerMetadata?.userAgent || "",
3393
+ request.callerMetadata?.forwardedFor || "",
3394
+ request.callerMetadata?.agentCardUrl || ""
3357
3395
  ].join("|");
3358
3396
  }
3359
3397
  function getCachedResult(request) {
@@ -3377,21 +3415,22 @@ function cacheResult(request, result, configuredTtl) {
3377
3415
  expiresAt: Date.now() + ttlSeconds * 1e3
3378
3416
  });
3379
3417
  }
3380
- function createGuidanceResponse(config, reason, options = {}) {
3418
+ function createGuidanceResponse(_config, reason, options = {}) {
3381
3419
  const source = options.source ?? "no_credentials";
3382
3420
  const isApiError = source === "api_error";
3421
+ const urls = options.urls;
3383
3422
  const guidance = isApiError ? {
3384
3423
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
3385
- registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/register`,
3386
- documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
3424
+ registrationUrl: urls?.registrationUrl ?? "",
3425
+ documentationUrl: urls?.documentationUrl ?? "",
3387
3426
  steps: [
3388
3427
  "Retry the request with exponential backoff",
3389
3428
  "If failures persist, share the correlationId with support"
3390
3429
  ]
3391
3430
  } : {
3392
3431
  message: "This service verifies AI agents before granting access. Please register your agent with AstraSync.",
3393
- registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/register`,
3394
- documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
3432
+ registrationUrl: urls?.registrationUrl ?? "",
3433
+ documentationUrl: urls?.documentationUrl ?? "",
3395
3434
  steps: [
3396
3435
  "Register for an AstraSync account",
3397
3436
  "Create and register your agent",
@@ -3433,7 +3472,7 @@ async function callVerifyAccessAPI(config, request) {
3433
3472
  const { credentials, ...requestData } = request;
3434
3473
  const body = {
3435
3474
  ...credentials.astraId && { agentId: credentials.astraId },
3436
- purpose: requestData.purpose || "general"
3475
+ ...requestData.purpose && { purpose: requestData.purpose }
3437
3476
  };
3438
3477
  if (requestData.action) body.action = requestData.action;
3439
3478
  if (requestData.resourceType) body.resourceType = requestData.resourceType;
@@ -3467,12 +3506,8 @@ async function callVerifyAccessAPI(config, request) {
3467
3506
  "Content-Type": "application/json",
3468
3507
  ...config.customHeaders
3469
3508
  };
3470
- if (credentials.authorizationHeader) {
3471
- headers["Authorization"] = credentials.authorizationHeader;
3472
- } else if (config.apiKey) {
3473
- headers["Authorization"] = `Bearer ${config.apiKey}`;
3474
- }
3475
3509
  if (config.apiKey) {
3510
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
3476
3511
  headers["X-API-Key"] = config.apiKey;
3477
3512
  }
3478
3513
  try {
@@ -3517,8 +3552,13 @@ async function callVerifyAccessAPI(config, request) {
3517
3552
  }
3518
3553
  async function verify(config, request) {
3519
3554
  const mergedConfig = { ...DEFAULT_CONFIG, ...config };
3555
+ const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
3520
3556
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
3521
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug);
3557
+ if (mergedConfig.strictInit) {
3558
+ await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
3559
+ } else {
3560
+ void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
3561
+ }
3522
3562
  }
3523
3563
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
3524
3564
  deprecationWarningShown = true;
@@ -3549,7 +3589,8 @@ async function verify(config, request) {
3549
3589
  if (!apiResponse.success) {
3550
3590
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
3551
3591
  source: "api_error",
3552
- correlationId: apiResponse.correlationId
3592
+ correlationId: apiResponse.correlationId,
3593
+ urls
3553
3594
  });
3554
3595
  }
3555
3596
  if (!apiResponse.access?.allowed) {
@@ -3572,8 +3613,8 @@ async function verify(config, request) {
3572
3613
  requiresApproval: apiResponse.access?.requiresApproval,
3573
3614
  guidance: {
3574
3615
  message: apiResponse.access?.reason || "Access denied by PDLSS policy",
3575
- registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/register`,
3576
- documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/pdlss`
3616
+ registrationUrl: urls?.registrationUrl ?? "",
3617
+ documentationUrl: urls?.documentationUrl ?? ""
3577
3618
  },
3578
3619
  verifiedAt: /* @__PURE__ */ new Date(),
3579
3620
  // Extract sessionId so decisions can be recorded for denials too
@@ -3642,13 +3683,15 @@ async function verify(config, request) {
3642
3683
  result.denialReasons = result.recommendationReasons || [
3643
3684
  "Access denied by AstraSync recommendation"
3644
3685
  ];
3645
- if (result.runtimeChallenge) {
3646
- result.guidance = {
3647
- message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
3648
- registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/register`,
3649
- documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/runtime-challenge`
3650
- };
3651
- }
3686
+ result.guidance = result.runtimeChallenge ? {
3687
+ message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
3688
+ registrationUrl: urls?.registrationUrl ?? "",
3689
+ documentationUrl: urls?.documentationUrl ?? ""
3690
+ } : {
3691
+ message: result.recommendationReasons?.[0] || "Access denied by AstraSync recommendation",
3692
+ registrationUrl: urls?.registrationUrl ?? "",
3693
+ documentationUrl: urls?.documentationUrl ?? ""
3694
+ };
3652
3695
  } else if (result.recommendation === "step_up_required") {
3653
3696
  result.requiresStepUp = true;
3654
3697
  if (ACCESS_LEVEL_HIERARCHY[result.accessLevel] > ACCESS_LEVEL_HIERARCHY["read-only"]) {
@@ -3674,6 +3717,35 @@ var import_structured_headers = require("structured-headers");
3674
3717
  // src/transport/rfc9421-verify.ts
3675
3718
  var import_http_message_signatures = require("http-message-signatures");
3676
3719
 
3720
+ // src/transport/nonce-store.ts
3721
+ var InMemoryNonceStore = class {
3722
+ constructor(capacity = 1e4) {
3723
+ this.entries = /* @__PURE__ */ new Map();
3724
+ this.lastSweepMs = 0;
3725
+ this.capacity = capacity;
3726
+ }
3727
+ seen(key, expiresAtMs) {
3728
+ const nowMs = Date.now();
3729
+ if (nowMs - this.lastSweepMs > 1e3) {
3730
+ for (const [k, exp] of this.entries) {
3731
+ if (exp <= nowMs) this.entries.delete(k);
3732
+ }
3733
+ this.lastSweepMs = nowMs;
3734
+ }
3735
+ const existing = this.entries.get(key);
3736
+ if (existing !== void 0 && existing > nowMs) {
3737
+ return true;
3738
+ }
3739
+ if (this.entries.size >= this.capacity) {
3740
+ const oldest = this.entries.keys().next().value;
3741
+ if (oldest !== void 0) this.entries.delete(oldest);
3742
+ }
3743
+ this.entries.set(key, expiresAtMs);
3744
+ return false;
3745
+ }
3746
+ };
3747
+ var defaultNonceStore = new InMemoryNonceStore();
3748
+
3677
3749
  // src/transport/vi.ts
3678
3750
  var import_decode = require("@sd-jwt/decode");
3679
3751
  var import_node_crypto = require("crypto");