@astrasyncai/verification-gateway 4.3.0 → 4.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 (87) hide show
  1. package/dist/adapters/express.js +104 -28
  2. package/dist/adapters/express.js.map +1 -1
  3. package/dist/adapters/express.mjs +104 -28
  4. package/dist/adapters/express.mjs.map +1 -1
  5. package/dist/adapters/mcp.js +63 -21
  6. package/dist/adapters/mcp.js.map +1 -1
  7. package/dist/adapters/mcp.mjs +63 -21
  8. package/dist/adapters/mcp.mjs.map +1 -1
  9. package/dist/adapters/nextjs.js +103 -27
  10. package/dist/adapters/nextjs.js.map +1 -1
  11. package/dist/adapters/nextjs.mjs +103 -27
  12. package/dist/adapters/nextjs.mjs.map +1 -1
  13. package/dist/adapters/sdk.js +33 -12
  14. package/dist/adapters/sdk.js.map +1 -1
  15. package/dist/adapters/sdk.mjs +33 -12
  16. package/dist/adapters/sdk.mjs.map +1 -1
  17. package/dist/agent/index.js +24 -3
  18. package/dist/agent/index.js.map +1 -1
  19. package/dist/agent/index.mjs +24 -3
  20. package/dist/agent/index.mjs.map +1 -1
  21. package/dist/bin/astrasync-claude-hook.js +31 -10
  22. package/dist/bin/astrasync-codex-hook.js +31 -10
  23. package/dist/bin/astrasync-guard.js +35 -14
  24. package/dist/bin/astrasync.js +75 -29
  25. package/dist/browser/background.js +31 -10
  26. package/dist/browser/background.js.map +1 -1
  27. package/dist/browser/background.mjs +31 -10
  28. package/dist/browser/background.mjs.map +1 -1
  29. package/dist/cli/index.js +23 -2
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/cli/index.mjs +23 -2
  32. package/dist/cli/index.mjs.map +1 -1
  33. package/dist/codex/index.js +31 -10
  34. package/dist/codex/index.js.map +1 -1
  35. package/dist/codex/index.mjs +31 -10
  36. package/dist/codex/index.mjs.map +1 -1
  37. package/dist/cursor/extension.js +31 -10
  38. package/dist/cursor/extension.js.map +1 -1
  39. package/dist/cursor/extension.mjs +31 -10
  40. package/dist/cursor/extension.mjs.map +1 -1
  41. package/dist/edge-config.d.mts +11 -4
  42. package/dist/edge-config.d.ts +11 -4
  43. package/dist/edge-config.js +24 -1
  44. package/dist/edge-config.js.map +1 -1
  45. package/dist/edge-config.mjs +22 -1
  46. package/dist/edge-config.mjs.map +1 -1
  47. package/dist/edge-core/index.d.mts +21 -7
  48. package/dist/edge-core/index.d.ts +21 -7
  49. package/dist/edge-core/index.js +170 -25
  50. package/dist/edge-core/index.js.map +1 -1
  51. package/dist/edge-core/index.mjs +170 -25
  52. package/dist/edge-core/index.mjs.map +1 -1
  53. package/dist/gateway/gateway.js +31 -10
  54. package/dist/gateway/gateway.js.map +1 -1
  55. package/dist/gateway/gateway.mjs +31 -10
  56. package/dist/gateway/gateway.mjs.map +1 -1
  57. package/dist/index.d.mts +51 -2
  58. package/dist/index.d.ts +51 -2
  59. package/dist/index.js +169 -40
  60. package/dist/index.js.map +1 -1
  61. package/dist/index.mjs +165 -40
  62. package/dist/index.mjs.map +1 -1
  63. package/dist/metadata-capture.d.mts +17 -0
  64. package/dist/metadata-capture.d.ts +17 -0
  65. package/dist/metadata-capture.js +25 -4
  66. package/dist/metadata-capture.js.map +1 -1
  67. package/dist/metadata-capture.mjs +25 -4
  68. package/dist/metadata-capture.mjs.map +1 -1
  69. package/dist/platform-signatures.d.mts +18 -1
  70. package/dist/platform-signatures.d.ts +18 -1
  71. package/dist/platform-signatures.js +35 -2
  72. package/dist/platform-signatures.js.map +1 -1
  73. package/dist/platform-signatures.mjs +35 -2
  74. package/dist/platform-signatures.mjs.map +1 -1
  75. package/dist/registration/index.js +25 -4
  76. package/dist/registration/index.js.map +1 -1
  77. package/dist/registration/index.mjs +25 -4
  78. package/dist/registration/index.mjs.map +1 -1
  79. package/dist/transport/index.js +22 -1
  80. package/dist/transport/index.js.map +1 -1
  81. package/dist/transport/index.mjs +22 -1
  82. package/dist/transport/index.mjs.map +1 -1
  83. package/dist/verify.js +38 -17
  84. package/dist/verify.js.map +1 -1
  85. package/dist/verify.mjs +38 -17
  86. package/dist/verify.mjs.map +1 -1
  87. package/package.json +2 -2
@@ -31,6 +31,27 @@ __export(mcp_exports, {
31
31
  });
32
32
  module.exports = __toCommonJS(mcp_exports);
33
33
 
34
+ // src/version.ts
35
+ var SDK_VERSION = "4.5.0";
36
+
37
+ // src/http.ts
38
+ var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
39
+ function withUserAgent(initHeaders) {
40
+ if (!initHeaders) return { "user-agent": SDK_USER_AGENT };
41
+ if (initHeaders instanceof Headers) {
42
+ const copy = new Headers(initHeaders);
43
+ if (!copy.has("user-agent")) copy.set("user-agent", SDK_USER_AGENT);
44
+ return copy;
45
+ }
46
+ if (Array.isArray(initHeaders)) {
47
+ const has2 = initHeaders.some(([name]) => name.toLowerCase() === "user-agent");
48
+ return has2 ? initHeaders : [...initHeaders, ["user-agent", SDK_USER_AGENT]];
49
+ }
50
+ const has = Object.keys(initHeaders).some((name) => name.toLowerCase() === "user-agent");
51
+ return has ? initHeaders : { "user-agent": SDK_USER_AGENT, ...initHeaders };
52
+ }
53
+ var sdkFetch = (input, init) => fetch(input, { ...init, headers: withUserAgent(init?.headers) });
54
+
34
55
  // src/access-levels.ts
35
56
  function getTrustLevel(score) {
36
57
  if (score >= 80) return "PLATINUM";
@@ -39,9 +60,6 @@ function getTrustLevel(score) {
39
60
  return "BRONZE";
40
61
  }
41
62
 
42
- // src/version.ts
43
- var SDK_VERSION = "4.1.0";
44
-
45
63
  // src/well-known.ts
46
64
  var CACHE_TTL_MS = 60 * 60 * 1e3;
47
65
  var cache = /* @__PURE__ */ new Map();
@@ -52,7 +70,7 @@ function wellKnownUrl(apiBaseUrl) {
52
70
  }
53
71
  async function fetchWellKnown(apiBaseUrl) {
54
72
  const url = wellKnownUrl(apiBaseUrl);
55
- const response = await fetch(url, {
73
+ const response = await sdkFetch(url, {
56
74
  method: "GET",
57
75
  headers: { Accept: "application/json" },
58
76
  signal: AbortSignal.timeout(5e3)
@@ -122,7 +140,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
122
140
  initCheckPerformed = true;
123
141
  try {
124
142
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
125
- const response = await fetch(probeUrl, { method: "HEAD" });
143
+ const response = await sdkFetch(probeUrl, { method: "HEAD" });
126
144
  const contentType = response.headers.get("content-type") ?? "";
127
145
  if (contentType.startsWith("text/html")) {
128
146
  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).`;
@@ -136,7 +154,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
136
154
  );
137
155
  }
138
156
  if (apiKey) {
139
- const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
157
+ const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
140
158
  headers: { Authorization: `Bearer ${apiKey}` }
141
159
  });
142
160
  if (selfCheck.status === 401) {
@@ -383,7 +401,7 @@ async function callVerifyAccessAPI(config, request) {
383
401
  headers["X-API-Key"] = config.apiKey;
384
402
  }
385
403
  try {
386
- const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
404
+ const response = await sdkFetch(`${config.apiBaseUrl}/agents/verify-access`, {
387
405
  method: "POST",
388
406
  headers,
389
407
  body: JSON.stringify(body),
@@ -565,12 +583,15 @@ async function verify(config, request, options) {
565
583
  const verificationContext = apiResponse.verificationContext;
566
584
  const accessLevel = apiResponse.access?.accessLevel ?? "standard";
567
585
  const result = {
568
- // Round-18 G4: backend allowed access. Identity is verified (we resolved
569
- // the caller to an agent) and policy passed all gates. Read idVerified
570
- // from verificationContext for symmetry with the deny branch; default true
571
- // on success path since `access.allowed === true` implies identity was
572
- // resolvable (anonymous-allow paths flow through createGuidanceResponse).
573
- identityVerified: apiResponse.verificationContext?.idVerified !== false,
586
+ // 4.5.0 (probe F1): read idVerified from verificationContext with the
587
+ // SAME absent⇒false default as the deny branch. The previous `!== false`
588
+ // default manufactured `identityVerified: true` for anonymous
589
+ // allow_full/allow_partial/audit responses (which allow access but omit
590
+ // verificationContext entirely) — the "anonymous caller labelled
591
+ // verified" defect. Every authenticated success response has carried
592
+ // `verificationContext.idVerified: true` since v2.2.4, so a truth claim
593
+ // this load-bearing must never be defaulted on.
594
+ identityVerified: apiResponse.verificationContext?.idVerified === true,
574
595
  policyAllowed: true,
575
596
  accessLevel,
576
597
  agent,
@@ -626,7 +647,7 @@ async function recordDecision(config, sessionId, decision, reason) {
626
647
  headers["Authorization"] = `Bearer ${config.apiKey}`;
627
648
  headers["X-API-Key"] = config.apiKey;
628
649
  }
629
- await fetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
650
+ await sdkFetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
630
651
  method: "POST",
631
652
  headers,
632
653
  body: JSON.stringify({ decision, reason })
@@ -671,7 +692,13 @@ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
671
692
  "x-agent-card-url",
672
693
  "x-agent-provider"
673
694
  ]);
674
- var PLATFORM_HEADER_PREFIXES = ["x-goog-", "x-stainless-", "x-anthropic-", "x-openai-"];
695
+ var PLATFORM_HEADER_PREFIXES = [
696
+ "x-goog-",
697
+ "x-stainless-",
698
+ "x-anthropic-",
699
+ "x-openai-",
700
+ "sec-ch-"
701
+ ];
675
702
  var KEY_FORMAT_PREFIXES = [
676
703
  "sk-ant-api03",
677
704
  "sk-ant-api",
@@ -743,6 +770,7 @@ function sanitizeHeaders(raw) {
743
770
  const headers = {};
744
771
  const platformHeaders = {};
745
772
  let apiKeyFormat;
773
+ let cookieCount;
746
774
  let totalBytes = 0;
747
775
  let count = 0;
748
776
  if (!raw) return { headers };
@@ -757,6 +785,9 @@ function sanitizeHeaders(raw) {
757
785
  if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
758
786
  continue;
759
787
  }
788
+ if (name === "cookie") {
789
+ cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
790
+ }
760
791
  if (isSecretHeader(name)) continue;
761
792
  let value = joined;
762
793
  if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
@@ -772,6 +803,7 @@ function sanitizeHeaders(raw) {
772
803
  const result = { headers };
773
804
  if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
774
805
  if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
806
+ if (cookieCount !== void 0) result.cookieCount = cookieCount;
775
807
  return result;
776
808
  }
777
809
  var CONNECTION_HEADER_SOURCES = [
@@ -783,6 +815,9 @@ var CONNECTION_HEADER_SOURCES = [
783
815
  ["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
784
816
  ["countryRegionName", ["cloudfront-viewer-country-region-name"]],
785
817
  ["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
818
+ ["latitude", ["x-vercel-ip-latitude", "cloudfront-viewer-latitude"]],
819
+ ["longitude", ["x-vercel-ip-longitude", "cloudfront-viewer-longitude"]],
820
+ ["postalCode", ["x-vercel-ip-postal-code", "cloudfront-viewer-postal-code"]],
786
821
  ["asn", ["cloudfront-viewer-asn"]],
787
822
  ["tlsVersion", ["cloudfront-viewer-tls"]],
788
823
  ["httpVersion", ["cloudfront-viewer-http-version"]],
@@ -817,19 +852,25 @@ function deriveConnectionFromHeaders(headers) {
817
852
  }
818
853
  }
819
854
  }
820
- if (!connection.ip) {
855
+ {
821
856
  const addr = lower["cloudfront-viewer-address"]?.trim();
822
- if (addr) connection.ip = addr.replace(/:\d+$/, "");
857
+ const portMatch = addr?.match(/:(\d+)$/);
858
+ if (portMatch) connection.sourcePort = portMatch[1];
859
+ if (!connection.ip && addr) connection.ip = addr.replace(/:\d+$/, "");
823
860
  }
824
861
  if (!connection.ip) {
825
862
  const xff = lower["x-forwarded-for"];
826
863
  const client = xff?.split(",")[0]?.trim();
827
864
  if (client) connection.ip = client;
828
865
  }
866
+ if (!connection.tlsCipher) {
867
+ const cipher = connection.tlsVersion?.split(":")[1];
868
+ if (cipher) connection.tlsCipher = cipher;
869
+ }
829
870
  return Object.keys(connection).length > 0 ? connection : void 0;
830
871
  }
831
872
  function buildSdkObservedMetadata(rawHeaders) {
832
- const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(rawHeaders);
873
+ const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(rawHeaders);
833
874
  const flat = {};
834
875
  if (rawHeaders) {
835
876
  for (const name of Object.keys(rawHeaders)) {
@@ -844,6 +885,7 @@ function buildSdkObservedMetadata(rawHeaders) {
844
885
  ...apiKeyFormat && { apiKeyFormat },
845
886
  ...platformHeaders && { platformHeaders },
846
887
  ...connection && { connection },
888
+ ...cookieCount !== void 0 && { cookieCount },
847
889
  schemaVersion: CAPTURE_SCHEMA_VERSION
848
890
  };
849
891
  }
@@ -875,7 +917,7 @@ function resolvePollUrl(config, pollUrl) {
875
917
  async function pollStepUpStatus(config, approval) {
876
918
  if (!approval.pollUrl) return null;
877
919
  try {
878
- const res = await fetch(resolvePollUrl(config, approval.pollUrl), {
920
+ const res = await sdkFetch(resolvePollUrl(config, approval.pollUrl), {
879
921
  method: "GET",
880
922
  signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS)
881
923
  });
@@ -1287,7 +1329,7 @@ function createMcpMiddleware(options) {
1287
1329
  let result = await verify(config, verificationRequest);
1288
1330
  req.agentVerification = result;
1289
1331
  let sessionId = result.sessionId;
1290
- if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
1332
+ if (config.stepUpMaxWaitMs !== void 0 && result.policyAllowed && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
1291
1333
  const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
1292
1334
  res.setHeader("X-Astra-Step-Up", outcome);
1293
1335
  if (outcome === "approved") {
@@ -1298,7 +1340,7 @@ function createMcpMiddleware(options) {
1298
1340
  result.stepUpOutcome = outcome;
1299
1341
  }
1300
1342
  }
1301
- if (!result.identityVerified || !result.policyAllowed) {
1343
+ if (!result.policyAllowed) {
1302
1344
  if (shouldRecordDecisions && sessionId) {
1303
1345
  recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
1304
1346
  });