@astrasyncai/verification-gateway 3.8.0 → 3.10.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/adapter-interface/interface.d.mts +3 -2
- package/dist/adapter-interface/interface.d.ts +3 -2
- package/dist/adapters/express.d.mts +3 -2
- package/dist/adapters/express.d.ts +3 -2
- package/dist/adapters/express.js +152 -2
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +152 -2
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/http-pdlss.d.mts +81 -0
- package/dist/adapters/http-pdlss.d.ts +81 -0
- package/dist/adapters/http-pdlss.js +117 -0
- package/dist/adapters/http-pdlss.js.map +1 -0
- package/dist/adapters/http-pdlss.mjs +87 -0
- package/dist/adapters/http-pdlss.mjs.map +1 -0
- package/dist/adapters/mcp.d.mts +2 -1
- package/dist/adapters/mcp.d.ts +2 -1
- package/dist/adapters/mcp.js +2 -1
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +2 -1
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +3 -2
- package/dist/adapters/nextjs.d.ts +3 -2
- package/dist/adapters/nextjs.js +152 -2
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +152 -2
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +3 -2
- package/dist/adapters/sdk.d.ts +3 -2
- package/dist/adapters/sdk.js +2 -1
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +2 -1
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +3 -2
- package/dist/agent/index.d.ts +3 -2
- package/dist/bin/astrasync-claude-hook.js +17 -1
- package/dist/bin/astrasync-guard.js +17 -1
- package/dist/bin/astrasync.js +43 -1
- package/dist/browser/background.js +17 -1
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +17 -1
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +3 -2
- package/dist/browser/browser-adapter.d.ts +3 -2
- package/dist/claude-code/claude-code-adapter.d.mts +3 -2
- package/dist/claude-code/claude-code-adapter.d.ts +3 -2
- package/dist/cli/index.d.mts +3 -2
- package/dist/cli/index.d.ts +3 -2
- package/dist/cursor/cursor-adapter.d.mts +3 -2
- package/dist/cursor/cursor-adapter.d.ts +3 -2
- package/dist/cursor/extension.d.mts +3 -2
- package/dist/cursor/extension.d.ts +3 -2
- package/dist/cursor/extension.js +17 -1
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +17 -1
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +131 -0
- package/dist/edge-config.d.ts +131 -0
- package/dist/edge-config.js +162 -0
- package/dist/edge-config.js.map +1 -0
- package/dist/edge-config.mjs +131 -0
- package/dist/edge-config.mjs.map +1 -0
- package/dist/{express-C8nJGi5P.d.ts → express-ClNtDhhc.d.ts} +1 -1
- package/dist/{express-Di_hnZZS.d.mts → express-DCXa1oqj.d.mts} +1 -1
- package/dist/gateway/gateway.d.mts +3 -2
- package/dist/gateway/gateway.d.ts +3 -2
- package/dist/gateway/gateway.js +17 -1
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +17 -1
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +3 -2
- package/dist/git-trigger/git-hooks.d.ts +3 -2
- package/dist/{index-CXcvO9Au.d.mts → index-BrNKDmiR.d.mts} +1 -1
- package/dist/{index-CuCkjT7B.d.ts → index-CfHurO1P.d.ts} +1 -1
- package/dist/{index-CBQr4FGs.d.ts → index-D2ztkumS.d.ts} +1 -1
- package/dist/{index-DALAqct7.d.mts → index-Dr_XiN65.d.mts} +1 -1
- package/dist/index.d.mts +27 -82
- package/dist/index.d.ts +27 -82
- package/dist/index.js +435 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +417 -12
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +3 -2
- package/dist/local-evaluator/evaluator.d.ts +3 -2
- package/dist/metadata-capture.d.mts +87 -0
- package/dist/metadata-capture.d.ts +87 -0
- package/dist/metadata-capture.js +184 -0
- package/dist/metadata-capture.js.map +1 -0
- package/dist/metadata-capture.mjs +154 -0
- package/dist/metadata-capture.mjs.map +1 -0
- package/dist/{nextjs-IyXWW2KL.d.ts → nextjs-CEBVBsdi.d.ts} +1 -1
- package/dist/{nextjs-BMAe8ode.d.mts → nextjs-DcQIk6Zj.d.mts} +1 -1
- package/dist/platform-signatures.d.mts +97 -0
- package/dist/platform-signatures.d.ts +97 -0
- package/dist/platform-signatures.js +116 -0
- package/dist/platform-signatures.js.map +1 -0
- package/dist/platform-signatures.mjs +89 -0
- package/dist/platform-signatures.mjs.map +1 -0
- package/dist/{sdk-Cn4KcZ5G.d.mts → sdk-CZkbSOeO.d.mts} +1 -1
- package/dist/{sdk-ThdA_NtL.d.ts → sdk-H0JCLW2y.d.ts} +1 -1
- package/dist/transport/index.d.mts +3 -2
- package/dist/transport/index.d.ts +3 -2
- package/dist/{types-DedAJbNI.d.mts → types-9tns4wyl.d.ts} +88 -1
- package/dist/{types-CSFci5zD.d.mts → types-D0lCtFQ7.d.mts} +1 -1
- package/dist/{types-D1kyMiml.d.ts → types-YbiXYKx1.d.ts} +1 -1
- package/dist/{types-DedAJbNI.d.ts → types-sy3tq8lp.d.mts} +88 -1
- package/dist/ui/index.d.mts +2 -1
- package/dist/ui/index.d.ts +2 -1
- package/dist/verify.d.mts +151 -0
- package/dist/verify.d.ts +151 -0
- package/dist/verify.js +593 -0
- package/dist/verify.js.map +1 -0
- package/dist/verify.mjs +557 -0
- package/dist/verify.mjs.map +1 -0
- package/package.json +26 -1
package/dist/index.mjs
CHANGED
|
@@ -126,7 +126,7 @@ function getCapabilities(accessLevel) {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
// src/version.ts
|
|
129
|
-
var SDK_VERSION = "3.
|
|
129
|
+
var SDK_VERSION = "3.10.0";
|
|
130
130
|
|
|
131
131
|
// src/well-known.ts
|
|
132
132
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -413,6 +413,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
413
413
|
if (requestData.runtimeChallengeOptions)
|
|
414
414
|
body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
|
|
415
415
|
if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
|
|
416
|
+
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
416
417
|
body.sdkVersion = SDK_VERSION;
|
|
417
418
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
418
419
|
const meta = {
|
|
@@ -661,6 +662,21 @@ async function fetchRoutes(config, counterpartyId) {
|
|
|
661
662
|
return null;
|
|
662
663
|
}
|
|
663
664
|
}
|
|
665
|
+
async function reportUnregisteredAttempt(config, data) {
|
|
666
|
+
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
667
|
+
const { counterpartyUrl, ...rest } = data;
|
|
668
|
+
const body = {
|
|
669
|
+
...rest,
|
|
670
|
+
...counterpartyUrl && { counterpartyUrl },
|
|
671
|
+
...config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
672
|
+
};
|
|
673
|
+
await fetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
|
|
674
|
+
method: "POST",
|
|
675
|
+
headers: { "Content-Type": "application/json" },
|
|
676
|
+
body: JSON.stringify(body)
|
|
677
|
+
}).catch(() => {
|
|
678
|
+
});
|
|
679
|
+
}
|
|
664
680
|
async function reportCounterpartyPreCheckFailure(config, data) {
|
|
665
681
|
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
666
682
|
await fetch(`${apiBaseUrl}/verification-activity/counterparty-pre-check-failure`, {
|
|
@@ -1007,6 +1023,152 @@ function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
|
|
|
1007
1023
|
return failures;
|
|
1008
1024
|
}
|
|
1009
1025
|
|
|
1026
|
+
// src/metadata-capture.ts
|
|
1027
|
+
var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
1028
|
+
"cookie",
|
|
1029
|
+
"set-cookie",
|
|
1030
|
+
"x-csrf-token",
|
|
1031
|
+
"proxy-authorization",
|
|
1032
|
+
"x-astrasync-signature",
|
|
1033
|
+
"x-astrasync-secret",
|
|
1034
|
+
"x-hub-signature",
|
|
1035
|
+
"x-hub-signature-256"
|
|
1036
|
+
]);
|
|
1037
|
+
var SECRET_HEADER_PREFIXES = ["x-astrasync-", "kya-", "kya_"];
|
|
1038
|
+
var CREDENTIAL_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
1039
|
+
"authorization",
|
|
1040
|
+
"x-api-key",
|
|
1041
|
+
"x-goog-api-key",
|
|
1042
|
+
"api-key"
|
|
1043
|
+
]);
|
|
1044
|
+
function isSignatureHeader(name) {
|
|
1045
|
+
return name === "signature" || name.endsWith("-signature") || name.endsWith("-signature-256");
|
|
1046
|
+
}
|
|
1047
|
+
var PLATFORM_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
1048
|
+
"openai-organization",
|
|
1049
|
+
"openai-project",
|
|
1050
|
+
"openai-version",
|
|
1051
|
+
"openai-processing-ms",
|
|
1052
|
+
"anthropic-version",
|
|
1053
|
+
"anthropic-beta",
|
|
1054
|
+
"x-goog-user-project",
|
|
1055
|
+
"x-goog-api-client",
|
|
1056
|
+
"user-agent",
|
|
1057
|
+
"x-agent-card-url",
|
|
1058
|
+
"x-agent-provider"
|
|
1059
|
+
]);
|
|
1060
|
+
var PLATFORM_HEADER_PREFIXES = ["x-goog-", "x-stainless-", "x-anthropic-", "x-openai-"];
|
|
1061
|
+
var KEY_FORMAT_PREFIXES = [
|
|
1062
|
+
"sk-ant-api03",
|
|
1063
|
+
"sk-ant-api",
|
|
1064
|
+
"sk-ant",
|
|
1065
|
+
"sk-proj",
|
|
1066
|
+
"sk-svcacct",
|
|
1067
|
+
"sk-or-v1",
|
|
1068
|
+
"sk-or",
|
|
1069
|
+
"sk-lf",
|
|
1070
|
+
"sk-",
|
|
1071
|
+
"gsk_",
|
|
1072
|
+
"aiza",
|
|
1073
|
+
"ya29",
|
|
1074
|
+
"ghp_",
|
|
1075
|
+
"gho_",
|
|
1076
|
+
"github_pat_",
|
|
1077
|
+
"xai-",
|
|
1078
|
+
"pplx-",
|
|
1079
|
+
"r8_",
|
|
1080
|
+
"hf_",
|
|
1081
|
+
"astra-",
|
|
1082
|
+
"astrae-"
|
|
1083
|
+
];
|
|
1084
|
+
var MAX_HEADERS = 64;
|
|
1085
|
+
var MAX_HEADER_VALUE_BYTES = 1024;
|
|
1086
|
+
var MAX_TOTAL_BYTES = 16 * 1024;
|
|
1087
|
+
function byteLength(s) {
|
|
1088
|
+
let bytes = 0;
|
|
1089
|
+
for (let i = 0; i < s.length; i++) {
|
|
1090
|
+
const code = s.charCodeAt(i);
|
|
1091
|
+
if (code < 128) bytes += 1;
|
|
1092
|
+
else if (code < 2048) bytes += 2;
|
|
1093
|
+
else if (code >= 55296 && code <= 56319) {
|
|
1094
|
+
bytes += 4;
|
|
1095
|
+
i++;
|
|
1096
|
+
} else bytes += 3;
|
|
1097
|
+
}
|
|
1098
|
+
return bytes;
|
|
1099
|
+
}
|
|
1100
|
+
function extractApiKeyFormat(rawValue) {
|
|
1101
|
+
if (!rawValue) return void 0;
|
|
1102
|
+
let value = rawValue.trim();
|
|
1103
|
+
const spaceIdx = value.indexOf(" ");
|
|
1104
|
+
if (spaceIdx > 0) {
|
|
1105
|
+
const scheme = value.slice(0, spaceIdx).toLowerCase();
|
|
1106
|
+
if (scheme === "bearer" || scheme === "basic" || scheme === "token") {
|
|
1107
|
+
value = value.slice(spaceIdx + 1).trim();
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
const lower = value.toLowerCase();
|
|
1111
|
+
for (const prefix of KEY_FORMAT_PREFIXES) {
|
|
1112
|
+
if (lower.startsWith(prefix)) {
|
|
1113
|
+
return prefix;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
return void 0;
|
|
1117
|
+
}
|
|
1118
|
+
function isSecretHeader(name) {
|
|
1119
|
+
if (SECRET_HEADER_NAMES.has(name)) return true;
|
|
1120
|
+
if (SECRET_HEADER_PREFIXES.some((p) => name.startsWith(p))) return true;
|
|
1121
|
+
if (isSignatureHeader(name)) return true;
|
|
1122
|
+
return false;
|
|
1123
|
+
}
|
|
1124
|
+
function isPlatformHeader(name) {
|
|
1125
|
+
if (PLATFORM_HEADER_NAMES.has(name)) return true;
|
|
1126
|
+
return PLATFORM_HEADER_PREFIXES.some((p) => name.startsWith(p));
|
|
1127
|
+
}
|
|
1128
|
+
function sanitizeHeaders(raw) {
|
|
1129
|
+
const headers = {};
|
|
1130
|
+
const platformHeaders = {};
|
|
1131
|
+
let apiKeyFormat;
|
|
1132
|
+
let totalBytes = 0;
|
|
1133
|
+
let count = 0;
|
|
1134
|
+
if (!raw) return { headers };
|
|
1135
|
+
for (const rawName of Object.keys(raw)) {
|
|
1136
|
+
if (count >= MAX_HEADERS) break;
|
|
1137
|
+
const name = rawName.toLowerCase();
|
|
1138
|
+
const rawValue = raw[rawName];
|
|
1139
|
+
if (rawValue === void 0) continue;
|
|
1140
|
+
const joined = Array.isArray(rawValue) ? rawValue.join(", ") : String(rawValue);
|
|
1141
|
+
if (CREDENTIAL_HEADER_NAMES.has(name)) {
|
|
1142
|
+
const fmt = extractApiKeyFormat(joined);
|
|
1143
|
+
if (fmt && !apiKeyFormat) apiKeyFormat = fmt;
|
|
1144
|
+
continue;
|
|
1145
|
+
}
|
|
1146
|
+
if (isSecretHeader(name)) continue;
|
|
1147
|
+
let value = joined;
|
|
1148
|
+
if (byteLength(value) > MAX_HEADER_VALUE_BYTES) {
|
|
1149
|
+
value = value.slice(0, MAX_HEADER_VALUE_BYTES);
|
|
1150
|
+
}
|
|
1151
|
+
const entryBytes = byteLength(name) + byteLength(value);
|
|
1152
|
+
if (totalBytes + entryBytes > MAX_TOTAL_BYTES) continue;
|
|
1153
|
+
totalBytes += entryBytes;
|
|
1154
|
+
count++;
|
|
1155
|
+
headers[name] = value;
|
|
1156
|
+
if (isPlatformHeader(name)) platformHeaders[name] = value;
|
|
1157
|
+
}
|
|
1158
|
+
const result = { headers };
|
|
1159
|
+
if (apiKeyFormat) result.apiKeyFormat = apiKeyFormat;
|
|
1160
|
+
if (Object.keys(platformHeaders).length > 0) result.platformHeaders = platformHeaders;
|
|
1161
|
+
return result;
|
|
1162
|
+
}
|
|
1163
|
+
function extractPlatformHeaders(sanitized) {
|
|
1164
|
+
const out = {};
|
|
1165
|
+
if (!sanitized) return out;
|
|
1166
|
+
for (const name of Object.keys(sanitized)) {
|
|
1167
|
+
if (isPlatformHeader(name.toLowerCase())) out[name.toLowerCase()] = sanitized[name];
|
|
1168
|
+
}
|
|
1169
|
+
return out;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1010
1172
|
// src/adapters/express.ts
|
|
1011
1173
|
function defaultExtractCredentials(req) {
|
|
1012
1174
|
return extractCredentials(
|
|
@@ -1273,7 +1435,18 @@ function createMiddleware(options) {
|
|
|
1273
1435
|
referer: req.headers.referer,
|
|
1274
1436
|
host: req.headers.host,
|
|
1275
1437
|
forwardedFor: forwardedForStr,
|
|
1276
|
-
agentCardUrl
|
|
1438
|
+
agentCardUrl,
|
|
1439
|
+
// Workstream D — capture EVERY inbound header (SDK-only merchants
|
|
1440
|
+
// have no edge to do it upstream). Local string work, secrets
|
|
1441
|
+
// stripped; out of the verify cache key so it doesn't defeat caching.
|
|
1442
|
+
observedMetadata: (() => {
|
|
1443
|
+
const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(req.headers);
|
|
1444
|
+
return {
|
|
1445
|
+
headers,
|
|
1446
|
+
...apiKeyFormat && { apiKeyFormat },
|
|
1447
|
+
...platformHeaders && { platformHeaders }
|
|
1448
|
+
};
|
|
1449
|
+
})()
|
|
1277
1450
|
}
|
|
1278
1451
|
};
|
|
1279
1452
|
let result = await verify(config, verificationRequest);
|
|
@@ -1753,7 +1926,18 @@ function createMiddleware2(options) {
|
|
|
1753
1926
|
referer: request.headers.get("referer") || void 0,
|
|
1754
1927
|
host: request.headers.get("host") || void 0,
|
|
1755
1928
|
forwardedFor,
|
|
1756
|
-
agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
|
|
1929
|
+
agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0,
|
|
1930
|
+
// Workstream D — full sanitised header capture (Web Headers → plain map).
|
|
1931
|
+
observedMetadata: (() => {
|
|
1932
|
+
const { headers, apiKeyFormat, platformHeaders } = sanitizeHeaders(
|
|
1933
|
+
Object.fromEntries(request.headers.entries())
|
|
1934
|
+
);
|
|
1935
|
+
return {
|
|
1936
|
+
headers,
|
|
1937
|
+
...apiKeyFormat && { apiKeyFormat },
|
|
1938
|
+
...platformHeaders && { platformHeaders }
|
|
1939
|
+
};
|
|
1940
|
+
})()
|
|
1757
1941
|
}
|
|
1758
1942
|
};
|
|
1759
1943
|
let result = await verify(config, verificationRequest);
|
|
@@ -4429,7 +4613,7 @@ async function exportJwkFromKeyLike(keyLike) {
|
|
|
4429
4613
|
|
|
4430
4614
|
// src/transport/registry/mastercard.ts
|
|
4431
4615
|
function createMastercardRegistry(options = {}) {
|
|
4432
|
-
const
|
|
4616
|
+
const cache3 = /* @__PURE__ */ new Map();
|
|
4433
4617
|
const ttlSec = options.cacheTtlSec ?? 3600;
|
|
4434
4618
|
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
4435
4619
|
let warned = false;
|
|
@@ -4446,7 +4630,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4446
4630
|
}
|
|
4447
4631
|
return null;
|
|
4448
4632
|
}
|
|
4449
|
-
const cached =
|
|
4633
|
+
const cached = cache3.get(kid);
|
|
4450
4634
|
if (cached && cached.expiresAt > Date.now()) return cached.jwk;
|
|
4451
4635
|
try {
|
|
4452
4636
|
const res = await fetchFn(options.registryUrl);
|
|
@@ -4455,7 +4639,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4455
4639
|
const keys = body.keys ?? [];
|
|
4456
4640
|
for (const k of keys) {
|
|
4457
4641
|
if (k.kid === kid) {
|
|
4458
|
-
|
|
4642
|
+
cache3.set(kid, { jwk: k, expiresAt: Date.now() + ttlSec * 1e3 });
|
|
4459
4643
|
return k;
|
|
4460
4644
|
}
|
|
4461
4645
|
}
|
|
@@ -4470,7 +4654,7 @@ function createMastercardRegistry(options = {}) {
|
|
|
4470
4654
|
// src/transport/registry/web-bot-auth.ts
|
|
4471
4655
|
var DIRECTORY_PATH = "/.well-known/http-message-signatures-directory";
|
|
4472
4656
|
function createWebBotAuthRegistry(options = {}) {
|
|
4473
|
-
const
|
|
4657
|
+
const cache3 = /* @__PURE__ */ new Map();
|
|
4474
4658
|
const ttlSec = options.cacheTtlSec ?? 3600;
|
|
4475
4659
|
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
4476
4660
|
return {
|
|
@@ -4479,7 +4663,7 @@ function createWebBotAuthRegistry(options = {}) {
|
|
|
4479
4663
|
if (!kid) return null;
|
|
4480
4664
|
const directoryUrl = resolveDirectoryUrl(options.directoryUrl, context?.origin);
|
|
4481
4665
|
if (!directoryUrl) return null;
|
|
4482
|
-
const cached =
|
|
4666
|
+
const cached = cache3.get(directoryUrl);
|
|
4483
4667
|
const now = Date.now();
|
|
4484
4668
|
if (cached && cached.expiresAt > now) {
|
|
4485
4669
|
return findKeyByKid(cached.keys, kid);
|
|
@@ -4489,7 +4673,7 @@ function createWebBotAuthRegistry(options = {}) {
|
|
|
4489
4673
|
if (!res.ok) return null;
|
|
4490
4674
|
const body = await res.json();
|
|
4491
4675
|
const keys = body.keys ?? [];
|
|
4492
|
-
|
|
4676
|
+
cache3.set(directoryUrl, { keys, expiresAt: now + ttlSec * 1e3 });
|
|
4493
4677
|
return findKeyByKid(keys, kid);
|
|
4494
4678
|
} catch {
|
|
4495
4679
|
return null;
|
|
@@ -5658,8 +5842,211 @@ async function recordDecision2(config, params) {
|
|
|
5658
5842
|
};
|
|
5659
5843
|
}
|
|
5660
5844
|
|
|
5661
|
-
// src/
|
|
5662
|
-
var
|
|
5845
|
+
// src/edge-config.ts
|
|
5846
|
+
var DEFAULT_EDGE_CONFIG = Object.freeze({
|
|
5847
|
+
version: 1,
|
|
5848
|
+
mode: "observe",
|
|
5849
|
+
depth: "classify",
|
|
5850
|
+
pathRules: [],
|
|
5851
|
+
sampling: Object.freeze({ anonymousBeaconRate: 0.1 }),
|
|
5852
|
+
failurePosture: "open"
|
|
5853
|
+
});
|
|
5854
|
+
var EDGE_MODES = ["observe", "enforce"];
|
|
5855
|
+
var EDGE_DEPTHS = ["classify", "authenticate", "authorize"];
|
|
5856
|
+
function isEdgeConfig(value) {
|
|
5857
|
+
if (typeof value !== "object" || value === null) return false;
|
|
5858
|
+
const v = value;
|
|
5859
|
+
if (v.version !== 1) return false;
|
|
5860
|
+
if (!EDGE_MODES.includes(v.mode)) return false;
|
|
5861
|
+
if (!EDGE_DEPTHS.includes(v.depth)) return false;
|
|
5862
|
+
if (!Array.isArray(v.pathRules)) return false;
|
|
5863
|
+
for (const rule of v.pathRules) {
|
|
5864
|
+
if (typeof rule !== "object" || rule === null) return false;
|
|
5865
|
+
const r = rule;
|
|
5866
|
+
if (typeof r.pattern !== "string" || r.pattern.length === 0) return false;
|
|
5867
|
+
if (r.mode !== void 0 && !EDGE_MODES.includes(r.mode)) return false;
|
|
5868
|
+
if (r.depth !== void 0 && !EDGE_DEPTHS.includes(r.depth)) return false;
|
|
5869
|
+
}
|
|
5870
|
+
const sampling = v.sampling;
|
|
5871
|
+
if (typeof sampling !== "object" || sampling === null || typeof sampling.anonymousBeaconRate !== "number" || sampling.anonymousBeaconRate < 0 || sampling.anonymousBeaconRate > 1) {
|
|
5872
|
+
return false;
|
|
5873
|
+
}
|
|
5874
|
+
return v.failurePosture === "open";
|
|
5875
|
+
}
|
|
5876
|
+
async function fetchEdgeConfig(config, counterpartyId, opts) {
|
|
5877
|
+
if (!counterpartyId) return null;
|
|
5878
|
+
const headers = { Accept: "application/json" };
|
|
5879
|
+
if (config.apiKey) {
|
|
5880
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
5881
|
+
headers["X-API-Key"] = config.apiKey;
|
|
5882
|
+
}
|
|
5883
|
+
if (opts?.etag) headers["If-None-Match"] = opts.etag;
|
|
5884
|
+
try {
|
|
5885
|
+
const response = await fetch(
|
|
5886
|
+
`${config.apiBaseUrl}/endpoints/${encodeURIComponent(counterpartyId)}/edge-config`,
|
|
5887
|
+
{ method: "GET", headers, signal: AbortSignal.timeout(opts?.timeoutMs ?? 5e3) }
|
|
5888
|
+
);
|
|
5889
|
+
if (response.status === 304) return { notModified: true };
|
|
5890
|
+
if (!response.ok) return null;
|
|
5891
|
+
const body = await response.json();
|
|
5892
|
+
const edgeConfig = body.data?.edgeConfig;
|
|
5893
|
+
if (!isEdgeConfig(edgeConfig)) return null;
|
|
5894
|
+
return { edgeConfig, etag: response.headers.get("etag") ?? void 0 };
|
|
5895
|
+
} catch {
|
|
5896
|
+
return null;
|
|
5897
|
+
}
|
|
5898
|
+
}
|
|
5899
|
+
var DEFAULT_TTL_MS = 60 * 1e3;
|
|
5900
|
+
var DEFAULT_MAX_STALE_MS = 24 * 60 * 60 * 1e3;
|
|
5901
|
+
var cache2 = /* @__PURE__ */ new Map();
|
|
5902
|
+
var inflight2 = /* @__PURE__ */ new Map();
|
|
5903
|
+
function cacheKey(apiBaseUrl, counterpartyId) {
|
|
5904
|
+
return `${apiBaseUrl}|${counterpartyId}`;
|
|
5905
|
+
}
|
|
5906
|
+
function degradeToObserve(config) {
|
|
5907
|
+
if (config.mode !== "enforce" && !config.pathRules.some((r) => r.mode === "enforce")) {
|
|
5908
|
+
return config;
|
|
5909
|
+
}
|
|
5910
|
+
return {
|
|
5911
|
+
...config,
|
|
5912
|
+
mode: "observe",
|
|
5913
|
+
pathRules: config.pathRules.map((r) => r.mode === "enforce" ? { ...r, mode: "observe" } : r)
|
|
5914
|
+
};
|
|
5915
|
+
}
|
|
5916
|
+
async function revalidate(config, counterpartyId) {
|
|
5917
|
+
const key = cacheKey(config.apiBaseUrl, counterpartyId);
|
|
5918
|
+
const existing = inflight2.get(key);
|
|
5919
|
+
if (existing) return existing;
|
|
5920
|
+
const promise = fetchEdgeConfig(config, counterpartyId, { etag: cache2.get(key)?.etag }).then((result) => {
|
|
5921
|
+
if (result === null) return;
|
|
5922
|
+
const now = Date.now();
|
|
5923
|
+
if ("notModified" in result) {
|
|
5924
|
+
const entry = cache2.get(key);
|
|
5925
|
+
if (entry) entry.lastSuccessAt = now;
|
|
5926
|
+
return;
|
|
5927
|
+
}
|
|
5928
|
+
cache2.set(key, { config: result.edgeConfig, etag: result.etag, lastSuccessAt: now });
|
|
5929
|
+
}).finally(() => {
|
|
5930
|
+
inflight2.delete(key);
|
|
5931
|
+
});
|
|
5932
|
+
inflight2.set(key, promise);
|
|
5933
|
+
return promise;
|
|
5934
|
+
}
|
|
5935
|
+
async function getEdgeConfig(config, counterpartyId, opts) {
|
|
5936
|
+
const ttlMs = opts?.ttlMs ?? DEFAULT_TTL_MS;
|
|
5937
|
+
const maxStaleMs = opts?.maxStaleMs ?? DEFAULT_MAX_STALE_MS;
|
|
5938
|
+
const key = cacheKey(config.apiBaseUrl, counterpartyId);
|
|
5939
|
+
const entry = cache2.get(key);
|
|
5940
|
+
if (entry) {
|
|
5941
|
+
const age = Date.now() - entry.lastSuccessAt;
|
|
5942
|
+
if (age > ttlMs) {
|
|
5943
|
+
revalidate(config, counterpartyId).catch(() => {
|
|
5944
|
+
});
|
|
5945
|
+
}
|
|
5946
|
+
return age > maxStaleMs ? degradeToObserve(entry.config) : entry.config;
|
|
5947
|
+
}
|
|
5948
|
+
await revalidate(config, counterpartyId).catch(() => {
|
|
5949
|
+
});
|
|
5950
|
+
return cache2.get(key)?.config ?? DEFAULT_EDGE_CONFIG;
|
|
5951
|
+
}
|
|
5952
|
+
function matchEdgePathRule(rules, path) {
|
|
5953
|
+
for (const rule of rules) {
|
|
5954
|
+
if (globToRegExp(rule.pattern).test(path)) return rule;
|
|
5955
|
+
}
|
|
5956
|
+
return void 0;
|
|
5957
|
+
}
|
|
5958
|
+
function globToRegExp(pattern) {
|
|
5959
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
5960
|
+
return new RegExp(`^${escaped}$`, "i");
|
|
5961
|
+
}
|
|
5962
|
+
function _resetEdgeConfigCache() {
|
|
5963
|
+
cache2.clear();
|
|
5964
|
+
inflight2.clear();
|
|
5965
|
+
}
|
|
5966
|
+
|
|
5967
|
+
// src/platform-signatures.ts
|
|
5968
|
+
var PLATFORM_AGENT_SIGNATURES = [
|
|
5969
|
+
{
|
|
5970
|
+
vendor: "claude",
|
|
5971
|
+
displayName: "Anthropic Claude",
|
|
5972
|
+
uaPatterns: [/claude/i, /anthropic/i],
|
|
5973
|
+
agentCardPatterns: [/anthropic\.com/i, /claude\.ai/i],
|
|
5974
|
+
apiKeyFormatPatterns: [/^sk-ant/i],
|
|
5975
|
+
headerPatterns: [/^anthropic-version/i, /^anthropic-beta/i, /^x-anthropic-/i]
|
|
5976
|
+
},
|
|
5977
|
+
{
|
|
5978
|
+
vendor: "chatgpt",
|
|
5979
|
+
displayName: "OpenAI ChatGPT",
|
|
5980
|
+
uaPatterns: [/chatgpt/i, /openai/i, /gpt-?\d/i],
|
|
5981
|
+
agentCardPatterns: [/openai\.com/i, /chatgpt\.com/i],
|
|
5982
|
+
apiKeyFormatPatterns: [/^sk-proj/i, /^sk-svcacct/i],
|
|
5983
|
+
headerPatterns: [/^openai-organization/i, /^openai-project/i, /^openai-version/i]
|
|
5984
|
+
},
|
|
5985
|
+
{
|
|
5986
|
+
vendor: "gemini",
|
|
5987
|
+
displayName: "Google Gemini",
|
|
5988
|
+
uaPatterns: [/gemini/i, /google-gemini/i, /bard/i],
|
|
5989
|
+
agentCardPatterns: [/gemini\.google\.com/i, /ai\.google\.dev/i],
|
|
5990
|
+
apiKeyFormatPatterns: [/^aiza/i],
|
|
5991
|
+
headerPatterns: [/^x-goog-user-project/i, /^x-goog-api-client/i]
|
|
5992
|
+
},
|
|
5993
|
+
{
|
|
5994
|
+
vendor: "cursor",
|
|
5995
|
+
displayName: "Cursor",
|
|
5996
|
+
uaPatterns: [/cursor/i],
|
|
5997
|
+
agentCardPatterns: [/cursor\.sh/i, /cursor\.com/i]
|
|
5998
|
+
},
|
|
5999
|
+
{
|
|
6000
|
+
vendor: "goose",
|
|
6001
|
+
displayName: "Block Goose",
|
|
6002
|
+
uaPatterns: [/goose/i, /block-goose/i],
|
|
6003
|
+
agentCardPatterns: [/block\.xyz\/goose/i, /goose\.tools/i]
|
|
6004
|
+
},
|
|
6005
|
+
{
|
|
6006
|
+
vendor: "perplexity",
|
|
6007
|
+
displayName: "Perplexity",
|
|
6008
|
+
uaPatterns: [/perplexity/i],
|
|
6009
|
+
agentCardPatterns: [/perplexity\.ai/i],
|
|
6010
|
+
apiKeyFormatPatterns: [/^pplx-/i]
|
|
6011
|
+
}
|
|
6012
|
+
];
|
|
6013
|
+
function matchPlatformSignature(signatures, input) {
|
|
6014
|
+
const ua = input.userAgent ?? "";
|
|
6015
|
+
const cardUrl = input.agentCardUrl ?? "";
|
|
6016
|
+
const apiKeyFormat = input.apiKeyFormat ?? "";
|
|
6017
|
+
const headerLines = [];
|
|
6018
|
+
if (input.platformHeaders) {
|
|
6019
|
+
for (const [name, value] of Object.entries(input.platformHeaders)) {
|
|
6020
|
+
headerLines.push(name, `${name}: ${value}`);
|
|
6021
|
+
}
|
|
6022
|
+
}
|
|
6023
|
+
for (const sig of signatures) {
|
|
6024
|
+
const uaMatch = sig.uaPatterns?.some((p) => p.test(ua));
|
|
6025
|
+
const cardMatch = sig.agentCardPatterns?.some((p) => p.test(cardUrl));
|
|
6026
|
+
const keyMatch = apiKeyFormat.length > 0 && sig.apiKeyFormatPatterns?.some((p) => p.test(apiKeyFormat));
|
|
6027
|
+
const headerMatch = headerLines.length > 0 && sig.headerPatterns?.some((p) => headerLines.some((line) => p.test(line)));
|
|
6028
|
+
if (uaMatch || cardMatch || keyMatch || headerMatch) {
|
|
6029
|
+
const uaBase = ua.split(/[\s/]/)[0]?.toLowerCase() ?? "";
|
|
6030
|
+
const cardHost = (() => {
|
|
6031
|
+
try {
|
|
6032
|
+
return cardUrl ? new URL(cardUrl).host : "";
|
|
6033
|
+
} catch {
|
|
6034
|
+
return "";
|
|
6035
|
+
}
|
|
6036
|
+
})();
|
|
6037
|
+
const keyBasis = uaBase || cardHost || apiKeyFormat || "unknown";
|
|
6038
|
+
return {
|
|
6039
|
+
vendor: sig.vendor,
|
|
6040
|
+
fingerprintKey: `${sig.vendor}:${keyBasis}`,
|
|
6041
|
+
displayName: sig.displayName
|
|
6042
|
+
};
|
|
6043
|
+
}
|
|
6044
|
+
}
|
|
6045
|
+
return void 0;
|
|
6046
|
+
}
|
|
6047
|
+
function detectPlatformFingerprint(input) {
|
|
6048
|
+
return matchPlatformSignature(PLATFORM_AGENT_SIGNATURES, input);
|
|
6049
|
+
}
|
|
5663
6050
|
export {
|
|
5664
6051
|
ACCESS_LEVEL_DESCRIPTIONS,
|
|
5665
6052
|
ACCESS_LEVEL_HIERARCHY,
|
|
@@ -5668,35 +6055,53 @@ export {
|
|
|
5668
6055
|
AstraSyncError,
|
|
5669
6056
|
AuthenticationError,
|
|
5670
6057
|
ChallengeHandler,
|
|
6058
|
+
DEFAULT_EDGE_CONFIG,
|
|
5671
6059
|
DEFAULT_TRUST_THRESHOLDS,
|
|
5672
6060
|
KYDRequiredError,
|
|
6061
|
+
MAX_HEADERS,
|
|
6062
|
+
MAX_HEADER_VALUE_BYTES,
|
|
6063
|
+
MAX_TOTAL_BYTES,
|
|
6064
|
+
PLATFORM_AGENT_SIGNATURES,
|
|
5673
6065
|
RegistrationDeniedError,
|
|
5674
6066
|
RegistrationExpiredError,
|
|
5675
6067
|
RegistrationTimeoutError,
|
|
5676
6068
|
TRUST_LEVEL_RANGES,
|
|
5677
|
-
VERSION,
|
|
6069
|
+
SDK_VERSION as VERSION,
|
|
6070
|
+
_resetEdgeConfigCache,
|
|
5678
6071
|
agent_exports as agent,
|
|
5679
6072
|
authorizeSettlement,
|
|
5680
6073
|
awaitStepUpApproval,
|
|
5681
6074
|
buildGuidance,
|
|
5682
6075
|
clearCache,
|
|
5683
6076
|
createMcpMiddleware,
|
|
6077
|
+
degradeToObserve,
|
|
6078
|
+
detectPlatformFingerprint,
|
|
5684
6079
|
determineAccessLevel,
|
|
5685
6080
|
express_exports as express,
|
|
6081
|
+
extractApiKeyFormat,
|
|
5686
6082
|
extractCredentials,
|
|
5687
6083
|
extractMcpCredentials,
|
|
6084
|
+
extractPlatformHeaders,
|
|
6085
|
+
fetchEdgeConfig,
|
|
6086
|
+
fetchRoutes,
|
|
5688
6087
|
getAccessLevelForScore,
|
|
5689
6088
|
getCachedWellKnownUrls,
|
|
5690
6089
|
getCapabilities,
|
|
6090
|
+
getEdgeConfig,
|
|
5691
6091
|
getTrustLevel,
|
|
5692
6092
|
getWellKnownUrls,
|
|
5693
6093
|
hasCredentials,
|
|
5694
6094
|
hasMinimumAccess,
|
|
6095
|
+
isEdgeConfig,
|
|
6096
|
+
matchEdgePathRule,
|
|
6097
|
+
matchPlatformSignature,
|
|
5695
6098
|
nextjs_exports as nextjs,
|
|
5696
6099
|
pollStepUpStatus,
|
|
5697
6100
|
prefetchWellKnown,
|
|
5698
6101
|
quickVerify,
|
|
5699
6102
|
recordDecision2 as recordDecision,
|
|
6103
|
+
reportUnregisteredAttempt,
|
|
6104
|
+
sanitizeHeaders,
|
|
5700
6105
|
sdk_exports as sdk,
|
|
5701
6106
|
setMcpMeta,
|
|
5702
6107
|
transport_exports as transport,
|