@astrasyncai/verification-gateway 2.4.12 → 2.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/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +224 -42
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +224 -42
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +101 -57
- package/dist/adapters/mcp.d.ts +101 -57
- package/dist/adapters/mcp.js +215 -44
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +215 -44
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +87 -34
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +87 -34
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +2 -2
- package/dist/adapters/sdk.d.ts +2 -2
- package/dist/adapters/sdk.js +61 -28
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +61 -28
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +29 -0
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +29 -0
- package/dist/agent/index.mjs.map +1 -1
- package/dist/browser/background.js +102 -30
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +102 -30
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +2 -2
- package/dist/browser/browser-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cursor/cursor-adapter.d.mts +2 -2
- package/dist/cursor/cursor-adapter.d.ts +2 -2
- package/dist/cursor/extension.d.mts +2 -2
- package/dist/cursor/extension.d.ts +2 -2
- package/dist/cursor/extension.js +102 -30
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +102 -30
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/{express-C1ePFB7n.d.ts → express-CrfwoNAR.d.ts} +1 -1
- package/dist/{express-4WStX3PV.d.mts → express-ienhAXps.d.mts} +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +102 -30
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +102 -30
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +2 -2
- package/dist/git-trigger/git-hooks.d.ts +2 -2
- package/dist/{index-ChPX4WHl.d.mts → index-B5e2IDWU.d.mts} +1 -1
- package/dist/{index-CzJMCgEy.d.ts → index-CCdZxvAr.d.ts} +71 -6
- package/dist/{index-D8IEntil.d.mts → index-CEg_WG6y.d.mts} +71 -6
- package/dist/{index-Cjm-zBeZ.d.ts → index-DC5f8eoQ.d.ts} +1 -1
- package/dist/index.d.mts +39 -9
- package/dist/index.d.ts +39 -9
- package/dist/index.js +500 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +497 -94
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +2 -2
- package/dist/local-evaluator/evaluator.d.ts +2 -2
- package/dist/local-evaluator/evaluator.js +12 -2
- package/dist/local-evaluator/evaluator.js.map +1 -1
- package/dist/local-evaluator/evaluator.mjs +12 -2
- package/dist/local-evaluator/evaluator.mjs.map +1 -1
- package/dist/{nextjs-BIORS__0.d.ts → nextjs-66R1KW8e.d.ts} +1 -1
- package/dist/{nextjs-CjzHdaXA.d.mts → nextjs-DSpisQst.d.mts} +1 -1
- package/dist/{sdk-Chhz-FcT.d.mts → sdk-5U_CBRpr.d.mts} +1 -1
- package/dist/{sdk-CqTEQAc6.d.ts → sdk-Bm8np66n.d.ts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/transport/index.js +146 -28
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +146 -28
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-L15pYd2c.d.mts → types-B3USs-Kx.d.mts} +42 -1
- package/dist/{types-L15pYd2c.d.ts → types-B3USs-Kx.d.ts} +42 -1
- package/dist/{types-DNK2BgIf.d.mts → types-CgDCUfo8.d.mts} +1 -1
- package/dist/{types-DoWIuzfj.d.ts → types-R5N4ET6x.d.ts} +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/gateway/gateway.mjs
CHANGED
|
@@ -80,7 +80,10 @@ var LocalEvaluator = class {
|
|
|
80
80
|
}
|
|
81
81
|
const depth = context.metadata?.subAgentDepth || 0;
|
|
82
82
|
if (this.policy.selfInstantiation.maxDepth !== void 0 && depth >= this.policy.selfInstantiation.maxDepth) {
|
|
83
|
-
return {
|
|
83
|
+
return {
|
|
84
|
+
recommendation: "DENY",
|
|
85
|
+
reason: `Sub-agent depth ${depth} exceeds max depth ${this.policy.selfInstantiation.maxDepth}`
|
|
86
|
+
};
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
if (purposeRule.requiresApproval) {
|
|
@@ -161,7 +164,10 @@ var LocalEvaluator = class {
|
|
|
161
164
|
return { recommendation: "DENY", reason: `Risk score ${riskScore} exceeds block threshold` };
|
|
162
165
|
}
|
|
163
166
|
if (riskScore >= thresholds.requireApproval.min) {
|
|
164
|
-
return {
|
|
167
|
+
return {
|
|
168
|
+
recommendation: "MANUAL_REVIEW",
|
|
169
|
+
reason: `Risk score ${riskScore} requires approval`
|
|
170
|
+
};
|
|
165
171
|
}
|
|
166
172
|
return null;
|
|
167
173
|
}
|
|
@@ -226,6 +232,10 @@ var LocalEvaluator = class {
|
|
|
226
232
|
*/
|
|
227
233
|
matchGlob(value, pattern) {
|
|
228
234
|
if (pattern === value) return true;
|
|
235
|
+
const starCount = (pattern.match(/\*/g) ?? []).length;
|
|
236
|
+
if (starCount > 8) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
229
239
|
const regexStr = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
230
240
|
try {
|
|
231
241
|
return new RegExp(`^${regexStr}$`, "i").test(value);
|
|
@@ -3029,7 +3039,14 @@ function getTrustLevel(score) {
|
|
|
3029
3039
|
}
|
|
3030
3040
|
|
|
3031
3041
|
// src/version.ts
|
|
3032
|
-
var SDK_VERSION = "2.4.
|
|
3042
|
+
var SDK_VERSION = "2.4.13";
|
|
3043
|
+
|
|
3044
|
+
// src/well-known.ts
|
|
3045
|
+
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
3046
|
+
var cache = /* @__PURE__ */ new Map();
|
|
3047
|
+
function getCachedWellKnownUrls(apiBaseUrl) {
|
|
3048
|
+
return cache.get(apiBaseUrl)?.data;
|
|
3049
|
+
}
|
|
3033
3050
|
|
|
3034
3051
|
// src/verify.ts
|
|
3035
3052
|
var DEFAULT_CONFIG = {
|
|
@@ -3048,22 +3065,27 @@ var DEFAULT_CONFIG = {
|
|
|
3048
3065
|
};
|
|
3049
3066
|
var initCheckPerformed = false;
|
|
3050
3067
|
var deprecationWarningShown = false;
|
|
3051
|
-
async function performInitCheck(apiBaseUrl, debug) {
|
|
3068
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
3052
3069
|
initCheckPerformed = true;
|
|
3053
3070
|
try {
|
|
3054
3071
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
3055
3072
|
const response = await fetch(probeUrl, { method: "HEAD" });
|
|
3056
3073
|
const contentType = response.headers.get("content-type") ?? "";
|
|
3057
3074
|
if (contentType.startsWith("text/html")) {
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3075
|
+
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).`;
|
|
3076
|
+
if (strictInit) {
|
|
3077
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
3078
|
+
}
|
|
3079
|
+
console.warn(`${message} Set disableInitChecks: true on GatewayConfig to silence.`);
|
|
3061
3080
|
} else if (debug) {
|
|
3062
3081
|
console.log(
|
|
3063
3082
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
3064
3083
|
);
|
|
3065
3084
|
}
|
|
3066
3085
|
} catch (err) {
|
|
3086
|
+
if (strictInit) {
|
|
3087
|
+
throw err;
|
|
3088
|
+
}
|
|
3067
3089
|
if (debug) {
|
|
3068
3090
|
console.log(`[VerificationGateway] init check failed (non-blocking): ${String(err)}`);
|
|
3069
3091
|
}
|
|
@@ -3087,7 +3109,23 @@ function getCacheKey(request) {
|
|
|
3087
3109
|
request.counterpartyType || "",
|
|
3088
3110
|
request.isSubAgentRequest ? "1" : "0",
|
|
3089
3111
|
request.parentAgentId || "",
|
|
3090
|
-
request.subAgentDepth ?? ""
|
|
3112
|
+
request.subAgentDepth ?? "",
|
|
3113
|
+
// Audit F-A1-07: previously-missing dimensions that DO affect the
|
|
3114
|
+
// backend verdict. Without these, two requests with different
|
|
3115
|
+
// durations (e.g. 60s vs 86400s) collided on the same cache key and
|
|
3116
|
+
// the shorter-duration allow served the longer-duration request.
|
|
3117
|
+
request.durationRequired ?? "",
|
|
3118
|
+
request.invocationProtocol || "",
|
|
3119
|
+
request.enableRuntimeChallenge ? "1" : "0",
|
|
3120
|
+
// callerMetadata fields contribute to risk model; include the ones
|
|
3121
|
+
// backend reads. sourceIp/userAgent/forwardedFor change per-request
|
|
3122
|
+
// so their inclusion effectively forces a re-check for any varying
|
|
3123
|
+
// client (the right behavior — IP-driven anomaly scoring shouldn't
|
|
3124
|
+
// be cached across IPs).
|
|
3125
|
+
request.callerMetadata?.sourceIp || "",
|
|
3126
|
+
request.callerMetadata?.userAgent || "",
|
|
3127
|
+
request.callerMetadata?.forwardedFor || "",
|
|
3128
|
+
request.callerMetadata?.agentCardUrl || ""
|
|
3091
3129
|
].join("|");
|
|
3092
3130
|
}
|
|
3093
3131
|
function getCachedResult(request) {
|
|
@@ -3111,21 +3149,22 @@ function cacheResult(request, result, configuredTtl) {
|
|
|
3111
3149
|
expiresAt: Date.now() + ttlSeconds * 1e3
|
|
3112
3150
|
});
|
|
3113
3151
|
}
|
|
3114
|
-
function createGuidanceResponse(
|
|
3152
|
+
function createGuidanceResponse(_config, reason, options = {}) {
|
|
3115
3153
|
const source = options.source ?? "no_credentials";
|
|
3116
3154
|
const isApiError = source === "api_error";
|
|
3155
|
+
const urls = options.urls;
|
|
3117
3156
|
const guidance = isApiError ? {
|
|
3118
3157
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
3119
|
-
registrationUrl:
|
|
3120
|
-
documentationUrl:
|
|
3158
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
3159
|
+
documentationUrl: urls?.documentationUrl ?? "",
|
|
3121
3160
|
steps: [
|
|
3122
3161
|
"Retry the request with exponential backoff",
|
|
3123
3162
|
"If failures persist, share the correlationId with support"
|
|
3124
3163
|
]
|
|
3125
3164
|
} : {
|
|
3126
3165
|
message: "This service verifies AI agents before granting access. Please register your agent with AstraSync.",
|
|
3127
|
-
registrationUrl:
|
|
3128
|
-
documentationUrl:
|
|
3166
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
3167
|
+
documentationUrl: urls?.documentationUrl ?? "",
|
|
3129
3168
|
steps: [
|
|
3130
3169
|
"Register for an AstraSync account",
|
|
3131
3170
|
"Create and register your agent",
|
|
@@ -3167,7 +3206,7 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
3167
3206
|
const { credentials, ...requestData } = request;
|
|
3168
3207
|
const body = {
|
|
3169
3208
|
...credentials.astraId && { agentId: credentials.astraId },
|
|
3170
|
-
purpose: requestData.purpose
|
|
3209
|
+
...requestData.purpose && { purpose: requestData.purpose }
|
|
3171
3210
|
};
|
|
3172
3211
|
if (requestData.action) body.action = requestData.action;
|
|
3173
3212
|
if (requestData.resourceType) body.resourceType = requestData.resourceType;
|
|
@@ -3201,12 +3240,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
3201
3240
|
"Content-Type": "application/json",
|
|
3202
3241
|
...config.customHeaders
|
|
3203
3242
|
};
|
|
3204
|
-
if (credentials.authorizationHeader) {
|
|
3205
|
-
headers["Authorization"] = credentials.authorizationHeader;
|
|
3206
|
-
} else if (config.apiKey) {
|
|
3207
|
-
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
3208
|
-
}
|
|
3209
3243
|
if (config.apiKey) {
|
|
3244
|
+
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
3210
3245
|
headers["X-API-Key"] = config.apiKey;
|
|
3211
3246
|
}
|
|
3212
3247
|
try {
|
|
@@ -3251,8 +3286,13 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
3251
3286
|
}
|
|
3252
3287
|
async function verify(config, request) {
|
|
3253
3288
|
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
3289
|
+
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
3254
3290
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
3255
|
-
|
|
3291
|
+
if (mergedConfig.strictInit) {
|
|
3292
|
+
await performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, true);
|
|
3293
|
+
} else {
|
|
3294
|
+
void performInitCheck(mergedConfig.apiBaseUrl, mergedConfig.debug, false);
|
|
3295
|
+
}
|
|
3256
3296
|
}
|
|
3257
3297
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
3258
3298
|
deprecationWarningShown = true;
|
|
@@ -3283,7 +3323,8 @@ async function verify(config, request) {
|
|
|
3283
3323
|
if (!apiResponse.success) {
|
|
3284
3324
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
3285
3325
|
source: "api_error",
|
|
3286
|
-
correlationId: apiResponse.correlationId
|
|
3326
|
+
correlationId: apiResponse.correlationId,
|
|
3327
|
+
urls
|
|
3287
3328
|
});
|
|
3288
3329
|
}
|
|
3289
3330
|
if (!apiResponse.access?.allowed) {
|
|
@@ -3306,8 +3347,8 @@ async function verify(config, request) {
|
|
|
3306
3347
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
3307
3348
|
guidance: {
|
|
3308
3349
|
message: apiResponse.access?.reason || "Access denied by PDLSS policy",
|
|
3309
|
-
registrationUrl:
|
|
3310
|
-
documentationUrl:
|
|
3350
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
3351
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
3311
3352
|
},
|
|
3312
3353
|
verifiedAt: /* @__PURE__ */ new Date(),
|
|
3313
3354
|
// Extract sessionId so decisions can be recorded for denials too
|
|
@@ -3376,13 +3417,15 @@ async function verify(config, request) {
|
|
|
3376
3417
|
result.denialReasons = result.recommendationReasons || [
|
|
3377
3418
|
"Access denied by AstraSync recommendation"
|
|
3378
3419
|
];
|
|
3379
|
-
|
|
3380
|
-
result.
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3420
|
+
result.guidance = result.runtimeChallenge ? {
|
|
3421
|
+
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
3422
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
3423
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
3424
|
+
} : {
|
|
3425
|
+
message: result.recommendationReasons?.[0] || "Access denied by AstraSync recommendation",
|
|
3426
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
3427
|
+
documentationUrl: urls?.documentationUrl ?? ""
|
|
3428
|
+
};
|
|
3386
3429
|
} else if (result.recommendation === "step_up_required") {
|
|
3387
3430
|
result.requiresStepUp = true;
|
|
3388
3431
|
if (ACCESS_LEVEL_HIERARCHY[result.accessLevel] > ACCESS_LEVEL_HIERARCHY["read-only"]) {
|
|
@@ -3408,6 +3451,35 @@ import { parseDictionary } from "structured-headers";
|
|
|
3408
3451
|
// src/transport/rfc9421-verify.ts
|
|
3409
3452
|
import { httpbis } from "http-message-signatures";
|
|
3410
3453
|
|
|
3454
|
+
// src/transport/nonce-store.ts
|
|
3455
|
+
var InMemoryNonceStore = class {
|
|
3456
|
+
constructor(capacity = 1e4) {
|
|
3457
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
3458
|
+
this.lastSweepMs = 0;
|
|
3459
|
+
this.capacity = capacity;
|
|
3460
|
+
}
|
|
3461
|
+
seen(key, expiresAtMs) {
|
|
3462
|
+
const nowMs = Date.now();
|
|
3463
|
+
if (nowMs - this.lastSweepMs > 1e3) {
|
|
3464
|
+
for (const [k, exp] of this.entries) {
|
|
3465
|
+
if (exp <= nowMs) this.entries.delete(k);
|
|
3466
|
+
}
|
|
3467
|
+
this.lastSweepMs = nowMs;
|
|
3468
|
+
}
|
|
3469
|
+
const existing = this.entries.get(key);
|
|
3470
|
+
if (existing !== void 0 && existing > nowMs) {
|
|
3471
|
+
return true;
|
|
3472
|
+
}
|
|
3473
|
+
if (this.entries.size >= this.capacity) {
|
|
3474
|
+
const oldest = this.entries.keys().next().value;
|
|
3475
|
+
if (oldest !== void 0) this.entries.delete(oldest);
|
|
3476
|
+
}
|
|
3477
|
+
this.entries.set(key, expiresAtMs);
|
|
3478
|
+
return false;
|
|
3479
|
+
}
|
|
3480
|
+
};
|
|
3481
|
+
var defaultNonceStore = new InMemoryNonceStore();
|
|
3482
|
+
|
|
3411
3483
|
// src/transport/vi.ts
|
|
3412
3484
|
import { splitSdJwt, decodeSdJwtSync } from "@sd-jwt/decode";
|
|
3413
3485
|
import { createHash } from "crypto";
|