@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.
- package/dist/adapters/express.js +104 -28
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +104 -28
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.js +63 -21
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +63 -21
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.js +103 -27
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +103 -27
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.js +33 -12
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +33 -12
- 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 +31 -10
- package/dist/bin/astrasync-codex-hook.js +31 -10
- package/dist/bin/astrasync-guard.js +35 -14
- package/dist/bin/astrasync.js +75 -29
- package/dist/browser/background.js +31 -10
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +31 -10
- 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 +31 -10
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +31 -10
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +31 -10
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +31 -10
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +11 -4
- package/dist/edge-config.d.ts +11 -4
- 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.d.mts +21 -7
- package/dist/edge-core/index.d.ts +21 -7
- package/dist/edge-core/index.js +170 -25
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +170 -25
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +31 -10
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +31 -10
- 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 +169 -40
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +165 -40
- 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 +38 -17
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +38 -17
- package/dist/verify.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -127,6 +127,55 @@ declare function getWellKnownUrls(apiBaseUrl: string): Promise<WellKnownAgenticC
|
|
|
127
127
|
*/
|
|
128
128
|
declare function getCachedWellKnownUrls(apiBaseUrl: string): WellKnownAgenticCommerce | undefined;
|
|
129
129
|
|
|
130
|
+
/**
|
|
131
|
+
* HTTP-client RUNTIME signatures — a display-only vocabulary, disjoint from
|
|
132
|
+
* the platform-agent vendor vocabulary in `platform-signatures.ts`.
|
|
133
|
+
*
|
|
134
|
+
* A UA of `node` or `python-requests` identifies the HTTP STACK, never the
|
|
135
|
+
* operator: OpenAI Codex, Claude Code, Perplexity's tooling, and our own SDK
|
|
136
|
+
* all fetch through Node — labeling any of them a vendor from the runtime
|
|
137
|
+
* alone would be fabrication. What we CAN say honestly is "undeclared
|
|
138
|
+
* automation on the Node.js runtime", which beats "unknown" in every surface.
|
|
139
|
+
*
|
|
140
|
+
* HARD RULE: this module must NEVER be consulted by `edge-core/classify.ts`,
|
|
141
|
+
* `detectPlatformFingerprint`, or any tiering / orphan-provisioning path.
|
|
142
|
+
* Runtime matches carry no identity: promoting them to the `identified` tier
|
|
143
|
+
* would flip anonymous-bot traffic to 1:1 beacons and auto-provision orphan
|
|
144
|
+
* agents literally named "node". Display and clustering layers only.
|
|
145
|
+
*/
|
|
146
|
+
interface RuntimeSignature {
|
|
147
|
+
/** Stable runtime key — namespace disjoint from `PlatformAgentVendor`. */
|
|
148
|
+
runtime: string;
|
|
149
|
+
/** Human-readable label, e.g. "Node.js runtime". */
|
|
150
|
+
displayName: string;
|
|
151
|
+
uaPatterns: RegExp[];
|
|
152
|
+
}
|
|
153
|
+
/** First match wins — order more-specific tokens before generic ones. */
|
|
154
|
+
declare const RUNTIME_SIGNATURES: ReadonlyArray<RuntimeSignature>;
|
|
155
|
+
/**
|
|
156
|
+
* Detect the HTTP-client runtime from a User-Agent. Returns the displayName
|
|
157
|
+
* (e.g. "Node.js runtime") or undefined when the UA doesn't look like a bare
|
|
158
|
+
* runtime/library client.
|
|
159
|
+
*/
|
|
160
|
+
declare function detectRuntime(userAgent: string | undefined | null): string | undefined;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Shared outbound-HTTP wrapper — every request the SDK makes to the
|
|
164
|
+
* AstraSync backend (or anywhere else) goes through `sdkFetch` so it
|
|
165
|
+
* carries an identifying User-Agent.
|
|
166
|
+
*
|
|
167
|
+
* Why: Node's global fetch defaults to `user-agent: node`, which is
|
|
168
|
+
* indistinguishable from every other Node client on the wire. Visit
|
|
169
|
+
* Intelligence observed our own SDK/beacon traffic as anonymous "node"
|
|
170
|
+
* visits. Self-identification is the platform's own medicine.
|
|
171
|
+
*
|
|
172
|
+
* Browser note: some browsers filter the User-Agent request header
|
|
173
|
+
* silently (never throwing), so this is a no-op there — which is correct:
|
|
174
|
+
* in a browser the page's real UA is the honest identity.
|
|
175
|
+
*/
|
|
176
|
+
declare const SDK_USER_AGENT = "astrasync-sdk/4.5.0";
|
|
177
|
+
declare const sdkFetch: typeof fetch;
|
|
178
|
+
|
|
130
179
|
/**
|
|
131
180
|
* Single source-of-truth for the SDK's
|
|
132
181
|
* package version emitted on verify-access bodies (and any future
|
|
@@ -145,6 +194,6 @@ declare function getCachedWellKnownUrls(apiBaseUrl: string): WellKnownAgenticCom
|
|
|
145
194
|
* is fine — bumping both in the release-ceremony commit keeps them
|
|
146
195
|
* lockstep.
|
|
147
196
|
*/
|
|
148
|
-
declare const SDK_VERSION = "4.
|
|
197
|
+
declare const SDK_VERSION = "4.5.0";
|
|
149
198
|
|
|
150
|
-
export { EnhancedVerificationResult, GatewayConfig, type SettlementDecision, type SettlementRequest, StepUpApprovalInfo, StepUpApprovalStatus, StepUpOutcome, SDK_VERSION as VERSION, type WellKnownAgenticCommerce, authorizeSettlement, awaitStepUpApproval, getCachedWellKnownUrls, getWellKnownUrls, pollStepUpStatus, prefetchWellKnown };
|
|
199
|
+
export { EnhancedVerificationResult, GatewayConfig, RUNTIME_SIGNATURES, type RuntimeSignature, SDK_USER_AGENT, type SettlementDecision, type SettlementRequest, StepUpApprovalInfo, StepUpApprovalStatus, StepUpOutcome, SDK_VERSION as VERSION, type WellKnownAgenticCommerce, authorizeSettlement, awaitStepUpApproval, detectRuntime, getCachedWellKnownUrls, getWellKnownUrls, pollStepUpStatus, prefetchWellKnown, sdkFetch };
|
package/dist/index.d.ts
CHANGED
|
@@ -127,6 +127,55 @@ declare function getWellKnownUrls(apiBaseUrl: string): Promise<WellKnownAgenticC
|
|
|
127
127
|
*/
|
|
128
128
|
declare function getCachedWellKnownUrls(apiBaseUrl: string): WellKnownAgenticCommerce | undefined;
|
|
129
129
|
|
|
130
|
+
/**
|
|
131
|
+
* HTTP-client RUNTIME signatures — a display-only vocabulary, disjoint from
|
|
132
|
+
* the platform-agent vendor vocabulary in `platform-signatures.ts`.
|
|
133
|
+
*
|
|
134
|
+
* A UA of `node` or `python-requests` identifies the HTTP STACK, never the
|
|
135
|
+
* operator: OpenAI Codex, Claude Code, Perplexity's tooling, and our own SDK
|
|
136
|
+
* all fetch through Node — labeling any of them a vendor from the runtime
|
|
137
|
+
* alone would be fabrication. What we CAN say honestly is "undeclared
|
|
138
|
+
* automation on the Node.js runtime", which beats "unknown" in every surface.
|
|
139
|
+
*
|
|
140
|
+
* HARD RULE: this module must NEVER be consulted by `edge-core/classify.ts`,
|
|
141
|
+
* `detectPlatformFingerprint`, or any tiering / orphan-provisioning path.
|
|
142
|
+
* Runtime matches carry no identity: promoting them to the `identified` tier
|
|
143
|
+
* would flip anonymous-bot traffic to 1:1 beacons and auto-provision orphan
|
|
144
|
+
* agents literally named "node". Display and clustering layers only.
|
|
145
|
+
*/
|
|
146
|
+
interface RuntimeSignature {
|
|
147
|
+
/** Stable runtime key — namespace disjoint from `PlatformAgentVendor`. */
|
|
148
|
+
runtime: string;
|
|
149
|
+
/** Human-readable label, e.g. "Node.js runtime". */
|
|
150
|
+
displayName: string;
|
|
151
|
+
uaPatterns: RegExp[];
|
|
152
|
+
}
|
|
153
|
+
/** First match wins — order more-specific tokens before generic ones. */
|
|
154
|
+
declare const RUNTIME_SIGNATURES: ReadonlyArray<RuntimeSignature>;
|
|
155
|
+
/**
|
|
156
|
+
* Detect the HTTP-client runtime from a User-Agent. Returns the displayName
|
|
157
|
+
* (e.g. "Node.js runtime") or undefined when the UA doesn't look like a bare
|
|
158
|
+
* runtime/library client.
|
|
159
|
+
*/
|
|
160
|
+
declare function detectRuntime(userAgent: string | undefined | null): string | undefined;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Shared outbound-HTTP wrapper — every request the SDK makes to the
|
|
164
|
+
* AstraSync backend (or anywhere else) goes through `sdkFetch` so it
|
|
165
|
+
* carries an identifying User-Agent.
|
|
166
|
+
*
|
|
167
|
+
* Why: Node's global fetch defaults to `user-agent: node`, which is
|
|
168
|
+
* indistinguishable from every other Node client on the wire. Visit
|
|
169
|
+
* Intelligence observed our own SDK/beacon traffic as anonymous "node"
|
|
170
|
+
* visits. Self-identification is the platform's own medicine.
|
|
171
|
+
*
|
|
172
|
+
* Browser note: some browsers filter the User-Agent request header
|
|
173
|
+
* silently (never throwing), so this is a no-op there — which is correct:
|
|
174
|
+
* in a browser the page's real UA is the honest identity.
|
|
175
|
+
*/
|
|
176
|
+
declare const SDK_USER_AGENT = "astrasync-sdk/4.5.0";
|
|
177
|
+
declare const sdkFetch: typeof fetch;
|
|
178
|
+
|
|
130
179
|
/**
|
|
131
180
|
* Single source-of-truth for the SDK's
|
|
132
181
|
* package version emitted on verify-access bodies (and any future
|
|
@@ -145,6 +194,6 @@ declare function getCachedWellKnownUrls(apiBaseUrl: string): WellKnownAgenticCom
|
|
|
145
194
|
* is fine — bumping both in the release-ceremony commit keeps them
|
|
146
195
|
* lockstep.
|
|
147
196
|
*/
|
|
148
|
-
declare const SDK_VERSION = "4.
|
|
197
|
+
declare const SDK_VERSION = "4.5.0";
|
|
149
198
|
|
|
150
|
-
export { EnhancedVerificationResult, GatewayConfig, type SettlementDecision, type SettlementRequest, StepUpApprovalInfo, StepUpApprovalStatus, StepUpOutcome, SDK_VERSION as VERSION, type WellKnownAgenticCommerce, authorizeSettlement, awaitStepUpApproval, getCachedWellKnownUrls, getWellKnownUrls, pollStepUpStatus, prefetchWellKnown };
|
|
199
|
+
export { EnhancedVerificationResult, GatewayConfig, RUNTIME_SIGNATURES, type RuntimeSignature, SDK_USER_AGENT, type SettlementDecision, type SettlementRequest, StepUpApprovalInfo, StepUpApprovalStatus, StepUpOutcome, SDK_VERSION as VERSION, type WellKnownAgenticCommerce, authorizeSettlement, awaitStepUpApproval, detectRuntime, getCachedWellKnownUrls, getWellKnownUrls, pollStepUpStatus, prefetchWellKnown, sdkFetch };
|
package/dist/index.js
CHANGED
|
@@ -45,9 +45,11 @@ __export(src_exports, {
|
|
|
45
45
|
MAX_HEADER_VALUE_BYTES: () => MAX_HEADER_VALUE_BYTES,
|
|
46
46
|
MAX_TOTAL_BYTES: () => MAX_TOTAL_BYTES,
|
|
47
47
|
PLATFORM_AGENT_SIGNATURES: () => PLATFORM_AGENT_SIGNATURES,
|
|
48
|
+
RUNTIME_SIGNATURES: () => RUNTIME_SIGNATURES,
|
|
48
49
|
RegistrationDeniedError: () => RegistrationDeniedError,
|
|
49
50
|
RegistrationExpiredError: () => RegistrationExpiredError,
|
|
50
51
|
RegistrationTimeoutError: () => RegistrationTimeoutError,
|
|
52
|
+
SDK_USER_AGENT: () => SDK_USER_AGENT,
|
|
51
53
|
TRUST_LEVEL_RANGES: () => TRUST_LEVEL_RANGES,
|
|
52
54
|
VERSION: () => SDK_VERSION,
|
|
53
55
|
_resetEdgeConfigCache: () => _resetEdgeConfigCache,
|
|
@@ -61,6 +63,7 @@ __export(src_exports, {
|
|
|
61
63
|
degradeToObserve: () => degradeToObserve,
|
|
62
64
|
deriveConnectionFromHeaders: () => deriveConnectionFromHeaders,
|
|
63
65
|
detectPlatformFingerprint: () => detectPlatformFingerprint,
|
|
66
|
+
detectRuntime: () => detectRuntime,
|
|
64
67
|
determineAccessLevel: () => determineAccessLevel,
|
|
65
68
|
express: () => express_exports,
|
|
66
69
|
extractApiKeyFormat: () => extractApiKeyFormat,
|
|
@@ -89,6 +92,7 @@ __export(src_exports, {
|
|
|
89
92
|
reportUnregisteredAttempt: () => reportUnregisteredAttempt,
|
|
90
93
|
sanitizeHeaders: () => sanitizeHeaders,
|
|
91
94
|
sdk: () => sdk_exports,
|
|
95
|
+
sdkFetch: () => sdkFetch,
|
|
92
96
|
setMcpMeta: () => setMcpMeta,
|
|
93
97
|
transport: () => transport_exports,
|
|
94
98
|
verify: () => verify
|
|
@@ -217,7 +221,25 @@ function getCapabilities(accessLevel) {
|
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
// src/version.ts
|
|
220
|
-
var SDK_VERSION = "4.
|
|
224
|
+
var SDK_VERSION = "4.5.0";
|
|
225
|
+
|
|
226
|
+
// src/http.ts
|
|
227
|
+
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
228
|
+
function withUserAgent(initHeaders) {
|
|
229
|
+
if (!initHeaders) return { "user-agent": SDK_USER_AGENT };
|
|
230
|
+
if (initHeaders instanceof Headers) {
|
|
231
|
+
const copy = new Headers(initHeaders);
|
|
232
|
+
if (!copy.has("user-agent")) copy.set("user-agent", SDK_USER_AGENT);
|
|
233
|
+
return copy;
|
|
234
|
+
}
|
|
235
|
+
if (Array.isArray(initHeaders)) {
|
|
236
|
+
const has2 = initHeaders.some(([name]) => name.toLowerCase() === "user-agent");
|
|
237
|
+
return has2 ? initHeaders : [...initHeaders, ["user-agent", SDK_USER_AGENT]];
|
|
238
|
+
}
|
|
239
|
+
const has = Object.keys(initHeaders).some((name) => name.toLowerCase() === "user-agent");
|
|
240
|
+
return has ? initHeaders : { "user-agent": SDK_USER_AGENT, ...initHeaders };
|
|
241
|
+
}
|
|
242
|
+
var sdkFetch = (input, init) => fetch(input, { ...init, headers: withUserAgent(init?.headers) });
|
|
221
243
|
|
|
222
244
|
// src/well-known.ts
|
|
223
245
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -229,7 +251,7 @@ function wellKnownUrl(apiBaseUrl) {
|
|
|
229
251
|
}
|
|
230
252
|
async function fetchWellKnown(apiBaseUrl) {
|
|
231
253
|
const url = wellKnownUrl(apiBaseUrl);
|
|
232
|
-
const response = await
|
|
254
|
+
const response = await sdkFetch(url, {
|
|
233
255
|
method: "GET",
|
|
234
256
|
headers: { Accept: "application/json" },
|
|
235
257
|
signal: AbortSignal.timeout(5e3)
|
|
@@ -299,7 +321,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
299
321
|
initCheckPerformed = true;
|
|
300
322
|
try {
|
|
301
323
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
302
|
-
const response = await
|
|
324
|
+
const response = await sdkFetch(probeUrl, { method: "HEAD" });
|
|
303
325
|
const contentType = response.headers.get("content-type") ?? "";
|
|
304
326
|
if (contentType.startsWith("text/html")) {
|
|
305
327
|
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).`;
|
|
@@ -313,7 +335,7 @@ async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
|
313
335
|
);
|
|
314
336
|
}
|
|
315
337
|
if (apiKey) {
|
|
316
|
-
const selfCheck = await
|
|
338
|
+
const selfCheck = await sdkFetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
317
339
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
318
340
|
});
|
|
319
341
|
if (selfCheck.status === 401) {
|
|
@@ -566,7 +588,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
566
588
|
headers["X-API-Key"] = config.apiKey;
|
|
567
589
|
}
|
|
568
590
|
try {
|
|
569
|
-
const response = await
|
|
591
|
+
const response = await sdkFetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
570
592
|
method: "POST",
|
|
571
593
|
headers,
|
|
572
594
|
body: JSON.stringify(body),
|
|
@@ -748,12 +770,15 @@ async function verify(config, request, options) {
|
|
|
748
770
|
const verificationContext = apiResponse.verificationContext;
|
|
749
771
|
const accessLevel = apiResponse.access?.accessLevel ?? "standard";
|
|
750
772
|
const result = {
|
|
751
|
-
//
|
|
752
|
-
//
|
|
753
|
-
//
|
|
754
|
-
//
|
|
755
|
-
//
|
|
756
|
-
|
|
773
|
+
// 4.5.0 (probe F1): read idVerified from verificationContext with the
|
|
774
|
+
// SAME absent⇒false default as the deny branch. The previous `!== false`
|
|
775
|
+
// default manufactured `identityVerified: true` for anonymous
|
|
776
|
+
// allow_full/allow_partial/audit responses (which allow access but omit
|
|
777
|
+
// verificationContext entirely) — the "anonymous caller labelled
|
|
778
|
+
// verified" defect. Every authenticated success response has carried
|
|
779
|
+
// `verificationContext.idVerified: true` since v2.2.4, so a truth claim
|
|
780
|
+
// this load-bearing must never be defaulted on.
|
|
781
|
+
identityVerified: apiResponse.verificationContext?.idVerified === true,
|
|
757
782
|
policyAllowed: true,
|
|
758
783
|
accessLevel,
|
|
759
784
|
agent,
|
|
@@ -809,7 +834,7 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
809
834
|
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
810
835
|
headers["X-API-Key"] = config.apiKey;
|
|
811
836
|
}
|
|
812
|
-
await
|
|
837
|
+
await sdkFetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
|
|
813
838
|
method: "POST",
|
|
814
839
|
headers,
|
|
815
840
|
body: JSON.stringify({ decision, reason })
|
|
@@ -827,7 +852,7 @@ async function reportAttempt(config, report) {
|
|
|
827
852
|
...report,
|
|
828
853
|
...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
829
854
|
};
|
|
830
|
-
await
|
|
855
|
+
await sdkFetch(`${apiBaseUrl}/agents/verify-access/attempt-report`, {
|
|
831
856
|
method: "POST",
|
|
832
857
|
headers,
|
|
833
858
|
body: JSON.stringify(body)
|
|
@@ -842,7 +867,7 @@ async function fetchRoutes(config, counterpartyId) {
|
|
|
842
867
|
headers["X-API-Key"] = config.apiKey;
|
|
843
868
|
}
|
|
844
869
|
try {
|
|
845
|
-
const response = await
|
|
870
|
+
const response = await sdkFetch(
|
|
846
871
|
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/routes`,
|
|
847
872
|
{ method: "GET", headers }
|
|
848
873
|
);
|
|
@@ -861,7 +886,7 @@ async function reportUnregisteredAttempt(config, data) {
|
|
|
861
886
|
...counterpartyUrl && { counterpartyUrl },
|
|
862
887
|
...config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
863
888
|
};
|
|
864
|
-
await
|
|
889
|
+
await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
|
|
865
890
|
method: "POST",
|
|
866
891
|
headers: { "Content-Type": "application/json" },
|
|
867
892
|
body: JSON.stringify(body)
|
|
@@ -870,7 +895,7 @@ async function reportUnregisteredAttempt(config, data) {
|
|
|
870
895
|
}
|
|
871
896
|
async function reportCounterpartyPreCheckFailure(config, data) {
|
|
872
897
|
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
873
|
-
await
|
|
898
|
+
await sdkFetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {
|
|
874
899
|
method: "POST",
|
|
875
900
|
headers: { "Content-Type": "application/json" },
|
|
876
901
|
body: JSON.stringify(data)
|
|
@@ -904,7 +929,7 @@ function resolvePollUrl(config, pollUrl) {
|
|
|
904
929
|
async function pollStepUpStatus(config, approval) {
|
|
905
930
|
if (!approval.pollUrl) return null;
|
|
906
931
|
try {
|
|
907
|
-
const res = await
|
|
932
|
+
const res = await sdkFetch(resolvePollUrl(config, approval.pollUrl), {
|
|
908
933
|
method: "GET",
|
|
909
934
|
signal: AbortSignal.timeout(POLL_REQUEST_TIMEOUT_MS)
|
|
910
935
|
});
|
|
@@ -1279,7 +1304,13 @@ var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
|
1279
1304
|
"x-agent-card-url",
|
|
1280
1305
|
"x-agent-provider"
|
|
1281
1306
|
]);
|
|
1282
|
-
var PLATFORM_HEADER_PREFIXES = [
|
|
1307
|
+
var PLATFORM_HEADER_PREFIXES = [
|
|
1308
|
+
"x-goog-",
|
|
1309
|
+
"x-stainless-",
|
|
1310
|
+
"x-anthropic-",
|
|
1311
|
+
"x-openai-",
|
|
1312
|
+
"sec-ch-"
|
|
1313
|
+
];
|
|
1283
1314
|
var KEY_FORMAT_PREFIXES = [
|
|
1284
1315
|
"sk-ant-api03",
|
|
1285
1316
|
"sk-ant-api",
|
|
@@ -1351,6 +1382,7 @@ function sanitizeHeaders(raw) {
|
|
|
1351
1382
|
const headers = {};
|
|
1352
1383
|
const platformHeaders = {};
|
|
1353
1384
|
let apiKeyFormat;
|
|
1385
|
+
let cookieCount;
|
|
1354
1386
|
let totalBytes = 0;
|
|
1355
1387
|
let count = 0;
|
|
1356
1388
|
if (!raw) return { headers };
|
|
@@ -1365,6 +1397,9 @@ function sanitizeHeaders(raw) {
|
|
|
1365
1397
|
if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
|
|
1366
1398
|
continue;
|
|
1367
1399
|
}
|
|
1400
|
+
if (name === "cookie") {
|
|
1401
|
+
cookieCount = joined.split(";").filter((s) => s.trim().length > 0).length;
|
|
1402
|
+
}
|
|
1368
1403
|
if (isSecretHeader(name)) continue;
|
|
1369
1404
|
let value = joined;
|
|
1370
1405
|
if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
|
|
@@ -1380,6 +1415,7 @@ function sanitizeHeaders(raw) {
|
|
|
1380
1415
|
const result = { headers };
|
|
1381
1416
|
if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
|
|
1382
1417
|
if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
|
|
1418
|
+
if (cookieCount !== void 0) result.cookieCount = cookieCount;
|
|
1383
1419
|
return result;
|
|
1384
1420
|
}
|
|
1385
1421
|
function extractPlatformHeaders(sanitized) {
|
|
@@ -1399,6 +1435,9 @@ var CONNECTION_HEADER_SOURCES = [
|
|
|
1399
1435
|
["region", ["x-vercel-ip-country-region", "cloudfront-viewer-country-region"]],
|
|
1400
1436
|
["countryRegionName", ["cloudfront-viewer-country-region-name"]],
|
|
1401
1437
|
["city", ["x-vercel-ip-city", "cloudfront-viewer-city"]],
|
|
1438
|
+
["latitude", ["x-vercel-ip-latitude", "cloudfront-viewer-latitude"]],
|
|
1439
|
+
["longitude", ["x-vercel-ip-longitude", "cloudfront-viewer-longitude"]],
|
|
1440
|
+
["postalCode", ["x-vercel-ip-postal-code", "cloudfront-viewer-postal-code"]],
|
|
1402
1441
|
["asn", ["cloudfront-viewer-asn"]],
|
|
1403
1442
|
["tlsVersion", ["cloudfront-viewer-tls"]],
|
|
1404
1443
|
["httpVersion", ["cloudfront-viewer-http-version"]],
|
|
@@ -1433,19 +1472,25 @@ function deriveConnectionFromHeaders(headers) {
|
|
|
1433
1472
|
}
|
|
1434
1473
|
}
|
|
1435
1474
|
}
|
|
1436
|
-
|
|
1475
|
+
{
|
|
1437
1476
|
const addr = lower["cloudfront-viewer-address"]?.trim();
|
|
1438
|
-
|
|
1477
|
+
const portMatch = addr?.match(/:(\d+)$/);
|
|
1478
|
+
if (portMatch) connection.sourcePort = portMatch[1];
|
|
1479
|
+
if (!connection.ip && addr) connection.ip = addr.replace(/:\d+$/, "");
|
|
1439
1480
|
}
|
|
1440
1481
|
if (!connection.ip) {
|
|
1441
1482
|
const xff = lower["x-forwarded-for"];
|
|
1442
1483
|
const client = xff?.split(",")[0]?.trim();
|
|
1443
1484
|
if (client) connection.ip = client;
|
|
1444
1485
|
}
|
|
1486
|
+
if (!connection.tlsCipher) {
|
|
1487
|
+
const cipher = connection.tlsVersion?.split(":")[1];
|
|
1488
|
+
if (cipher) connection.tlsCipher = cipher;
|
|
1489
|
+
}
|
|
1445
1490
|
return Object.keys(connection).length > 0 ? connection : void 0;
|
|
1446
1491
|
}
|
|
1447
1492
|
function buildSdkObservedMetadata(rawHeaders) {
|
|
1448
|
-
const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(rawHeaders);
|
|
1493
|
+
const { headers, apiKeyFormat, platformHeaders, cookieCount } = sanitizeHeaders(rawHeaders);
|
|
1449
1494
|
const flat = {};
|
|
1450
1495
|
if (rawHeaders) {
|
|
1451
1496
|
for (const name of Object.keys(rawHeaders)) {
|
|
@@ -1460,6 +1505,7 @@ function buildSdkObservedMetadata(rawHeaders) {
|
|
|
1460
1505
|
...apiKeyFormat && { apiKeyFormat },
|
|
1461
1506
|
...platformHeaders && { platformHeaders },
|
|
1462
1507
|
...connection && { connection },
|
|
1508
|
+
...cookieCount !== void 0 && { cookieCount },
|
|
1463
1509
|
schemaVersion: CAPTURE_SCHEMA_VERSION
|
|
1464
1510
|
};
|
|
1465
1511
|
}
|
|
@@ -1504,7 +1550,7 @@ async function fetchEdgeConfig(config, counterpartyId, opts) {
|
|
|
1504
1550
|
}
|
|
1505
1551
|
if (opts?.etag) headers["If-None-Match"] = opts.etag;
|
|
1506
1552
|
try {
|
|
1507
|
-
const response = await
|
|
1553
|
+
const response = await sdkFetch(
|
|
1508
1554
|
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/edge-config`,
|
|
1509
1555
|
{ method: "GET", headers, signal: AbortSignal.timeout(opts?.timeoutMs ?? 5e3) }
|
|
1510
1556
|
);
|
|
@@ -1630,12 +1676,43 @@ var PLATFORM_AGENT_SIGNATURES = [
|
|
|
1630
1676
|
uaPatterns: [/perplexity/i],
|
|
1631
1677
|
agentCardPatterns: [/perplexity\.ai/i],
|
|
1632
1678
|
apiKeyFormatPatterns: [/^pplx-/i]
|
|
1679
|
+
},
|
|
1680
|
+
// Agentic browsers — versioned-token patterns ONLY (a stock Chrome UA must
|
|
1681
|
+
// never match). Distinct vendor keys (not 'chatgpt'/'perplexity'): the
|
|
1682
|
+
// browser product is a different surface than the assistant service, and
|
|
1683
|
+
// the DB registry mirrors one row per vendor. These sit after the primary
|
|
1684
|
+
// vendor entries so a UA carrying an explicit vendor token keeps its
|
|
1685
|
+
// primary attribution; a browser-shaped UA with the agentic token is
|
|
1686
|
+
// caught here BEFORE classify's human tier, which is what makes these
|
|
1687
|
+
// visits observable at all. Token drift is real (some builds mimic Chrome
|
|
1688
|
+
// outright) — re-verify against captured events when a new browser ships,
|
|
1689
|
+
// and check `sec-ch-ua` platformHeaders for the real brand.
|
|
1690
|
+
{
|
|
1691
|
+
vendor: "chatgpt-atlas",
|
|
1692
|
+
displayName: "ChatGPT Atlas browser",
|
|
1693
|
+
uaPatterns: [/\batlas\/\d/i],
|
|
1694
|
+
headerPatterns: [/^sec-ch-ua: .*atlas/i]
|
|
1695
|
+
},
|
|
1696
|
+
{
|
|
1697
|
+
vendor: "perplexity-comet",
|
|
1698
|
+
displayName: "Perplexity Comet browser",
|
|
1699
|
+
uaPatterns: [/\bcomet\/\d/i],
|
|
1700
|
+
headerPatterns: [/^sec-ch-ua: .*comet/i]
|
|
1701
|
+
},
|
|
1702
|
+
// Our own SDK self-identifies (sdkFetch stamps this UA) — first-party
|
|
1703
|
+
// traffic must never pollute the unknown/anonymous pool it exists to audit.
|
|
1704
|
+
{
|
|
1705
|
+
vendor: "astrasync-sdk",
|
|
1706
|
+
displayName: "AstraSync SDK",
|
|
1707
|
+
uaPatterns: [/^astrasync-sdk\//i]
|
|
1633
1708
|
}
|
|
1634
1709
|
];
|
|
1635
1710
|
function matchPlatformSignature(signatures, input) {
|
|
1636
1711
|
const ua = input.userAgent ?? "";
|
|
1637
1712
|
const cardUrl = input.agentCardUrl ?? "";
|
|
1638
1713
|
const apiKeyFormat = input.apiKeyFormat ?? "";
|
|
1714
|
+
const ja4 = input.ja4 ?? "";
|
|
1715
|
+
const asn = input.asn ?? "";
|
|
1639
1716
|
const headerLines = [];
|
|
1640
1717
|
if (input.platformHeaders) {
|
|
1641
1718
|
for (const [name, value] of Object.entries(input.platformHeaders)) {
|
|
@@ -1647,7 +1724,9 @@ function matchPlatformSignature(signatures, input) {
|
|
|
1647
1724
|
const cardMatch = sig.agentCardPatterns?.some((p) => p.test(cardUrl));
|
|
1648
1725
|
const keyMatch = apiKeyFormat.length > 0 && sig.apiKeyFormatPatterns?.some((p) => p.test(apiKeyFormat));
|
|
1649
1726
|
const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
|
|
1650
|
-
|
|
1727
|
+
const ja4Match = ja4.length > 0 && sig.ja4Patterns?.some((p) => p.test(ja4));
|
|
1728
|
+
const asnMatch = asn.length > 0 && sig.asnList?.includes(asn);
|
|
1729
|
+
if (uaMatch || cardMatch || keyMatch || headerMatch || ja4Match || asnMatch) {
|
|
1651
1730
|
const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
|
|
1652
1731
|
const cardHost = (() => {
|
|
1653
1732
|
try {
|
|
@@ -1656,7 +1735,7 @@ function matchPlatformSignature(signatures, input) {
|
|
|
1656
1735
|
return "";
|
|
1657
1736
|
}
|
|
1658
1737
|
})();
|
|
1659
|
-
const keyBasis = uaBase || cardHost || apiKeyFormat || "unknown";
|
|
1738
|
+
const keyBasis = uaBase || cardHost || apiKeyFormat || ja4 || asn && `asn${asn}` || "unknown";
|
|
1660
1739
|
return {
|
|
1661
1740
|
vendor: sig.vendor,
|
|
1662
1741
|
fingerprintKey: `${sig.vendor}:${keyBasis}`,
|
|
@@ -1672,9 +1751,10 @@ function detectPlatformFingerprint(input) {
|
|
|
1672
1751
|
|
|
1673
1752
|
// src/edge-core/classify.ts
|
|
1674
1753
|
var STATIC_EXTENSIONS = /\.(css|js|mjs|map|png|jpe?g|gif|webp|avif|svg|ico|woff2?|ttf|otf|eot|mp4|webm|pdf|txt|xml)$/i;
|
|
1754
|
+
var SELF_UA_PATTERN = /^astrasync-sdk\//i;
|
|
1675
1755
|
var BOT_UA_PATTERN = /curl|wget|python-requests|python-urllib|node-fetch|axios|got|okhttp|go-http-client|libwww|httpie|java\/|ruby|php|scrapy|headless|phantomjs|selenium|playwright|puppeteer|bot|crawler|spider|slurp/i;
|
|
1676
1756
|
var BROWSER_UA_PATTERN = /mozilla\/\d/i;
|
|
1677
|
-
var _patterns = { STATIC_EXTENSIONS, BOT_UA_PATTERN, BROWSER_UA_PATTERN };
|
|
1757
|
+
var _patterns = { STATIC_EXTENSIONS, BOT_UA_PATTERN, BROWSER_UA_PATTERN, SELF_UA_PATTERN };
|
|
1678
1758
|
|
|
1679
1759
|
// src/edge-core/events.ts
|
|
1680
1760
|
function sampled(rate, random = Math.random) {
|
|
@@ -2094,7 +2174,7 @@ function createMiddleware(options) {
|
|
|
2094
2174
|
let result = await verify(config, verificationRequest);
|
|
2095
2175
|
req.agentVerification = result;
|
|
2096
2176
|
let sessionId = result.sessionId;
|
|
2097
|
-
if (config.stepUpMaxWaitMs !== void 0 && result.
|
|
2177
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.policyAllowed && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
2098
2178
|
const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
2099
2179
|
res.setHeader("X-Astra-Step-Up", outcome);
|
|
2100
2180
|
if (outcome === "approved") {
|
|
@@ -2105,7 +2185,7 @@ function createMiddleware(options) {
|
|
|
2105
2185
|
result.stepUpOutcome = outcome;
|
|
2106
2186
|
}
|
|
2107
2187
|
}
|
|
2108
|
-
if (!result.
|
|
2188
|
+
if (!result.policyAllowed) {
|
|
2109
2189
|
if (shouldRecordDecisions && sessionId) {
|
|
2110
2190
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
2111
2191
|
});
|
|
@@ -2606,7 +2686,7 @@ function createMiddleware2(options) {
|
|
|
2606
2686
|
};
|
|
2607
2687
|
let result = await verify(config, verificationRequest);
|
|
2608
2688
|
let stepUpHoldOutcome;
|
|
2609
|
-
if (config.stepUpMaxWaitMs !== void 0 && result.
|
|
2689
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.policyAllowed && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
2610
2690
|
stepUpHoldOutcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
2611
2691
|
if (stepUpHoldOutcome === "approved") {
|
|
2612
2692
|
result = await verify(config, verificationRequest, { bypassCache: true });
|
|
@@ -2614,9 +2694,9 @@ function createMiddleware2(options) {
|
|
|
2614
2694
|
result.stepUpOutcome = stepUpHoldOutcome;
|
|
2615
2695
|
}
|
|
2616
2696
|
}
|
|
2617
|
-
const approvalRequired = result.
|
|
2697
|
+
const approvalRequired = result.policyAllowed && requiresHumanApproval(result);
|
|
2618
2698
|
if (approvalRequired) annotateApprovalRequired(result);
|
|
2619
|
-
if (!result.
|
|
2699
|
+
if (!result.policyAllowed || approvalRequired) {
|
|
2620
2700
|
if (result.misconfigured && pathname.startsWith("/api/")) {
|
|
2621
2701
|
return NextResponse.json(
|
|
2622
2702
|
{
|
|
@@ -3487,7 +3567,7 @@ async function fetchUCPManifest(manifestUrl, options = {}) {
|
|
|
3487
3567
|
const controller = new AbortController();
|
|
3488
3568
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
3489
3569
|
try {
|
|
3490
|
-
const res = await
|
|
3570
|
+
const res = await sdkFetch(manifestUrl, { signal: controller.signal });
|
|
3491
3571
|
if (!res.ok) return null;
|
|
3492
3572
|
return await res.json();
|
|
3493
3573
|
} catch {
|
|
@@ -5749,7 +5829,7 @@ function createMcpMiddleware(options) {
|
|
|
5749
5829
|
let result = await verify(config, verificationRequest);
|
|
5750
5830
|
req.agentVerification = result;
|
|
5751
5831
|
let sessionId = result.sessionId;
|
|
5752
|
-
if (config.stepUpMaxWaitMs !== void 0 && result.
|
|
5832
|
+
if (config.stepUpMaxWaitMs !== void 0 && result.policyAllowed && requiresHumanApproval(result) && result.stepUpApproval?.pollUrl) {
|
|
5753
5833
|
const outcome = await awaitStepUpApproval(config, result.stepUpApproval);
|
|
5754
5834
|
res.setHeader("X-Astra-Step-Up", outcome);
|
|
5755
5835
|
if (outcome === "approved") {
|
|
@@ -5760,7 +5840,7 @@ function createMcpMiddleware(options) {
|
|
|
5760
5840
|
result.stepUpOutcome = outcome;
|
|
5761
5841
|
}
|
|
5762
5842
|
}
|
|
5763
|
-
if (!result.
|
|
5843
|
+
if (!result.policyAllowed) {
|
|
5764
5844
|
if (shouldRecordDecisions && sessionId) {
|
|
5765
5845
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
5766
5846
|
});
|
|
@@ -6032,7 +6112,7 @@ var AstraSync = class {
|
|
|
6032
6112
|
*/
|
|
6033
6113
|
async pollRegistration(requestId) {
|
|
6034
6114
|
const url = `${this.baseUrl}/api/agents/request-registration/${requestId}`;
|
|
6035
|
-
const res = await
|
|
6115
|
+
const res = await sdkFetch(url, { headers: { Accept: "application/json" } });
|
|
6036
6116
|
if (!res.ok) {
|
|
6037
6117
|
const errBody = await res.json().catch(() => ({}));
|
|
6038
6118
|
throw new AstraSyncError(
|
|
@@ -6089,7 +6169,7 @@ var AstraSync = class {
|
|
|
6089
6169
|
* Check API health.
|
|
6090
6170
|
*/
|
|
6091
6171
|
async health() {
|
|
6092
|
-
const res = await
|
|
6172
|
+
const res = await sdkFetch(`${this.baseUrl}/api/health/`);
|
|
6093
6173
|
if (!res.ok) {
|
|
6094
6174
|
throw new AstraSyncError(`Health check failed: ${res.status}`, res.status);
|
|
6095
6175
|
}
|
|
@@ -6116,7 +6196,7 @@ var AstraSync = class {
|
|
|
6116
6196
|
const signature = await this.signRequest(method, endpoint, body || {});
|
|
6117
6197
|
headers["X-AstraSync-Signature"] = signature;
|
|
6118
6198
|
}
|
|
6119
|
-
const res = await
|
|
6199
|
+
const res = await sdkFetch(url, {
|
|
6120
6200
|
method,
|
|
6121
6201
|
headers,
|
|
6122
6202
|
...body ? { body: JSON.stringify(body) } : {}
|
|
@@ -6141,7 +6221,7 @@ var AstraSync = class {
|
|
|
6141
6221
|
if (this.cachedJwt && this.jwtExpiresAt && Date.now() < this.jwtExpiresAt) {
|
|
6142
6222
|
return this.cachedJwt;
|
|
6143
6223
|
}
|
|
6144
|
-
const res = await
|
|
6224
|
+
const res = await sdkFetch(`${this.baseUrl}/api/auth/login`, {
|
|
6145
6225
|
method: "POST",
|
|
6146
6226
|
headers: { "Content-Type": "application/json" },
|
|
6147
6227
|
body: JSON.stringify({ email: this.email, password: this.password })
|
|
@@ -6284,7 +6364,7 @@ var AgentClient = class _AgentClient {
|
|
|
6284
6364
|
const url = `${this.apiBaseUrl.replace(/\/+$/, "")}/api/agents/${encodeURIComponent(
|
|
6285
6365
|
this.credentials.agentId
|
|
6286
6366
|
)}/ownership`;
|
|
6287
|
-
const resp = await
|
|
6367
|
+
const resp = await sdkFetch(url, {
|
|
6288
6368
|
method: "GET",
|
|
6289
6369
|
headers: {
|
|
6290
6370
|
Authorization: `Bearer ${this.apiKey}`,
|
|
@@ -6322,7 +6402,7 @@ var AgentClient = class _AgentClient {
|
|
|
6322
6402
|
}
|
|
6323
6403
|
}
|
|
6324
6404
|
const enrichedHeaders = setHttpHeaders(existingHeaders, creds);
|
|
6325
|
-
return
|
|
6405
|
+
return sdkFetch(url, {
|
|
6326
6406
|
...fetchOptions,
|
|
6327
6407
|
headers: enrichedHeaders
|
|
6328
6408
|
});
|
|
@@ -6511,7 +6591,7 @@ async function recordDecision2(config, params) {
|
|
|
6511
6591
|
if (config.customHeaders) {
|
|
6512
6592
|
Object.assign(headers, config.customHeaders);
|
|
6513
6593
|
}
|
|
6514
|
-
const response = await
|
|
6594
|
+
const response = await sdkFetch(url, {
|
|
6515
6595
|
method: "POST",
|
|
6516
6596
|
headers,
|
|
6517
6597
|
body: JSON.stringify(body)
|
|
@@ -6528,6 +6608,51 @@ async function recordDecision2(config, params) {
|
|
|
6528
6608
|
blockchainTxHash: result.blockchainTxHash
|
|
6529
6609
|
};
|
|
6530
6610
|
}
|
|
6611
|
+
|
|
6612
|
+
// src/runtime-signatures.ts
|
|
6613
|
+
var RUNTIME_SIGNATURES = [
|
|
6614
|
+
{
|
|
6615
|
+
runtime: "browser-automation",
|
|
6616
|
+
displayName: "Browser automation",
|
|
6617
|
+
uaPatterns: [/headless/i, /phantomjs/i, /selenium/i, /playwright/i, /puppeteer/i]
|
|
6618
|
+
},
|
|
6619
|
+
{
|
|
6620
|
+
runtime: "nodejs",
|
|
6621
|
+
displayName: "Node.js runtime",
|
|
6622
|
+
// `node` exactly is the global-fetch default UA; the token forms cover
|
|
6623
|
+
// the common Node HTTP libraries.
|
|
6624
|
+
uaPatterns: [/^node$/i, /^undici/i, /node-fetch/i, /^axios/i, /^got\b/i, /needle/i]
|
|
6625
|
+
},
|
|
6626
|
+
{
|
|
6627
|
+
runtime: "python",
|
|
6628
|
+
displayName: "Python runtime",
|
|
6629
|
+
uaPatterns: [/python-requests/i, /python-urllib/i, /^python\b/i, /httpx/i, /aiohttp/i]
|
|
6630
|
+
},
|
|
6631
|
+
{ runtime: "go", displayName: "Go runtime", uaPatterns: [/go-http-client/i] },
|
|
6632
|
+
{
|
|
6633
|
+
runtime: "java",
|
|
6634
|
+
displayName: "Java runtime",
|
|
6635
|
+
uaPatterns: [/^java\//i, /okhttp/i, /apache-httpclient/i]
|
|
6636
|
+
},
|
|
6637
|
+
{ runtime: "curl", displayName: "curl", uaPatterns: [/^curl\//i] },
|
|
6638
|
+
{ runtime: "wget", displayName: "wget", uaPatterns: [/^wget\//i] },
|
|
6639
|
+
{ runtime: "ruby", displayName: "Ruby runtime", uaPatterns: [/^ruby\b/i, /faraday/i] },
|
|
6640
|
+
{
|
|
6641
|
+
runtime: "php",
|
|
6642
|
+
displayName: "PHP runtime",
|
|
6643
|
+
uaPatterns: [/^php\b/i, /guzzlehttp/i, /^symfony/i]
|
|
6644
|
+
},
|
|
6645
|
+
{ runtime: "dotnet", displayName: ".NET runtime", uaPatterns: [/^dotnet/i, /httpclient/i] },
|
|
6646
|
+
{ runtime: "dart", displayName: "Dart runtime", uaPatterns: [/^dart/i] }
|
|
6647
|
+
];
|
|
6648
|
+
function detectRuntime(userAgent) {
|
|
6649
|
+
if (!userAgent) return void 0;
|
|
6650
|
+
const ua = userAgent.trim();
|
|
6651
|
+
for (const sig of RUNTIME_SIGNATURES) {
|
|
6652
|
+
if (sig.uaPatterns.some((p) => p.test(ua))) return sig.displayName;
|
|
6653
|
+
}
|
|
6654
|
+
return void 0;
|
|
6655
|
+
}
|
|
6531
6656
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6532
6657
|
0 && (module.exports = {
|
|
6533
6658
|
ACCESS_LEVEL_DESCRIPTIONS,
|
|
@@ -6545,9 +6670,11 @@ async function recordDecision2(config, params) {
|
|
|
6545
6670
|
MAX_HEADER_VALUE_BYTES,
|
|
6546
6671
|
MAX_TOTAL_BYTES,
|
|
6547
6672
|
PLATFORM_AGENT_SIGNATURES,
|
|
6673
|
+
RUNTIME_SIGNATURES,
|
|
6548
6674
|
RegistrationDeniedError,
|
|
6549
6675
|
RegistrationExpiredError,
|
|
6550
6676
|
RegistrationTimeoutError,
|
|
6677
|
+
SDK_USER_AGENT,
|
|
6551
6678
|
TRUST_LEVEL_RANGES,
|
|
6552
6679
|
VERSION,
|
|
6553
6680
|
_resetEdgeConfigCache,
|
|
@@ -6561,6 +6688,7 @@ async function recordDecision2(config, params) {
|
|
|
6561
6688
|
degradeToObserve,
|
|
6562
6689
|
deriveConnectionFromHeaders,
|
|
6563
6690
|
detectPlatformFingerprint,
|
|
6691
|
+
detectRuntime,
|
|
6564
6692
|
determineAccessLevel,
|
|
6565
6693
|
express,
|
|
6566
6694
|
extractApiKeyFormat,
|
|
@@ -6589,6 +6717,7 @@ async function recordDecision2(config, params) {
|
|
|
6589
6717
|
reportUnregisteredAttempt,
|
|
6590
6718
|
sanitizeHeaders,
|
|
6591
6719
|
sdk,
|
|
6720
|
+
sdkFetch,
|
|
6592
6721
|
setMcpMeta,
|
|
6593
6722
|
transport,
|
|
6594
6723
|
verify
|