@astrasyncai/verification-gateway 4.3.0 → 4.4.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.
- package/dist/adapters/express.js +91 -19
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +91 -19
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.js +52 -13
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +52 -13
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.js +89 -17
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +89 -17
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.js +24 -6
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +24 -6
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.js +24 -3
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +24 -3
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +22 -4
- package/dist/bin/astrasync-codex-hook.js +22 -4
- package/dist/bin/astrasync-guard.js +26 -8
- package/dist/bin/astrasync.js +66 -23
- package/dist/browser/background.js +22 -4
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +22 -4
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +23 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +23 -2
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +22 -4
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +22 -4
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +22 -4
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +22 -4
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.js +24 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +22 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.js +96 -11
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +96 -11
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +22 -4
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +22 -4
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/index.d.mts +51 -2
- package/dist/index.d.ts +51 -2
- package/dist/index.js +151 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +147 -26
- package/dist/index.mjs.map +1 -1
- package/dist/metadata-capture.d.mts +17 -0
- package/dist/metadata-capture.d.ts +17 -0
- package/dist/metadata-capture.js +25 -4
- package/dist/metadata-capture.js.map +1 -1
- package/dist/metadata-capture.mjs +25 -4
- package/dist/metadata-capture.mjs.map +1 -1
- package/dist/platform-signatures.d.mts +18 -1
- package/dist/platform-signatures.d.ts +18 -1
- package/dist/platform-signatures.js +35 -2
- package/dist/platform-signatures.js.map +1 -1
- package/dist/platform-signatures.mjs +35 -2
- package/dist/platform-signatures.mjs.map +1 -1
- package/dist/registration/index.js +25 -4
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +25 -4
- package/dist/registration/index.mjs.map +1 -1
- package/dist/transport/index.js +22 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +22 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/verify.js +29 -11
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +29 -11
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
package/dist/edge-core/index.mjs
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
// src/version.ts
|
|
2
|
+
var SDK_VERSION = "4.4.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/edge-config.ts
|
|
2
23
|
var DEFAULT_EDGE_CONFIG = Object.freeze({
|
|
3
24
|
version: 1,
|
|
@@ -57,7 +78,13 @@ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
|
57
78
|
"x-agent-card-url",
|
|
58
79
|
"x-agent-provider"
|
|
59
80
|
]);
|
|
60
|
-
var PLATFORM_HEADER_PREFIXES = [
|
|
81
|
+
var PLATFORM_HEADER_PREFIXES = [
|
|
82
|
+
"x-goog-",
|
|
83
|
+
"x-stainless-",
|
|
84
|
+
"x-anthropic-",
|
|
85
|
+
"x-openai-",
|
|
86
|
+
"sec-ch-"
|
|
87
|
+
];
|
|
61
88
|
var KEY_FORMAT_PREFIXES = [
|
|
62
89
|
"sk-ant-api03",
|
|
63
90
|
"sk-ant-api",
|
|
@@ -129,6 +156,7 @@ function sanitizeHeaders(raw) {
|
|
|
129
156
|
const headers = {};
|
|
130
157
|
const platformHeaders = {};
|
|
131
158
|
let apiKeyFormat;
|
|
159
|
+
let cookieCount;
|
|
132
160
|
let totalBytes = 0;
|
|
133
161
|
let count = 0;
|
|
134
162
|
if (!raw) return { headers };
|
|
@@ -143,6 +171,9 @@ function sanitizeHeaders(raw) {
|
|
|
143
171
|
if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
|
|
144
172
|
continue;
|
|
145
173
|
}
|
|
174
|
+
if (name === "cookie") {
|
|
175
|
+
cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
|
|
176
|
+
}
|
|
146
177
|
if (isSecretHeader(name)) continue;
|
|
147
178
|
let value = joined;
|
|
148
179
|
if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
|
|
@@ -158,6 +189,7 @@ function sanitizeHeaders(raw) {
|
|
|
158
189
|
const result = { headers };
|
|
159
190
|
if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
|
|
160
191
|
if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
|
|
192
|
+
if (cookieCount !== void 0) result.cookieCount = cookieCount;
|
|
161
193
|
return result;
|
|
162
194
|
}
|
|
163
195
|
|
|
@@ -205,12 +237,43 @@ var PLATFORM_AGENT_SIGNATURES = [
|
|
|
205
237
|
uaPatterns: [/perplexity/i],
|
|
206
238
|
agentCardPatterns: [/perplexity\.ai/i],
|
|
207
239
|
apiKeyFormatPatterns: [/^pplx-/i]
|
|
240
|
+
},
|
|
241
|
+
// Agentic browsers — versioned-token patterns ONLY (a stock Chrome UA must
|
|
242
|
+
// never match). Distinct vendor keys (not 'chatgpt'/'perplexity'): the
|
|
243
|
+
// browser product is a different surface than the assistant service, and
|
|
244
|
+
// the DB registry mirrors one row per vendor. These sit after the primary
|
|
245
|
+
// vendor entries so a UA carrying an explicit vendor token keeps its
|
|
246
|
+
// primary attribution; a browser-shaped UA with the agentic token is
|
|
247
|
+
// caught here BEFORE classify's human tier, which is what makes these
|
|
248
|
+
// visits observable at all. Token drift is real (some builds mimic Chrome
|
|
249
|
+
// outright) — re-verify against captured events when a new browser ships,
|
|
250
|
+
// and check `sec-ch-ua` platformHeaders for the real brand.
|
|
251
|
+
{
|
|
252
|
+
vendor: "chatgpt-atlas",
|
|
253
|
+
displayName: "ChatGPT Atlas browser",
|
|
254
|
+
uaPatterns: [/\batlas\/\d/i],
|
|
255
|
+
headerPatterns: [/^sec-ch-ua: .*atlas/i]
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
vendor: "perplexity-comet",
|
|
259
|
+
displayName: "Perplexity Comet browser",
|
|
260
|
+
uaPatterns: [/\bcomet\/\d/i],
|
|
261
|
+
headerPatterns: [/^sec-ch-ua: .*comet/i]
|
|
262
|
+
},
|
|
263
|
+
// Our own SDK self-identifies (sdkFetch stamps this UA) — first-party
|
|
264
|
+
// traffic must never pollute the unknown/anonymous pool it exists to audit.
|
|
265
|
+
{
|
|
266
|
+
vendor: "astrasync-sdk",
|
|
267
|
+
displayName: "AstraSync SDK",
|
|
268
|
+
uaPatterns: [/^astrasync-sdk\//i]
|
|
208
269
|
}
|
|
209
270
|
];
|
|
210
271
|
function matchPlatformSignature(signatures, input) {
|
|
211
272
|
const ua = input.userAgent ?? "";
|
|
212
273
|
const cardUrl = input.agentCardUrl ?? "";
|
|
213
274
|
const apiKeyFormat = input.apiKeyFormat ?? "";
|
|
275
|
+
const ja4 = input.ja4 ?? "";
|
|
276
|
+
const asn = input.asn ?? "";
|
|
214
277
|
const headerLines = [];
|
|
215
278
|
if (input.platformHeaders) {
|
|
216
279
|
for (const [name, value] of Object.entries(input.platformHeaders)) {
|
|
@@ -222,7 +285,9 @@ function matchPlatformSignature(signatures, input) {
|
|
|
222
285
|
const cardMatch = sig.agentCardPatterns?.some((p) => p.test(cardUrl));
|
|
223
286
|
const keyMatch = apiKeyFormat.length > 0 && sig.apiKeyFormatPatterns?.some((p) => p.test(apiKeyFormat));
|
|
224
287
|
const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
|
|
225
|
-
|
|
288
|
+
const ja4Match = ja4.length > 0 && sig.ja4Patterns?.some((p) => p.test(ja4));
|
|
289
|
+
const asnMatch = asn.length > 0 && sig.asnList?.includes(asn);
|
|
290
|
+
if (uaMatch || cardMatch || keyMatch || headerMatch || ja4Match || asnMatch) {
|
|
226
291
|
const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
|
|
227
292
|
const cardHost = (() => {
|
|
228
293
|
try {
|
|
@@ -231,7 +296,7 @@ function matchPlatformSignature(signatures, input) {
|
|
|
231
296
|
return "";
|
|
232
297
|
}
|
|
233
298
|
})();
|
|
234
|
-
const keyBasis = uaBase || cardHost || apiKeyFormat || "unknown";
|
|
299
|
+
const keyBasis = uaBase || cardHost || apiKeyFormat || ja4 || asn && `asn${asn}` || "unknown";
|
|
235
300
|
return {
|
|
236
301
|
vendor: sig.vendor,
|
|
237
302
|
fingerprintKey: `${sig.vendor}:${keyBasis}`,
|
|
@@ -253,9 +318,6 @@ function getTrustLevel(score) {
|
|
|
253
318
|
return "BRONZE";
|
|
254
319
|
}
|
|
255
320
|
|
|
256
|
-
// src/version.ts
|
|
257
|
-
var SDK_VERSION = "4.1.0";
|
|
258
|
-
|
|
259
321
|
// src/well-known.ts
|
|
260
322
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
261
323
|
var cache = /* @__PURE__ */ new Map();
|
|
@@ -284,7 +346,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
284
346
|
initCheckPerformed = true;
|
|
285
347
|
try {
|
|
286
348
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
287
|
-
const response = await
|
|
349
|
+
const response = await sdkFetch(probeUrl, { method: "HEAD" });
|
|
288
350
|
const contentType = response.headers.get("content-type") ?? "";
|
|
289
351
|
if (contentType.startsWith("text/html")) {
|
|
290
352
|
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).`;
|
|
@@ -298,7 +360,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
298
360
|
);
|
|
299
361
|
}
|
|
300
362
|
if (apiKey) {
|
|
301
|
-
const selfCheck = await
|
|
363
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
302
364
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
303
365
|
});
|
|
304
366
|
if (selfCheck.status === 401) {
|
|
@@ -545,7 +607,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
545
607
|
headers["X-API-Key"] = config.apiKey;
|
|
546
608
|
}
|
|
547
609
|
try {
|
|
548
|
-
const response = await
|
|
610
|
+
const response = await sdkFetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
549
611
|
method: "POST",
|
|
550
612
|
headers,
|
|
551
613
|
body: JSON.stringify(body),
|
|
@@ -790,7 +852,7 @@ async function reportUnregisteredAttempt(config, data) {
|
|
|
790
852
|
...counterpartyUrl && { counterpartyUrl },
|
|
791
853
|
...config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
792
854
|
};
|
|
793
|
-
await
|
|
855
|
+
await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
|
|
794
856
|
method: "POST",
|
|
795
857
|
headers: { "Content-Type": "application/json" },
|
|
796
858
|
body: JSON.stringify(body)
|
|
@@ -807,16 +869,39 @@ function requestUrl(req, host) {
|
|
|
807
869
|
return `https://${host}${req.uri}${qs}`;
|
|
808
870
|
}
|
|
809
871
|
function buildObservedMetadata(req) {
|
|
810
|
-
const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(req.headers);
|
|
872
|
+
const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(req.headers);
|
|
811
873
|
const connection = req.connection ?? {};
|
|
874
|
+
const queryKeys = extractQueryKeys(req.querystring);
|
|
812
875
|
return {
|
|
813
876
|
headers,
|
|
814
877
|
...apiKeyFormat && { apiKeyFormat },
|
|
815
878
|
...platformHeaders && { platformHeaders },
|
|
816
879
|
...Object.keys(connection).length > 0 && { connection },
|
|
880
|
+
...cookieCount !== void 0 && { cookieCount },
|
|
881
|
+
...queryKeys && { queryKeys },
|
|
817
882
|
schemaVersion: CAPTURE_SCHEMA_VERSION
|
|
818
883
|
};
|
|
819
884
|
}
|
|
885
|
+
var MAX_QUERY_KEYS = 32;
|
|
886
|
+
var MAX_QUERY_KEY_CHARS = 64;
|
|
887
|
+
function extractQueryKeys(querystring) {
|
|
888
|
+
if (!querystring) return void 0;
|
|
889
|
+
let params;
|
|
890
|
+
try {
|
|
891
|
+
params = new URLSearchParams(querystring);
|
|
892
|
+
} catch {
|
|
893
|
+
return void 0;
|
|
894
|
+
}
|
|
895
|
+
const keys = [];
|
|
896
|
+
for (const key of params.keys()) {
|
|
897
|
+
const normalized = key.toLowerCase().slice(0, MAX_QUERY_KEY_CHARS);
|
|
898
|
+
if (normalized && !keys.includes(normalized)) {
|
|
899
|
+
keys.push(normalized);
|
|
900
|
+
if (keys.length >= MAX_QUERY_KEYS) break;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
return keys.length > 0 ? keys : void 0;
|
|
904
|
+
}
|
|
820
905
|
|
|
821
906
|
// src/edge-core/detect.ts
|
|
822
907
|
var SD_JWT_PATTERN = /^eyJ[\w-]+\.[\w-]*\.[\w-]+~/;
|