@astrasyncai/verification-gateway 5.11.0 → 5.12.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 (98) hide show
  1. package/README.md +4 -0
  2. package/dist/adapters/express.d.mts +1 -1
  3. package/dist/adapters/express.d.ts +1 -1
  4. package/dist/adapters/express.js +359 -30
  5. package/dist/adapters/express.js.map +1 -1
  6. package/dist/adapters/express.mjs +359 -30
  7. package/dist/adapters/express.mjs.map +1 -1
  8. package/dist/adapters/mcp.d.mts +5 -1
  9. package/dist/adapters/mcp.d.ts +5 -1
  10. package/dist/adapters/mcp.js +168 -41
  11. package/dist/adapters/mcp.js.map +1 -1
  12. package/dist/adapters/mcp.mjs +168 -41
  13. package/dist/adapters/mcp.mjs.map +1 -1
  14. package/dist/adapters/nextjs.d.mts +1 -1
  15. package/dist/adapters/nextjs.d.ts +1 -1
  16. package/dist/adapters/nextjs.js +352 -13
  17. package/dist/adapters/nextjs.js.map +1 -1
  18. package/dist/adapters/nextjs.mjs +352 -13
  19. package/dist/adapters/nextjs.mjs.map +1 -1
  20. package/dist/adapters/sdk.d.mts +9 -1
  21. package/dist/adapters/sdk.d.ts +9 -1
  22. package/dist/adapters/sdk.js +100 -8
  23. package/dist/adapters/sdk.js.map +1 -1
  24. package/dist/adapters/sdk.mjs +100 -8
  25. package/dist/adapters/sdk.mjs.map +1 -1
  26. package/dist/agent/index.js +1 -1
  27. package/dist/agent/index.js.map +1 -1
  28. package/dist/agent/index.mjs +1 -1
  29. package/dist/agent/index.mjs.map +1 -1
  30. package/dist/bin/astrasync-claude-hook.js +284 -7
  31. package/dist/bin/astrasync-codex-hook.js +284 -7
  32. package/dist/bin/astrasync-guard.js +284 -7
  33. package/dist/bin/astrasync.js +297 -9
  34. package/dist/browser/background.js +284 -7
  35. package/dist/browser/background.js.map +1 -1
  36. package/dist/browser/background.mjs +284 -7
  37. package/dist/browser/background.mjs.map +1 -1
  38. package/dist/cli/index.js +1 -1
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/index.mjs +1 -1
  41. package/dist/cli/index.mjs.map +1 -1
  42. package/dist/codex/index.js +284 -7
  43. package/dist/codex/index.js.map +1 -1
  44. package/dist/codex/index.mjs +284 -7
  45. package/dist/codex/index.mjs.map +1 -1
  46. package/dist/cursor/extension.js +284 -7
  47. package/dist/cursor/extension.js.map +1 -1
  48. package/dist/cursor/extension.mjs +284 -7
  49. package/dist/cursor/extension.mjs.map +1 -1
  50. package/dist/edge-config.d.mts +1 -1
  51. package/dist/edge-config.d.ts +1 -1
  52. package/dist/edge-config.js +1 -1
  53. package/dist/edge-config.js.map +1 -1
  54. package/dist/edge-config.mjs +1 -1
  55. package/dist/edge-config.mjs.map +1 -1
  56. package/dist/edge-core/index.d.mts +128 -13
  57. package/dist/edge-core/index.d.ts +128 -13
  58. package/dist/edge-core/index.js +337 -55
  59. package/dist/edge-core/index.js.map +1 -1
  60. package/dist/edge-core/index.mjs +334 -55
  61. package/dist/edge-core/index.mjs.map +1 -1
  62. package/dist/gateway/gateway.js +284 -7
  63. package/dist/gateway/gateway.js.map +1 -1
  64. package/dist/gateway/gateway.mjs +284 -7
  65. package/dist/gateway/gateway.mjs.map +1 -1
  66. package/dist/git-trigger/git-hooks.d.mts +1 -1
  67. package/dist/git-trigger/git-hooks.d.ts +1 -1
  68. package/dist/index.d.mts +118 -5
  69. package/dist/index.d.ts +118 -5
  70. package/dist/index.js +486 -63
  71. package/dist/index.js.map +1 -1
  72. package/dist/index.mjs +480 -63
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/platform-signatures.js +4 -1
  75. package/dist/platform-signatures.js.map +1 -1
  76. package/dist/platform-signatures.mjs +4 -1
  77. package/dist/platform-signatures.mjs.map +1 -1
  78. package/dist/registration/index.js +1 -1
  79. package/dist/registration/index.js.map +1 -1
  80. package/dist/registration/index.mjs +1 -1
  81. package/dist/registration/index.mjs.map +1 -1
  82. package/dist/transport/index.js +1 -1
  83. package/dist/transport/index.js.map +1 -1
  84. package/dist/transport/index.mjs +1 -1
  85. package/dist/transport/index.mjs.map +1 -1
  86. package/dist/{types-CTmUpNpS.d.mts → types-BCkwBA84.d.mts} +12 -0
  87. package/dist/{types-CTmUpNpS.d.ts → types-BCkwBA84.d.ts} +12 -0
  88. package/dist/{types-CtFXmDzm.d.ts → types-C_b4QTyO.d.ts} +18 -0
  89. package/dist/{types-DQrn_kei.d.mts → types-DlshIIR-.d.mts} +18 -0
  90. package/dist/ui/index.d.mts +1 -1
  91. package/dist/ui/index.d.ts +1 -1
  92. package/dist/verify.d.mts +35 -4
  93. package/dist/verify.d.ts +35 -4
  94. package/dist/verify.js +130 -16
  95. package/dist/verify.js.map +1 -1
  96. package/dist/verify.mjs +129 -16
  97. package/dist/verify.mjs.map +1 -1
  98. package/package.json +1 -1
package/dist/verify.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var SDK_VERSION = "5.11.0";
2
+ var SDK_VERSION = "5.12.0";
3
3
 
4
4
  // src/http.ts
5
5
  var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
@@ -34,6 +34,29 @@ function getCachedWellKnownUrls(apiBaseUrl) {
34
34
  return cache.get(apiBaseUrl)?.data;
35
35
  }
36
36
 
37
+ // src/failure-posture.ts
38
+ var DEFAULT_UNAVAILABLE_RETRY_AFTER_S = 30;
39
+ var REJECTED_IDENTITY_DIMENSIONS = /* @__PURE__ */ new Set([
40
+ "identity.invalid_agent_id",
41
+ "identity.unknown_agent",
42
+ "agent.lookup"
43
+ ]);
44
+ var UNKNOWN_AGENT_GUIDANCE = "Register your agent with AstraSync (or, inside an MCP host, add the AstraSync MCP connector for keyless, human-approved registration), then present the canonical ASTRA-* id issued after owner approval.";
45
+ var UNAVAILABLE_DIMENSIONS = /* @__PURE__ */ new Set([
46
+ "verify_access.api_error",
47
+ "middleware.internal_error"
48
+ ]);
49
+ function isVerificationUnavailable(result) {
50
+ if (result.misconfigured) return false;
51
+ return (result.failures ?? []).some((f) => UNAVAILABLE_DIMENSIONS.has(f.dimension));
52
+ }
53
+ function unavailableRetryAfterSeconds(result) {
54
+ if (typeof result.retryAfterMs === "number" && Number.isFinite(result.retryAfterMs)) {
55
+ return Math.max(1, Math.ceil(result.retryAfterMs / 1e3));
56
+ }
57
+ return DEFAULT_UNAVAILABLE_RETRY_AFTER_S;
58
+ }
59
+
37
60
  // src/verify.ts
38
61
  var DEFAULT_CONFIG = {
39
62
  apiBaseUrl: "https://astrasync.ai/api",
@@ -288,11 +311,44 @@ function createGuidanceResponse(_config, reason, options = {}) {
288
311
  // coercing the absent recommendation to a policy 'deny'. Misconfig is
289
312
  // deterministic and intentionally NOT marked retryable.
290
313
  ...isApiError && { retryable: true },
314
+ ...options.httpStatus !== void 0 && { httpStatus: options.httpStatus },
315
+ ...options.retryAfterMs !== void 0 && { retryAfterMs: options.retryAfterMs },
291
316
  correlationId: options.correlationId,
292
317
  attemptId: options.attemptId,
293
318
  verifiedAt: /* @__PURE__ */ new Date()
294
319
  };
295
320
  }
321
+ async function readJsonSafe(response) {
322
+ try {
323
+ const parsed = await response.json();
324
+ return parsed && typeof parsed === "object" ? parsed : {};
325
+ } catch {
326
+ return {};
327
+ }
328
+ }
329
+ function rejectedIdentityGuidance(failures) {
330
+ const f = failures?.find((x) => REJECTED_IDENTITY_DIMENSIONS.has(x.dimension));
331
+ if (!f) return void 0;
332
+ if (f.dimension === "agent.lookup") {
333
+ return `The presented agent identifier is not registered with AstraSync. ${UNKNOWN_AGENT_GUIDANCE}`;
334
+ }
335
+ return f.guidance ? `${f.message} ${f.guidance}` : f.message;
336
+ }
337
+ var MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
338
+ function parseRetryAfterMs(response) {
339
+ const raw = response.headers?.get?.("retry-after");
340
+ if (!raw) return void 0;
341
+ const trimmed = raw.trim();
342
+ let ms;
343
+ if (/^\d+(\.\d+)?$/.test(trimmed)) {
344
+ ms = Number(trimmed) * 1e3;
345
+ } else {
346
+ const at = Date.parse(trimmed);
347
+ if (Number.isNaN(at)) return void 0;
348
+ ms = at - Date.now();
349
+ }
350
+ return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, Math.round(ms)));
351
+ }
296
352
  async function callVerifyAccessAPI(config, request) {
297
353
  const { credentials, ...requestData } = request;
298
354
  const body = {
@@ -349,7 +405,8 @@ async function callVerifyAccessAPI(config, request) {
349
405
  body: JSON.stringify(body),
350
406
  signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
351
407
  });
352
- const data = await response.json();
408
+ const data = await readJsonSafe(response);
409
+ const retryAfterMs = parseRetryAfterMs(response);
353
410
  if (response.status === 410) {
354
411
  return {
355
412
  success: true,
@@ -387,6 +444,23 @@ async function callVerifyAccessAPI(config, request) {
387
444
  }
388
445
  };
389
446
  }
447
+ if (response.status === 404 && credentials.astraId && (data?.error === "AGENT_NOT_FOUND" || typeof data?.message === "string" && /agent/i.test(data.message))) {
448
+ return {
449
+ success: true,
450
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
451
+ access: {
452
+ allowed: false,
453
+ reason: "unknown_agent",
454
+ failures: [
455
+ {
456
+ dimension: "identity.unknown_agent",
457
+ message: "The presented agent identifier is not registered with AstraSync.",
458
+ guidance: UNKNOWN_AGENT_GUIDANCE
459
+ }
460
+ ]
461
+ }
462
+ };
463
+ }
390
464
  if (!response.ok) {
391
465
  if (response.status === 401) {
392
466
  return {
@@ -401,9 +475,11 @@ async function callVerifyAccessAPI(config, request) {
401
475
  }
402
476
  return {
403
477
  success: false,
404
- error: data.message || data.error || `API returned ${response.status}`,
478
+ error: typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `API returned ${response.status}`,
405
479
  correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
406
- attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
480
+ attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
481
+ httpStatus: response.status,
482
+ ...retryAfterMs !== void 0 && { retryAfterMs }
407
483
  };
408
484
  }
409
485
  return data;
@@ -475,12 +551,14 @@ async function verify(config, request, options) {
475
551
  correlationId: apiResponse.correlationId,
476
552
  attemptId: apiResponse.attemptId,
477
553
  remediation: apiResponse.remediation,
554
+ httpStatus: apiResponse.httpStatus,
555
+ retryAfterMs: apiResponse.retryAfterMs,
478
556
  urls
479
557
  });
480
558
  }
481
559
  if (!apiResponse.access?.allowed) {
482
560
  const aggregatedFailures = apiResponse.access?.failures;
483
- const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
561
+ const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
484
562
  const result2 = {
485
563
  identityVerified: idVerifiedFromBackend,
486
564
  policyAllowed: false,
@@ -492,7 +570,10 @@ async function verify(config, request, options) {
492
570
  requiresStepUp: apiResponse.access?.requiresStepUp,
493
571
  requiresApproval: apiResponse.access?.requiresApproval,
494
572
  guidance: {
495
- message: apiResponse.access?.reason || "Access denied by PDLSS policy",
573
+ // 5.12.0: a presented-but-rejected id (malformed / unknown) carries
574
+ // actionable registration guidance on its failure — surface it
575
+ // instead of the bare machine reason ('unknown_agent').
576
+ message: rejectedIdentityGuidance(aggregatedFailures) ?? (apiResponse.access?.reason || "Access denied by PDLSS policy"),
496
577
  registrationUrl: urls?.registrationUrl ?? "",
497
578
  documentationUrl: urls?.documentationUrl ?? "",
498
579
  // 5.1.0: anonymous callers land on this branch — steer MCP-hosted
@@ -592,7 +673,7 @@ async function verify(config, request, options) {
592
673
  registrationUrl: urls?.registrationUrl ?? "",
593
674
  documentationUrl: urls?.documentationUrl ?? ""
594
675
  };
595
- } else if (result.recommendation === "step_up_required") {
676
+ } else if (result.recommendation === "step_up_required" && result.identityVerified) {
596
677
  result.requiresStepUp = true;
597
678
  result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
598
679
  }
@@ -615,7 +696,7 @@ async function recordDecision(config, sessionId, decision, reason) {
615
696
  }).catch(() => {
616
697
  });
617
698
  }
618
- async function reportAttempt(config, report) {
699
+ async function reportAttempt(config, report, options = {}) {
619
700
  const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
620
701
  const headers = { "Content-Type": "application/json" };
621
702
  if (config.apiKey) {
@@ -626,13 +707,37 @@ async function reportAttempt(config, report) {
626
707
  ...report,
627
708
  ...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
628
709
  };
629
- await sdkFetch(`${apiBaseUrl}/agents/verify-access/attempt-report`, {
630
- method: "POST",
631
- headers,
632
- body: JSON.stringify(body)
633
- }).catch(() => {
634
- });
710
+ const url = `${apiBaseUrl}/agents/verify-access/attempt-report`;
711
+ const init = { method: "POST", headers, body: JSON.stringify(body) };
712
+ const fail = (failure) => {
713
+ try {
714
+ options.onFailure?.(failure);
715
+ } catch {
716
+ }
717
+ };
718
+ let response;
719
+ try {
720
+ response = await sdkFetch(url, init);
721
+ } catch (err) {
722
+ fail({ error: err instanceof Error ? err.message : String(err), retried: false });
723
+ return;
724
+ }
725
+ if (response.ok) return;
726
+ if (response.status !== 429 && response.status < 500) {
727
+ fail({ status: response.status, retried: false });
728
+ return;
729
+ }
730
+ const delayMs = Math.min(ATTEMPT_REPORT_MAX_RETRY_DELAY_MS, parseRetryAfterMs(response) ?? 500);
731
+ const timer = setTimeout(() => {
732
+ sdkFetch(url, init).then((retry) => {
733
+ if (!retry.ok) fail({ status: retry.status, retried: true });
734
+ }).catch((err) => {
735
+ fail({ error: err instanceof Error ? err.message : String(err), retried: true });
736
+ });
737
+ }, delayMs);
738
+ timer.unref?.();
635
739
  }
740
+ var ATTEMPT_REPORT_MAX_RETRY_DELAY_MS = 2e3;
636
741
  async function fetchRoutes(config, counterpartyId) {
637
742
  if (!counterpartyId) return null;
638
743
  const headers = { "Content-Type": "application/json" };
@@ -677,7 +782,10 @@ async function reportUnregisteredAttempt(config, data) {
677
782
  };
678
783
  await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
679
784
  method: "POST",
680
- headers: { "Content-Type": "application/json" },
785
+ headers: {
786
+ "Content-Type": "application/json",
787
+ ...config.apiKey && { Authorization: `Bearer ${config.apiKey}` }
788
+ },
681
789
  body: JSON.stringify(body)
682
790
  }).catch(() => {
683
791
  });
@@ -699,7 +807,11 @@ async function quickVerify(config, credentials) {
699
807
  return {
700
808
  identityVerified: result.identityVerified,
701
809
  policyAllowed: result.policyAllowed,
702
- reason: result.denialReasons?.[0]
810
+ reason: result.denialReasons?.[0],
811
+ ...isVerificationUnavailable(result) && {
812
+ unavailable: true,
813
+ retryAfterMs: unavailableRetryAfterSeconds(result) * 1e3
814
+ }
703
815
  };
704
816
  }
705
817
  export {
@@ -708,6 +820,7 @@ export {
708
820
  extractCredentials,
709
821
  fetchRoutes,
710
822
  hasCredentials,
823
+ parseRetryAfterMs,
711
824
  quickVerify,
712
825
  recordDecision,
713
826
  reportAttempt,