@astrasyncai/verification-gateway 2.4.8 → 2.4.10
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 +81 -31
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +81 -31
- 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 +64 -26
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +64 -26
- 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 +89 -32
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +89 -32
- 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 +65 -25
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +65 -25
- 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 +60 -25
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +60 -25
- 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 +60 -25
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +60 -25
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/{express-DvVjR2H4.d.mts → express-4WStX3PV.d.mts} +1 -1
- package/dist/{express-714gJbaW.d.ts → express-C1ePFB7n.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 +60 -25
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +60 -25
- 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-DYFS9QVb.d.mts → index-ChPX4WHl.d.mts} +1 -1
- package/dist/{index-DO0oG8ED.d.ts → index-Cjm-zBeZ.d.ts} +1 -1
- package/dist/{index-2WAlxs2G.d.ts → index-CzJMCgEy.d.ts} +1 -1
- package/dist/{index-P9t7M_dJ.d.mts → index-D8IEntil.d.mts} +1 -1
- package/dist/index.d.mts +22 -11
- package/dist/index.d.ts +22 -11
- package/dist/index.js +133 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +132 -42
- 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-CZ-MwSOT.d.ts → nextjs-BIORS__0.d.ts} +1 -1
- package/dist/{nextjs-BCoH7EqF.d.mts → nextjs-CjzHdaXA.d.mts} +1 -1
- package/dist/registration/index.d.mts +76 -1
- package/dist/registration/index.d.ts +76 -1
- package/dist/registration/index.js +27 -2
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +25 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/{sdk-wwhFDXWX.d.mts → sdk-Chhz-FcT.d.mts} +9 -4
- package/dist/{sdk-kiA49vqJ.d.ts → sdk-CqTEQAc6.d.ts} +9 -4
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/{types-DOAb89cm.d.mts → types-DNK2BgIf.d.mts} +1 -1
- package/dist/{types-aucqzfUa.d.ts → types-DoWIuzfj.d.ts} +1 -1
- package/dist/{types-BwDmjIdr.d.mts → types-L15pYd2c.d.mts} +21 -4
- package/dist/{types-BwDmjIdr.d.ts → types-L15pYd2c.d.ts} +21 -4
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/index.mjs +1 -1
- package/dist/ui/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -18,7 +18,7 @@ function hasMinimumAccess(actual, required) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// src/version.ts
|
|
21
|
-
var SDK_VERSION = "2.4.
|
|
21
|
+
var SDK_VERSION = "2.4.10";
|
|
22
22
|
|
|
23
23
|
// src/verify.ts
|
|
24
24
|
var DEFAULT_CONFIG = {
|
|
@@ -29,8 +29,10 @@ var DEFAULT_CONFIG = {
|
|
|
29
29
|
// through (`hasMinimumAccess('guidance', 'guidance') === true`).
|
|
30
30
|
defaultAccessLevel: "none",
|
|
31
31
|
// minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
|
|
32
|
-
|
|
33
|
-
//
|
|
32
|
+
// Round-18.5 F4: cacheTtl deliberately unset. When undefined, cacheResult
|
|
33
|
+
// applies the split default (60s autonomous / 300s step-up). When the
|
|
34
|
+
// caller sets cacheTtl explicitly, that value is honoured uniformly.
|
|
35
|
+
// Set cacheTtl: 0 to disable caching entirely.
|
|
34
36
|
debug: false
|
|
35
37
|
};
|
|
36
38
|
var initCheckPerformed = false;
|
|
@@ -57,11 +59,28 @@ async function performInitCheck(apiBaseUrl, debug) {
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
var verificationCache = /* @__PURE__ */ new Map();
|
|
60
|
-
function getCacheKey(
|
|
61
|
-
|
|
62
|
+
function getCacheKey(request) {
|
|
63
|
+
const c = request.credentials;
|
|
64
|
+
return [
|
|
65
|
+
c.astraId || "",
|
|
66
|
+
c.apiKey || "",
|
|
67
|
+
c.jwt || "",
|
|
68
|
+
request.purpose || "",
|
|
69
|
+
request.action || "",
|
|
70
|
+
request.resourceType || "",
|
|
71
|
+
request.resource || "",
|
|
72
|
+
request.jurisdiction || "",
|
|
73
|
+
request.transactionValue ?? "",
|
|
74
|
+
request.currency || "",
|
|
75
|
+
request.counterpartyUrl || "",
|
|
76
|
+
request.counterpartyType || "",
|
|
77
|
+
request.isSubAgentRequest ? "1" : "0",
|
|
78
|
+
request.parentAgentId || "",
|
|
79
|
+
request.subAgentDepth ?? ""
|
|
80
|
+
].join("|");
|
|
62
81
|
}
|
|
63
|
-
function getCachedResult(
|
|
64
|
-
const key = getCacheKey(
|
|
82
|
+
function getCachedResult(request) {
|
|
83
|
+
const key = getCacheKey(request);
|
|
65
84
|
const cached = verificationCache.get(key);
|
|
66
85
|
if (cached && cached.expiresAt > Date.now()) {
|
|
67
86
|
return cached.result;
|
|
@@ -71,8 +90,11 @@ function getCachedResult(credentials) {
|
|
|
71
90
|
}
|
|
72
91
|
return null;
|
|
73
92
|
}
|
|
74
|
-
|
|
75
|
-
|
|
93
|
+
var DEFAULT_AUTONOMOUS_TTL_SECONDS = 60;
|
|
94
|
+
var DEFAULT_STEP_UP_TTL_SECONDS = 300;
|
|
95
|
+
function cacheResult(request, result, configuredTtl) {
|
|
96
|
+
const ttlSeconds = configuredTtl && configuredTtl > 0 ? configuredTtl : result.requiresStepUp ? DEFAULT_STEP_UP_TTL_SECONDS : DEFAULT_AUTONOMOUS_TTL_SECONDS;
|
|
97
|
+
const key = getCacheKey(request);
|
|
76
98
|
verificationCache.set(key, {
|
|
77
99
|
result,
|
|
78
100
|
expiresAt: Date.now() + ttlSeconds * 1e3
|
|
@@ -129,12 +151,17 @@ function createGuidanceResponse(config, reason, options = {}) {
|
|
|
129
151
|
]
|
|
130
152
|
};
|
|
131
153
|
return {
|
|
132
|
-
|
|
154
|
+
// Round-18 G4: createGuidanceResponse fires for unverified-agent path or
|
|
155
|
+
// API-error fallback. Identity is not verified (no agent resolved);
|
|
156
|
+
// policy is not evaluated (we never reached the gate).
|
|
157
|
+
identityVerified: false,
|
|
158
|
+
policyAllowed: false,
|
|
133
159
|
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
134
|
-
// Adapters additionally short-circuit on
|
|
135
|
-
// the gate check, but the access level still has
|
|
136
|
-
// data layer so downstream consumers (SDK adapters
|
|
137
|
-
// custom integrations) inherit the correct
|
|
160
|
+
// Adapters additionally short-circuit on `!identityVerified ||
|
|
161
|
+
// !policyAllowed` before the gate check, but the access level still has
|
|
162
|
+
// to be honest at the data layer so downstream consumers (SDK adapters
|
|
163
|
+
// in other languages, custom integrations) inherit the correct
|
|
164
|
+
// semantics.
|
|
138
165
|
accessLevel: "none",
|
|
139
166
|
guidance,
|
|
140
167
|
denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
|
|
@@ -250,8 +277,8 @@ async function verify(config, request) {
|
|
|
250
277
|
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access-level decisions (the SDK reads access.accessLevel from the verify-access response). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
|
|
251
278
|
);
|
|
252
279
|
}
|
|
253
|
-
if (mergedConfig.cacheTtl
|
|
254
|
-
const cached = getCachedResult(request
|
|
280
|
+
if (mergedConfig.cacheTtl !== 0) {
|
|
281
|
+
const cached = getCachedResult(request);
|
|
255
282
|
if (cached) {
|
|
256
283
|
if (mergedConfig.debug) {
|
|
257
284
|
console.log("[VerificationGateway] Returning cached result");
|
|
@@ -278,15 +305,17 @@ async function verify(config, request) {
|
|
|
278
305
|
}
|
|
279
306
|
if (!apiResponse.access?.allowed) {
|
|
280
307
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
308
|
+
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
|
|
281
309
|
const result2 = {
|
|
282
|
-
|
|
310
|
+
identityVerified: idVerifiedFromBackend,
|
|
311
|
+
policyAllowed: false,
|
|
283
312
|
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
284
313
|
// Pre-rename this hardcoded `'guidance'`, which conflated with the
|
|
285
314
|
// colocated `guidance: {...}` help-payload object below and let
|
|
286
315
|
// denied requests pass any route gated at `'guidance'` because
|
|
287
316
|
// `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now
|
|
288
|
-
// ALSO short-circuit on
|
|
289
|
-
// belt-and-braces.
|
|
317
|
+
// ALSO short-circuit on `!identityVerified || !policyAllowed` before
|
|
318
|
+
// the gate check — belt-and-braces.
|
|
290
319
|
accessLevel: "none",
|
|
291
320
|
denialReasons: aggregatedFailures && aggregatedFailures.length > 0 ? aggregatedFailures.map((f) => f.message) : apiResponse.access?.reason ? [apiResponse.access.reason] : ["Access denied"],
|
|
292
321
|
failures: aggregatedFailures,
|
|
@@ -330,7 +359,13 @@ async function verify(config, request) {
|
|
|
330
359
|
const verificationContext = apiResponse.verificationContext;
|
|
331
360
|
const accessLevel = apiResponse.access?.accessLevel ?? "standard";
|
|
332
361
|
const result = {
|
|
333
|
-
|
|
362
|
+
// Round-18 G4: backend allowed access. Identity is verified (we resolved
|
|
363
|
+
// the caller to an agent) and policy passed all gates. Read idVerified
|
|
364
|
+
// from verificationContext for symmetry with the deny branch; default true
|
|
365
|
+
// on success path since `access.allowed === true` implies identity was
|
|
366
|
+
// resolvable (anonymous-allow paths flow through createGuidanceResponse).
|
|
367
|
+
identityVerified: apiResponse.verificationContext?.idVerified !== false,
|
|
368
|
+
policyAllowed: true,
|
|
334
369
|
accessLevel,
|
|
335
370
|
agent,
|
|
336
371
|
developer,
|
|
@@ -353,7 +388,7 @@ async function verify(config, request) {
|
|
|
353
388
|
warningHeader: apiResponse.warningHeader
|
|
354
389
|
};
|
|
355
390
|
if (result.recommendation === "deny") {
|
|
356
|
-
result.
|
|
391
|
+
result.policyAllowed = false;
|
|
357
392
|
result.accessLevel = "none";
|
|
358
393
|
result.denialReasons = result.recommendationReasons || [
|
|
359
394
|
"Access denied by AstraSync recommendation"
|
|
@@ -372,8 +407,8 @@ async function verify(config, request) {
|
|
|
372
407
|
}
|
|
373
408
|
result.denialReasons = result.recommendationReasons || ["Step-up verification required"];
|
|
374
409
|
}
|
|
375
|
-
if (mergedConfig.cacheTtl
|
|
376
|
-
cacheResult(request
|
|
410
|
+
if (mergedConfig.cacheTtl !== 0 && result.recommendation !== "deny") {
|
|
411
|
+
cacheResult(request, result, mergedConfig.cacheTtl);
|
|
377
412
|
}
|
|
378
413
|
return result;
|
|
379
414
|
}
|
|
@@ -470,8 +505,15 @@ function extractHttpCredentials(headers) {
|
|
|
470
505
|
// src/pdlss-pre-check.ts
|
|
471
506
|
function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
|
|
472
507
|
const failures = [];
|
|
473
|
-
if (
|
|
474
|
-
if (!routeConfig.allowedPurposes.
|
|
508
|
+
if (purpose) {
|
|
509
|
+
if (!routeConfig.allowedPurposes || routeConfig.allowedPurposes.length === 0) {
|
|
510
|
+
failures.push({
|
|
511
|
+
field: "purpose",
|
|
512
|
+
requested: purpose,
|
|
513
|
+
limit: [],
|
|
514
|
+
message: `Purpose "${purpose}" not allowed: route declares no allowedPurposes. The endpoint owner must enumerate allowedPurposes on the route config to authorise specific purposes.`
|
|
515
|
+
});
|
|
516
|
+
} else if (!routeConfig.allowedPurposes.includes(purpose)) {
|
|
475
517
|
failures.push({
|
|
476
518
|
field: "purpose",
|
|
477
519
|
requested: purpose,
|
|
@@ -501,9 +543,16 @@ function performCounterpartyPreCheck(routeConfig, astraCreds, purpose) {
|
|
|
501
543
|
});
|
|
502
544
|
}
|
|
503
545
|
}
|
|
504
|
-
if (
|
|
546
|
+
if (astraCreds?.pdlss?.scope?.jurisdiction) {
|
|
505
547
|
const requested = astraCreds.pdlss.scope.jurisdiction;
|
|
506
|
-
if (!routeConfig.allowedJurisdictions.
|
|
548
|
+
if (!routeConfig.allowedJurisdictions || routeConfig.allowedJurisdictions.length === 0) {
|
|
549
|
+
failures.push({
|
|
550
|
+
field: "jurisdiction",
|
|
551
|
+
requested,
|
|
552
|
+
limit: [],
|
|
553
|
+
message: `Jurisdiction "${requested}" not allowed: route declares no allowedJurisdictions. The endpoint owner must enumerate allowedJurisdictions on the route config to authorise specific jurisdictions.`
|
|
554
|
+
});
|
|
555
|
+
} else if (!routeConfig.allowedJurisdictions.includes(requested)) {
|
|
507
556
|
failures.push({
|
|
508
557
|
field: "jurisdiction",
|
|
509
558
|
requested,
|
|
@@ -566,12 +615,12 @@ function findRouteConfig(routes, path, method) {
|
|
|
566
615
|
});
|
|
567
616
|
}
|
|
568
617
|
function defaultOnDenied(result, _req, res) {
|
|
569
|
-
const statusCode = result.
|
|
618
|
+
const statusCode = !result.identityVerified ? 401 : 403;
|
|
570
619
|
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
571
620
|
res.status(statusCode).json({
|
|
572
621
|
success: false,
|
|
573
622
|
error: {
|
|
574
|
-
code: result.
|
|
623
|
+
code: !result.identityVerified ? "UNAUTHORIZED" : "INSUFFICIENT_ACCESS",
|
|
575
624
|
message: result.denialReasons?.[0] || "Access denied",
|
|
576
625
|
accessLevel: result.accessLevel,
|
|
577
626
|
guidance: result.guidance,
|
|
@@ -665,7 +714,8 @@ function createMiddleware(options) {
|
|
|
665
714
|
const preCheckFailures = performCounterpartyPreCheck(routeConfig, astraCreds, purpose);
|
|
666
715
|
if (preCheckFailures.length > 0) {
|
|
667
716
|
const result2 = {
|
|
668
|
-
|
|
717
|
+
identityVerified: false,
|
|
718
|
+
policyAllowed: false,
|
|
669
719
|
accessLevel: "none",
|
|
670
720
|
denialReasons: preCheckFailures.map((f) => f.message),
|
|
671
721
|
guidance: {
|
|
@@ -714,7 +764,7 @@ function createMiddleware(options) {
|
|
|
714
764
|
});
|
|
715
765
|
req.agentVerification = result;
|
|
716
766
|
const sessionId = result.sessionId;
|
|
717
|
-
if (!result.
|
|
767
|
+
if (!result.identityVerified || !result.policyAllowed) {
|
|
718
768
|
if (shouldRecordDecisions && sessionId) {
|
|
719
769
|
recordDecision(config, sessionId, "denied", result.denialReasons?.[0]).catch(() => {
|
|
720
770
|
});
|