@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
@@ -1,3 +1,24 @@
1
+ // src/version.ts
2
+ var SDK_VERSION = "4.5.0";
3
+
4
+ // src/http.ts
5
+ var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
6
+ function withUserAgent(initHeaders) {
7
+ if (!initHeaders) return { "user-agent": SDK_USER_AGENT };
8
+ if (initHeaders instanceof Headers) {
9
+ const copy = new Headers(initHeaders);
10
+ if (!copy.has("user-agent")) copy.set("user-agent", SDK_USER_AGENT);
11
+ return copy;
12
+ }
13
+ if (Array.isArray(initHeaders)) {
14
+ const has2 = initHeaders.some(([name]) => name.toLowerCase() === "user-agent");
15
+ return has2 ? initHeaders : [...initHeaders, ["user-agent", SDK_USER_AGENT]];
16
+ }
17
+ const has = Object.keys(initHeaders).some((name) => name.toLowerCase() === "user-agent");
18
+ return has ? initHeaders : { "user-agent": SDK_USER_AGENT, ...initHeaders };
19
+ }
20
+ var sdkFetch = (input, init) => fetch(input, { ...init, headers: withUserAgent(init?.headers) });
21
+
1
22
  // src/access-levels.ts
2
23
  function getTrustLevel(score) {
3
24
  if (score >= 80) return "PLATINUM";
@@ -6,9 +27,6 @@ function getTrustLevel(score) {
6
27
  return "BRONZE";
7
28
  }
8
29
 
9
- // src/version.ts
10
- var SDK_VERSION = "4.1.0";
11
-
12
30
  // src/well-known.ts
13
31
  var CACHE_TTL_MS = 60 * 60 * 1e3;
14
32
  var cache = /* @__PURE__ */ new Map();
@@ -19,7 +37,7 @@ function wellKnownUrl(apiBaseUrl) {
19
37
  }
20
38
  async function fetchWellKnown(apiBaseUrl) {
21
39
  const url = wellKnownUrl(apiBaseUrl);
22
- const response = await fetch(url, {
40
+ const response = await sdkFetch(url, {
23
41
  method: "GET",
24
42
  headers: { Accept: "application/json" },
25
43
  signal: AbortSignal.timeout(5e3)
@@ -89,7 +107,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
89
107
  initCheckPerformed = true;
90
108
  try {
91
109
  const probeUrl = `${apiBaseUrl}/agents/verify-access`;
92
- const response = await fetch(probeUrl, { method: "HEAD" });
110
+ const response = await sdkFetch(probeUrl, { method: "HEAD" });
93
111
  const contentType = response.headers.get("content-type") ?? "";
94
112
  if (contentType.startsWith("text/html")) {
95
113
  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).`;
@@ -103,7 +121,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
103
121
  );
104
122
  }
105
123
  if (apiKey) {
106
- const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
124
+ const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
107
125
  headers: { Authorization: `Bearer ${apiKey}` }
108
126
  });
109
127
  if (selfCheck.status === 401) {
@@ -350,7 +368,7 @@ async function callVerifyAccessAPI(config, request) {
350
368
  headers["X-API-Key"] = config.apiKey;
351
369
  }
352
370
  try {
353
- const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
371
+ const response = await sdkFetch(`${config.apiBaseUrl}/agents/verify-access`, {
354
372
  method: "POST",
355
373
  headers,
356
374
  body: JSON.stringify(body),
@@ -532,12 +550,15 @@ async function verify(config, request, options) {
532
550
  const verificationContext = apiResponse.verificationContext;
533
551
  const accessLevel = apiResponse.access?.accessLevel ?? "standard";
534
552
  const result = {
535
- // Round-18 G4: backend allowed access. Identity is verified (we resolved
536
- // the caller to an agent) and policy passed all gates. Read idVerified
537
- // from verificationContext for symmetry with the deny branch; default true
538
- // on success path since `access.allowed === true` implies identity was
539
- // resolvable (anonymous-allow paths flow through createGuidanceResponse).
540
- identityVerified: apiResponse.verificationContext?.idVerified !== false,
553
+ // 4.5.0 (probe F1): read idVerified from verificationContext with the
554
+ // SAME absent⇒false default as the deny branch. The previous `!== false`
555
+ // default manufactured `identityVerified: true` for anonymous
556
+ // allow_full/allow_partial/audit responses (which allow access but omit
557
+ // verificationContext entirely) — the "anonymous caller labelled
558
+ // verified" defect. Every authenticated success response has carried
559
+ // `verificationContext.idVerified: true` since v2.2.4, so a truth claim
560
+ // this load-bearing must never be defaulted on.
561
+ identityVerified: apiResponse.verificationContext?.idVerified === true,
541
562
  policyAllowed: true,
542
563
  accessLevel,
543
564
  agent,
@@ -593,7 +614,7 @@ async function recordDecision(config, sessionId, decision, reason) {
593
614
  headers["Authorization"] = `Bearer ${config.apiKey}`;
594
615
  headers["X-API-Key"] = config.apiKey;
595
616
  }
596
- await fetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
617
+ await sdkFetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
597
618
  method: "POST",
598
619
  headers,
599
620
  body: JSON.stringify({ decision, reason })
@@ -638,7 +659,13 @@ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
638
659
  "x-agent-card-url",
639
660
  "x-agent-provider"
640
661
  ]);
641
- var PLATFORM_HEADER_PREFIXES = ["x-goog-", "x-stainless-", "x-anthropic-", "x-openai-"];
662
+ var PLATFORM_HEADER_PREFIXES = [
663
+ "x-goog-",
664
+ "x-stainless-",
665
+ "x-anthropic-",
666
+ "x-openai-",
667
+ "sec-ch-"
668
+ ];
642
669
  var KEY_FORMAT_PREFIXES = [
643
670
  "sk-ant-api03",
644
671
  "sk-ant-api",
@@ -710,6 +737,7 @@ function sanitizeHeaders(raw) {
710
737
  const headers = {};
711
738
  const platformHeaders = {};
712
739
  let apiKeyFormat;
740
+ let cookieCount;
713
741
  let totalBytes = 0;
714
742
  let count = 0;
715
743
  if (!raw) return { headers };
@@ -724,6 +752,9 @@ function sanitizeHeaders(raw) {
724
752
  if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
725
753
  continue;
726
754
  }
755
+ if (name === "cookie") {
756
+ cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
757
+ }
727
758
  if (isSecretHeader(name)) continue;
728
759
  let value = joined;
729
760
  if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
@@ -739,6 +770,7 @@ function sanitizeHeaders(raw) {
739
770
  const result = { headers };
740
771
  if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
741
772
  if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
773
+ if (cookieCount !== void 0) result.cookieCount = cookieCount;
742
774
  return result;
743
775
  }
744
776
  var CONNECTION_HEADER_SOURCES = [
@@ -750,6 +782,9 @@ var CONNECTION_HEADER_SOURCES = [
750
782
  ["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
751
783
  ["countryRegionName", ["cloudfront-viewer-country-region-name"]],
752
784
  ["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
785
+ ["latitude", ["x-vercel-ip-latitude", "cloudfront-viewer-latitude"]],
786
+ ["longitude", ["x-vercel-ip-longitude", "cloudfront-viewer-longitude"]],
787
+ ["postalCode", ["x-vercel-ip-postal-code", "cloudfront-viewer-postal-code"]],
753
788
  ["asn", ["cloudfront-viewer-asn"]],
754
789
  ["tlsVersion", ["cloudfront-viewer-tls"]],
755
790
  ["httpVersion", ["cloudfront-viewer-http-version"]],
@@ -784,19 +819,25 @@ function deriveConnectionFromHeaders(headers) {
784
819
  }
785
820
  }
786
821
  }
787
- if (!connection.ip) {
822
+ {
788
823
  const addr = lower["cloudfront-viewer-address"]?.trim();
789
- if (addr) connection.ip = addr.replace(/:\d+$/, "");
824
+ const portMatch = addr?.match(/:(\d+)$/);
825
+ if (portMatch) connection.sourcePort = portMatch[1];
826
+ if (!connection.ip && addr) connection.ip = addr.replace(/:\d+$/, "");
790
827
  }
791
828
  if (!connection.ip) {
792
829
  const xff = lower["x-forwarded-for"];
793
830
  const client = xff?.split(",")[0]?.trim();
794
831
  if (client) connection.ip = client;
795
832
  }
833
+ if (!connection.tlsCipher) {
834
+ const cipher = connection.tlsVersion?.split(":")[1];
835
+ if (cipher) connection.tlsCipher = cipher;
836
+ }
796
837
  return Object.keys(connection).length > 0 ? connection : void 0;
797
838
  }
798
839
  function buildSdkObservedMetadata(rawHeaders) {
799
- const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(rawHeaders);
840
+ const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(rawHeaders);
800
841
  const flat = {};
801
842
  if (rawHeaders) {
802
843
  for (const name of Object.keys(rawHeaders)) {
@@ -811,6 +852,7 @@ function buildSdkObservedMetadata(rawHeaders) {
811
852
  ...apiKeyFormat && { apiKeyFormat },
812
853
  ...platformHeaders && { platformHeaders },
813
854
  ...connection && { connection },
855
+ ...cookieCount !== void 0 && { cookieCount },
814
856
  schemaVersion: CAPTURE_SCHEMA_VERSION
815
857
  };
816
858
  }
@@ -842,7 +884,7 @@ function resolvePollUrl(config, pollUrl) {
842
884
  async function pollStepUpStatus(config, approval) {
843
885
  if (!approval.pollUrl) return null;
844
886
  try {
845
- const res = await fetch(resolvePollUrl(config, approval.pollUrl), {
887
+ const res = await sdkFetch(resolvePollUrl(config, approval.pollUrl), {
846
888
  method: "GET",
847
889
  signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS)
848
890
  });
@@ -1254,7 +1296,7 @@ function createMcpMiddleware(options) {
1254
1296
  let result = await verify(config, verificationRequest);
1255
1297
  req.agentVerification = result;
1256
1298
  let sessionId = result.sessionId;
1257
- if (config.stepUpMaxWaitMs !== void 0 && result.identityVerified && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
1299
+ if (config.stepUpMaxWaitMs !== void 0 && result.policyAllowed && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
1258
1300
  const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
1259
1301
  res.setHeader("X-Astra-Step-Up", outcome);
1260
1302
  if (outcome === "approved") {
@@ -1265,7 +1307,7 @@ function createMcpMiddleware(options) {
1265
1307
  result.stepUpOutcome = outcome;
1266
1308
  }
1267
1309
  }
1268
- if (!result.identityVerified || !result.policyAllowed) {
1310
+ if (!result.policyAllowed) {
1269
1311
  if (shouldRecordDecisions && sessionId) {
1270
1312
  recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
1271
1313
  });