@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
@@ -1,5 +1,5 @@
1
1
  import { RequestHandler, Request } from 'express';
2
- import { i as VerificationResult, d as ExpressMiddlewareOptions, b as AstraSyncCredentials } from './types-L15pYd2c.js';
2
+ import { i as VerificationResult, d as ExpressMiddlewareOptions, b as AstraSyncCredentials } from './types-B3USs-Kx.js';
3
3
 
4
4
  /**
5
5
  * AstraSync Universal Verification Gateway - Express Middleware
@@ -1,5 +1,5 @@
1
1
  import { RequestHandler, Request } from 'express';
2
- import { i as VerificationResult, d as ExpressMiddlewareOptions, b as AstraSyncCredentials } from './types-L15pYd2c.mjs';
2
+ import { i as VerificationResult, d as ExpressMiddlewareOptions, b as AstraSyncCredentials } from './types-B3USs-Kx.mjs';
3
3
 
4
4
  /**
5
5
  * AstraSync Universal Verification Gateway - Express Middleware
@@ -1,5 +1,5 @@
1
- import { a as AstraSyncGatewayConfig, P as PDLSSContext, V as VerificationDecision } from '../types-DNK2BgIf.mjs';
2
- import '../types-L15pYd2c.mjs';
1
+ import { a as AstraSyncGatewayConfig, P as PDLSSContext, V as VerificationDecision } from '../types-CgDCUfo8.mjs';
2
+ import '../types-B3USs-Kx.mjs';
3
3
 
4
4
  /**
5
5
  * AstraSyncGateway — Primary API surface for agent verification.
@@ -1,5 +1,5 @@
1
- import { a as AstraSyncGatewayConfig, P as PDLSSContext, V as VerificationDecision } from '../types-DoWIuzfj.js';
2
- import '../types-L15pYd2c.js';
1
+ import { a as AstraSyncGatewayConfig, P as PDLSSContext, V as VerificationDecision } from '../types-R5N4ET6x.js';
2
+ import '../types-B3USs-Kx.js';
3
3
 
4
4
  /**
5
5
  * AstraSyncGateway — Primary API surface for agent verification.
@@ -106,7 +106,10 @@ var LocalEvaluator = class {
106
106
  }
107
107
  const depth = context.metadata?.subAgentDepth || 0;
108
108
  if (this.policy.selfInstantiation.maxDepth !== void 0 && depth >= this.policy.selfInstantiation.maxDepth) {
109
- return { recommendation: "DENY", reason: `Sub-agent depth ${depth} exceeds max depth ${this.policy.selfInstantiation.maxDepth}` };
109
+ return {
110
+ recommendation: "DENY",
111
+ reason: `Sub-agent depth ${depth} exceeds max depth ${this.policy.selfInstantiation.maxDepth}`
112
+ };
110
113
  }
111
114
  }
112
115
  if (purposeRule.requiresApproval) {
@@ -187,7 +190,10 @@ var LocalEvaluator = class {
187
190
  return { recommendation: "DENY", reason: `Risk score ${riskScore} exceeds block threshold` };
188
191
  }
189
192
  if (riskScore >= thresholds.requireApproval.min) {
190
- return { recommendation: "MANUAL_REVIEW", reason: `Risk score ${riskScore} requires approval` };
193
+ return {
194
+ recommendation: "MANUAL_REVIEW",
195
+ reason: `Risk score ${riskScore} requires approval`
196
+ };
191
197
  }
192
198
  return null;
193
199
  }
@@ -252,6 +258,10 @@ var LocalEvaluator = class {
252
258
  */
253
259
  matchGlob(value, pattern) {
254
260
  if (pattern === value) return true;
261
+ const starCount = (pattern.match(/\*/g) ?? []).length;
262
+ if (starCount > 8) {
263
+ return false;
264
+ }
255
265
  const regexStr = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
256
266
  try {
257
267
  return new RegExp(`^${regexStr}$`, "i").test(value);
@@ -3055,7 +3065,14 @@ function getTrustLevel(score) {
3055
3065
  }
3056
3066
 
3057
3067
  // src/version.ts
3058
- var SDK_VERSION = "2.4.12";
3068
+ var SDK_VERSION = "2.4.13";
3069
+
3070
+ // src/well-known.ts
3071
+ var CACHE_TTL_MS = 60 * 60 * 1e3;
3072
+ var cache = /* @__PURE__ */ new Map();
3073
+ function getCachedWellKnownUrls(apiBaseUrl) {
3074
+ return cache.get(apiBaseUrl)?.data;
3075
+ }
3059
3076
 
3060
3077
  // src/verify.ts
3061
3078
  var DEFAULT_CONFIG = {
@@ -3074,22 +3091,27 @@ var DEFAULT_CONFIG = {
3074
3091
  };
3075
3092
  var initCheckPerformed = false;
3076
3093
  var deprecationWarningShown = false;
3077
- async function performInitCheck(apiBaseUrl, debug) {
3094
+ async function performInitCheck(apiBaseUrl, debug, strictInit) {
3078
3095
  initCheckPerformed = true;
3079
3096
  try {
3080
3097
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
3081
3098
  const response = await fetch(probeUrl, { method: "HEAD" });
3082
3099
  const contentType = response.headers.get("content-type") ?? "";
3083
3100
  if (contentType.startsWith("text/html")) {
3084
- console.warn(
3085
- `[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.`
3086
- );
3101
+ 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).`;
3102
+ if (strictInit) {
3103
+ throw new Error(`${message} (strictInit=true)`);
3104
+ }
3105
+ console.warn(`${message} Set disableInitChecks: true on GatewayConfig to silence.`);
3087
3106
  } else if (debug) {
3088
3107
  console.log(
3089
3108
  `[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
3090
3109
  );
3091
3110
  }
3092
3111
  } catch (err) {
3112
+ if (strictInit) {
3113
+ throw err;
3114
+ }
3093
3115
  if (debug) {
3094
3116
  console.log(`[VerificationGateway] init check failed (non-blocking): ${String(err)}`);
3095
3117
  }
@@ -3113,7 +3135,23 @@ function getCacheKey(request) {
3113
3135
  request.counterpartyType || "",
3114
3136
  request.isSubAgentRequest ? "1" : "0",
3115
3137
  request.parentAgentId || "",
3116
- request.subAgentDepth ?? ""
3138
+ request.subAgentDepth ?? "",
3139
+ // Audit F-A1-07: previously-missing dimensions that DO affect the
3140
+ // backend verdict. Without these, two requests with different
3141
+ // durations (e.g. 60s vs 86400s) collided on the same cache key and
3142
+ // the shorter-duration allow served the longer-duration request.
3143
+ request.durationRequired ?? "",
3144
+ request.invocationProtocol || "",
3145
+ request.enableRuntimeChallenge ? "1" : "0",
3146
+ // callerMetadata fields contribute to risk model; include the ones
3147
+ // backend reads. sourceIp/userAgent/forwardedFor change per-request
3148
+ // so their inclusion effectively forces a re-check for any varying
3149
+ // client (the right behavior — IP-driven anomaly scoring shouldn't
3150
+ // be cached across IPs).
3151
+ request.callerMetadata?.sourceIp || "",
3152
+ request.callerMetadata?.userAgent || "",
3153
+ request.callerMetadata?.forwardedFor || "",
3154
+ request.callerMetadata?.agentCardUrl || ""
3117
3155
  ].join("|");
3118
3156
  }
3119
3157
  function getCachedResult(request) {
@@ -3137,21 +3175,22 @@ function cacheResult(request, result, configuredTtl) {
3137
3175
  expiresAt: Date.now() + ttlSeconds * 1e3
3138
3176
  });
3139
3177
  }
3140
- function createGuidanceResponse(config, reason, options = {}) {
3178
+ function createGuidanceResponse(_config, reason, options = {}) {
3141
3179
  const source = options.source ?? "no_credentials";
3142
3180
  const isApiError = source === "api_error";
3181
+ const urls = options.urls;
3143
3182
  const guidance = isApiError ? {
3144
3183
  message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
3145
- registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/register`,
3146
- documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
3184
+ registrationUrl: urls?.registrationUrl ?? "",
3185
+ documentationUrl: urls?.documentationUrl ?? "",
3147
3186
  steps: [
3148
3187
  "Retry the request with exponential backoff",
3149
3188
  "If failures persist, share the correlationId with support"
3150
3189
  ]
3151
3190
  } : {
3152
3191
  message: "This service verifies AI agents before granting access. Please register your agent with AstraSync.",
3153
- registrationUrl: `${config.apiBaseUrl.replace("/api", "")}/register`,
3154
- documentationUrl: `${config.apiBaseUrl.replace("/api", "")}/docs/agent-access`,
3192
+ registrationUrl: urls?.registrationUrl ?? "",
3193
+ documentationUrl: urls?.documentationUrl ?? "",
3155
3194
  steps: [
3156
3195
  "Register for an AstraSync account",
3157
3196
  "Create and register your agent",
@@ -3193,7 +3232,7 @@ async function callVerifyAccessAPI(config, request) {
3193
3232
  const { credentials, ...requestData } = request;
3194
3233
  const body = {
3195
3234
  ...credentials.astraId && { agentId: credentials.astraId },
3196
- purpose: requestData.purpose || "general"
3235
+ ...requestData.purpose && { purpose: requestData.purpose }
3197
3236
  };
3198
3237
  if (requestData.action) body.action = requestData.action;
3199
3238
  if (requestData.resourceType) body.resourceType = requestData.resourceType;
@@ -3227,12 +3266,8 @@ async function callVerifyAccessAPI(config, request) {
3227
3266
  "Content-Type": "application/json",
3228
3267
  ...config.customHeaders
3229
3268
  };
3230
- if (credentials.authorizationHeader) {
3231
- headers["Authorization"] = credentials.authorizationHeader;
3232
- } else if (config.apiKey) {
3233
- headers["Authorization"] = `Bearer ${config.apiKey}`;
3234
- }
3235
3269
  if (config.apiKey) {
3270
+ headers["Authorization"] = `Bearer ${config.apiKey}`;
3236
3271
  headers["X-API-Key"] = config.apiKey;
3237
3272
  }
3238
3273
  try {
@@ -3277,8 +3312,13 @@ async function callVerifyAccessAPI(config, request) {
3277
3312
  }
3278
3313
  async function verify(config, request) {
3279
3314
  const mergedConfig = { ...DEFAULT_CONFIG, ...config };
3315
+ const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
3280
3316
  if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
3281
- void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug);
3317
+ if (mergedConfig.strictInit) {
3318
+ await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
3319
+ } else {
3320
+ void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
3321
+ }
3282
3322
  }
3283
3323
  if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
3284
3324
  deprecationWarningShown = true;
@@ -3309,7 +3349,8 @@ async function verify(config, request) {
3309
3349
  if (!apiResponse.success) {
3310
3350
  return createGuidanceResponse(mergedConfig, apiResponse.error, {
3311
3351
  source: "api_error",
3312
- correlationId: apiResponse.correlationId
3352
+ correlationId: apiResponse.correlationId,
3353
+ urls
3313
3354
  });
3314
3355
  }
3315
3356
  if (!apiResponse.access?.allowed) {
@@ -3332,8 +3373,8 @@ async function verify(config, request) {
3332
3373
  requiresApproval: apiResponse.access?.requiresApproval,
3333
3374
  guidance: {
3334
3375
  message: apiResponse.access?.reason || "Access denied by PDLSS policy",
3335
- registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/register`,
3336
- documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/pdlss`
3376
+ registrationUrl: urls?.registrationUrl ?? "",
3377
+ documentationUrl: urls?.documentationUrl ?? ""
3337
3378
  },
3338
3379
  verifiedAt: /* @__PURE__ */ new Date(),
3339
3380
  // Extract sessionId so decisions can be recorded for denials too
@@ -3402,13 +3443,15 @@ async function verify(config, request) {
3402
3443
  result.denialReasons = result.recommendationReasons || [
3403
3444
  "Access denied by AstraSync recommendation"
3404
3445
  ];
3405
- if (result.runtimeChallenge) {
3406
- result.guidance = {
3407
- message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
3408
- registrationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/register`,
3409
- documentationUrl: `${mergedConfig.apiBaseUrl?.replace("/api", "")}/docs/runtime-challenge`
3410
- };
3411
- }
3446
+ result.guidance = result.runtimeChallenge ? {
3447
+ message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
3448
+ registrationUrl: urls?.registrationUrl ?? "",
3449
+ documentationUrl: urls?.documentationUrl ?? ""
3450
+ } : {
3451
+ message: result.recommendationReasons?.[0] || "Access denied by AstraSync recommendation",
3452
+ registrationUrl: urls?.registrationUrl ?? "",
3453
+ documentationUrl: urls?.documentationUrl ?? ""
3454
+ };
3412
3455
  } else if (result.recommendation === "step_up_required") {
3413
3456
  result.requiresStepUp = true;
3414
3457
  if (ACCESS_LEVEL_HIERARCHY[result.accessLevel] > ACCESS_LEVEL_HIERARCHY["read-only"]) {
@@ -3434,6 +3477,35 @@ var import_structured_headers = require("structured-headers");
3434
3477
  // src/transport/rfc9421-verify.ts
3435
3478
  var import_http_message_signatures = require("http-message-signatures");
3436
3479
 
3480
+ // src/transport/nonce-store.ts
3481
+ var InMemoryNonceStore = class {
3482
+ constructor(capacity = 1e4) {
3483
+ this.entries = /* @__PURE__ */ new Map();
3484
+ this.lastSweepMs = 0;
3485
+ this.capacity = capacity;
3486
+ }
3487
+ seen(key, expiresAtMs) {
3488
+ const nowMs = Date.now();
3489
+ if (nowMs - this.lastSweepMs > 1e3) {
3490
+ for (const [k, exp] of this.entries) {
3491
+ if (exp <= nowMs) this.entries.delete(k);
3492
+ }
3493
+ this.lastSweepMs = nowMs;
3494
+ }
3495
+ const existing = this.entries.get(key);
3496
+ if (existing !== void 0 && existing > nowMs) {
3497
+ return true;
3498
+ }
3499
+ if (this.entries.size >= this.capacity) {
3500
+ const oldest = this.entries.keys().next().value;
3501
+ if (oldest !== void 0) this.entries.delete(oldest);
3502
+ }
3503
+ this.entries.set(key, expiresAtMs);
3504
+ return false;
3505
+ }
3506
+ };
3507
+ var defaultNonceStore = new InMemoryNonceStore();
3508
+
3437
3509
  // src/transport/vi.ts
3438
3510
  var import_decode = require("@sd-jwt/decode");
3439
3511
  var import_node_crypto = require("crypto");