@astrasyncai/verification-gateway 2.3.7 → 2.3.9
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/README.md +93 -10
- 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 +81 -7
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +81 -7
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +1 -1
- package/dist/adapters/mcp.d.ts +1 -1
- package/dist/adapters/mcp.js +84 -12
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +84 -12
- 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 +40 -6
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +40 -6
- 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 +40 -6
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +40 -6
- 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/browser/background.js +39 -5
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +39 -5
- 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 +39 -5
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +39 -5
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/{express-D9oRsseg.d.mts → express-BiB51d5t.d.mts} +1 -1
- package/dist/{express-DMSIl20m.d.ts → express-D6tEDU08.d.ts} +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +39 -5
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +39 -5
- 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-EwUWXC5T.d.ts → index-8DFMpITk.d.ts} +1 -1
- package/dist/{index-YNPs800Z.d.mts → index-B--6fiDp.d.mts} +1 -1
- package/dist/{index-Bn_7eGjb.d.mts → index-CAykfMWK.d.mts} +1 -1
- package/dist/{index-BtU9yFda.d.ts → index-Yt02MRyu.d.ts} +1 -1
- package/dist/index.d.mts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +87 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -13
- 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/{nextjs-B5ZBpHra.d.ts → nextjs-CK5F_tVZ.d.ts} +1 -1
- package/dist/{nextjs-BLtjRbc-.d.mts → nextjs-CpxqfQqD.d.mts} +1 -1
- package/dist/{sdk-BhkxvqnK.d.mts → sdk-BMvauMgP.d.ts} +9 -2
- package/dist/{sdk-YmE3RG8n.d.ts → sdk-yJjO7yzn.d.mts} +9 -2
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/{types-DxY5zt4z.d.mts → types-CKafuHDn.d.mts} +1 -1
- package/dist/{types-Bxqj1sKY.d.mts → types-UYT4GdPW.d.mts} +42 -4
- package/dist/{types-Bxqj1sKY.d.ts → types-UYT4GdPW.d.ts} +42 -4
- package/dist/{types-BecRpozv.d.ts → types-ppkhdldJ.d.ts} +1 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +3 -3
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/index.mjs +3 -3
- package/dist/ui/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@ var __export = (target, all) => {
|
|
|
7
7
|
// src/access-levels.ts
|
|
8
8
|
var ACCESS_LEVEL_HIERARCHY = {
|
|
9
9
|
none: 0,
|
|
10
|
-
|
|
10
|
+
restricted: 1,
|
|
11
11
|
"read-only": 2,
|
|
12
12
|
standard: 3,
|
|
13
13
|
full: 4,
|
|
@@ -15,7 +15,7 @@ var ACCESS_LEVEL_HIERARCHY = {
|
|
|
15
15
|
};
|
|
16
16
|
var ACCESS_LEVEL_DESCRIPTIONS = {
|
|
17
17
|
none: "No access - credentials required",
|
|
18
|
-
|
|
18
|
+
restricted: "Restricted access - registration prompt only",
|
|
19
19
|
"read-only": "Read-only access - can browse but not modify",
|
|
20
20
|
standard: "Standard access - normal operations per PDLSS policy",
|
|
21
21
|
full: "Full access - all operations for high-trust agents",
|
|
@@ -23,7 +23,7 @@ var ACCESS_LEVEL_DESCRIPTIONS = {
|
|
|
23
23
|
};
|
|
24
24
|
var DEFAULT_TRUST_THRESHOLDS = {
|
|
25
25
|
none: 0,
|
|
26
|
-
|
|
26
|
+
restricted: 0,
|
|
27
27
|
"read-only": 20,
|
|
28
28
|
standard: 40,
|
|
29
29
|
full: 70,
|
|
@@ -49,11 +49,11 @@ function getAccessLevelForScore(trustScore, thresholds = DEFAULT_TRUST_THRESHOLD
|
|
|
49
49
|
if (trustScore >= thresholds.full) return "full";
|
|
50
50
|
if (trustScore >= thresholds.standard) return "standard";
|
|
51
51
|
if (trustScore >= thresholds["read-only"]) return "read-only";
|
|
52
|
-
return "
|
|
52
|
+
return "restricted";
|
|
53
53
|
}
|
|
54
54
|
function determineAccessLevel(verified, trustScore, isOrgMember, customThresholds) {
|
|
55
55
|
if (!verified) {
|
|
56
|
-
return "
|
|
56
|
+
return "none";
|
|
57
57
|
}
|
|
58
58
|
if (isOrgMember) {
|
|
59
59
|
return "internal";
|
|
@@ -74,7 +74,7 @@ function getCapabilities(accessLevel) {
|
|
|
74
74
|
canAdmin: false,
|
|
75
75
|
canAccessInternal: false
|
|
76
76
|
};
|
|
77
|
-
case "
|
|
77
|
+
case "restricted":
|
|
78
78
|
return {
|
|
79
79
|
canRead: false,
|
|
80
80
|
canWrite: false,
|
|
@@ -128,7 +128,11 @@ function getCapabilities(accessLevel) {
|
|
|
128
128
|
// src/verify.ts
|
|
129
129
|
var DEFAULT_CONFIG = {
|
|
130
130
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
131
|
-
|
|
131
|
+
// v2.3.9 (defect #30): default for unconfigured callers is `'none'` (no
|
|
132
|
+
// access). Pre-rename this defaulted to `'guidance'`, which combined with
|
|
133
|
+
// a route gated at `'guidance'` to silently let unverified traffic
|
|
134
|
+
// through (`hasMinimumAccess('guidance', 'guidance') === true`).
|
|
135
|
+
defaultAccessLevel: "none",
|
|
132
136
|
// minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
|
|
133
137
|
cacheTtl: 300,
|
|
134
138
|
// 5 minutes
|
|
@@ -227,7 +231,12 @@ function createGuidanceResponse(config, reason) {
|
|
|
227
231
|
};
|
|
228
232
|
return {
|
|
229
233
|
verified: false,
|
|
230
|
-
|
|
234
|
+
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
235
|
+
// Adapters additionally short-circuit on `verified === false` before
|
|
236
|
+
// the gate check, but the access level still has to be honest at the
|
|
237
|
+
// data layer so downstream consumers (SDK adapters in other languages,
|
|
238
|
+
// custom integrations) inherit the correct semantics.
|
|
239
|
+
accessLevel: "none",
|
|
231
240
|
guidance,
|
|
232
241
|
denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
|
|
233
242
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -284,6 +293,23 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
284
293
|
body: JSON.stringify(body)
|
|
285
294
|
});
|
|
286
295
|
const data = await response.json();
|
|
296
|
+
if (response.status === 410) {
|
|
297
|
+
return {
|
|
298
|
+
success: true,
|
|
299
|
+
access: {
|
|
300
|
+
allowed: false,
|
|
301
|
+
accessLevel: "none",
|
|
302
|
+
reason: "endpoint_deactivated",
|
|
303
|
+
failures: [
|
|
304
|
+
{
|
|
305
|
+
dimension: "endpoint.deactivated",
|
|
306
|
+
message: typeof data?.message === "string" ? data.message : "Endpoint has been deactivated",
|
|
307
|
+
guidance: typeof data?.guidance === "string" ? data.guidance : "Reactivate via POST /api/endpoints/{id}/reactivate, or update the URL on the calling agent."
|
|
308
|
+
}
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
287
313
|
if (!response.ok) {
|
|
288
314
|
return {
|
|
289
315
|
success: false,
|
|
@@ -337,7 +363,14 @@ async function verify(config, request) {
|
|
|
337
363
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
338
364
|
const result2 = {
|
|
339
365
|
verified: false,
|
|
340
|
-
|
|
366
|
+
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
367
|
+
// Pre-rename this hardcoded `'guidance'`, which conflated with the
|
|
368
|
+
// colocated `guidance: {...}` help-payload object below and let
|
|
369
|
+
// denied requests pass any route gated at `'guidance'` because
|
|
370
|
+
// `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now
|
|
371
|
+
// ALSO short-circuit on `verified === false` before the gate check —
|
|
372
|
+
// belt-and-braces.
|
|
373
|
+
accessLevel: "none",
|
|
341
374
|
denialReasons: aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"],
|
|
342
375
|
failures: aggregatedFailures,
|
|
343
376
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
@@ -393,7 +426,8 @@ async function verify(config, request) {
|
|
|
393
426
|
runtimeChallenge: apiResponse.runtimeChallenge,
|
|
394
427
|
tokenGuidance: apiResponse.tokenGuidance,
|
|
395
428
|
recommendation: apiResponse.recommendation,
|
|
396
|
-
recommendationReasons: apiResponse.recommendationReasons
|
|
429
|
+
recommendationReasons: apiResponse.recommendationReasons,
|
|
430
|
+
warningHeader: apiResponse.warningHeader
|
|
397
431
|
};
|
|
398
432
|
if (result.recommendation === "deny") {
|
|
399
433
|
result.verified = false;
|
|
@@ -420,7 +454,7 @@ async function verify(config, request) {
|
|
|
420
454
|
}
|
|
421
455
|
return result;
|
|
422
456
|
}
|
|
423
|
-
async function recordDecision(config, sessionId, decision, reason) {
|
|
457
|
+
async function recordDecision(config, sessionId, decision, reason, override) {
|
|
424
458
|
const headers = { "Content-Type": "application/json" };
|
|
425
459
|
if (config.apiKey) {
|
|
426
460
|
headers["Authorization"] = `Bearer ${config.apiKey}`;
|
|
@@ -429,7 +463,16 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
429
463
|
await fetch(`${config.apiBaseUrl}/agents/verify-access/${sessionId}/decision`, {
|
|
430
464
|
method: "POST",
|
|
431
465
|
headers,
|
|
432
|
-
body: JSON.stringify({
|
|
466
|
+
body: JSON.stringify({
|
|
467
|
+
decision,
|
|
468
|
+
reason,
|
|
469
|
+
...override && {
|
|
470
|
+
overriddenBy: override.overriddenBy,
|
|
471
|
+
toolName: override.toolName,
|
|
472
|
+
requestedLevel: override.requestedLevel,
|
|
473
|
+
grantedLevel: override.grantedLevel
|
|
474
|
+
}
|
|
475
|
+
})
|
|
433
476
|
}).catch(() => {
|
|
434
477
|
});
|
|
435
478
|
}
|
|
@@ -666,6 +709,7 @@ function createMiddleware(options) {
|
|
|
666
709
|
let lastFetchAt = 0;
|
|
667
710
|
let refreshing = null;
|
|
668
711
|
let warnedNoCounterparty = false;
|
|
712
|
+
let warnedEmptyRoutes = false;
|
|
669
713
|
async function refreshRoutes() {
|
|
670
714
|
if (!config.counterpartyId) {
|
|
671
715
|
if (!warnedNoCounterparty) {
|
|
@@ -680,6 +724,13 @@ function createMiddleware(options) {
|
|
|
680
724
|
if (fetched) {
|
|
681
725
|
cachedRoutes = fetched;
|
|
682
726
|
lastFetchAt = Date.now();
|
|
727
|
+
if (cachedRoutes.length === 0 && !warnedEmptyRoutes) {
|
|
728
|
+
const dashboard = config.dashboardUrl ?? "https://app.astrasync.ai";
|
|
729
|
+
console.warn(
|
|
730
|
+
`[VerificationGateway] No route policy configured for ${config.counterpartyId}. Gateway is in pass-through mode for ALL traffic until you add at least one route. Configure at ${dashboard}/dashboard/endpoints/${config.counterpartyId}/routes`
|
|
731
|
+
);
|
|
732
|
+
warnedEmptyRoutes = true;
|
|
733
|
+
}
|
|
683
734
|
}
|
|
684
735
|
}
|
|
685
736
|
refreshing = refreshRoutes().finally(() => {
|
|
@@ -702,9 +753,20 @@ function createMiddleware(options) {
|
|
|
702
753
|
}
|
|
703
754
|
const routeConfig = findRouteConfig(cachedRoutes, req.path, req.method);
|
|
704
755
|
if (!routeConfig) {
|
|
756
|
+
if (config.setPassThroughHeader) {
|
|
757
|
+
res.setHeader("X-Astra-Gateway-Mode", "pass-through");
|
|
758
|
+
res.setHeader(
|
|
759
|
+
"X-Astra-Gateway-Reason",
|
|
760
|
+
cachedRoutes.length === 0 ? "no-policy" : "no-match"
|
|
761
|
+
);
|
|
762
|
+
}
|
|
705
763
|
return next();
|
|
706
764
|
}
|
|
707
765
|
if (routeConfig.minAccessLevel === "none") {
|
|
766
|
+
if (config.setPassThroughHeader) {
|
|
767
|
+
res.setHeader("X-Astra-Gateway-Mode", "pass-through");
|
|
768
|
+
res.setHeader("X-Astra-Gateway-Reason", "route-none");
|
|
769
|
+
}
|
|
708
770
|
return next();
|
|
709
771
|
}
|
|
710
772
|
const credentials = customExtractCredentials ? customExtractCredentials(req) : defaultExtractCredentials(req);
|
|
@@ -763,6 +825,14 @@ function createMiddleware(options) {
|
|
|
763
825
|
});
|
|
764
826
|
req.agentVerification = result;
|
|
765
827
|
const sessionId = result.sessionId;
|
|
828
|
+
if (!result.verified) {
|
|
829
|
+
if (shouldRecordDecisions && sessionId) {
|
|
830
|
+
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
onDenied(result, req, res);
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
766
836
|
if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
|
|
767
837
|
if (shouldRecordDecisions && sessionId) {
|
|
768
838
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
@@ -788,6 +858,10 @@ function createMiddleware(options) {
|
|
|
788
858
|
recordDecision(config, sessionId, "granted").catch(() => {
|
|
789
859
|
});
|
|
790
860
|
}
|
|
861
|
+
const enhancedResult = result;
|
|
862
|
+
if (enhancedResult.warningHeader) {
|
|
863
|
+
res.setHeader(enhancedResult.warningHeader.name, enhancedResult.warningHeader.value);
|
|
864
|
+
}
|
|
791
865
|
next();
|
|
792
866
|
} catch (error) {
|
|
793
867
|
console.error("[VerificationGateway] Middleware error:", error);
|
|
@@ -1143,7 +1217,7 @@ function createMiddleware2(options) {
|
|
|
1143
1217
|
agentCardUrl: request.headers.get("x-astrasync-agent-card") || void 0
|
|
1144
1218
|
}
|
|
1145
1219
|
});
|
|
1146
|
-
if (!hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
|
|
1220
|
+
if (!result.verified || !hasMinimumAccess(result.accessLevel, routeConfig.minAccessLevel)) {
|
|
1147
1221
|
if (pathname.startsWith("/api/")) {
|
|
1148
1222
|
return NextResponse.json(
|
|
1149
1223
|
{
|