@astrasyncai/verification-gateway 3.11.1 → 4.0.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 +106 -10
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +106 -10
- 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 +111 -10
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +111 -10
- 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 +107 -10
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +107 -10
- 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 +92 -10
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +92 -10
- 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/bin/astrasync-claude-hook.js +92 -10
- package/dist/bin/astrasync-codex-hook.js +92 -10
- package/dist/bin/astrasync-guard.js +92 -10
- package/dist/bin/astrasync.js +93 -10
- package/dist/browser/background.js +92 -10
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +92 -10
- 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/claude-code/claude-code-adapter.d.mts +2 -2
- package/dist/claude-code/claude-code-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/codex/index.d.mts +2 -2
- package/dist/codex/index.d.ts +2 -2
- package/dist/codex/index.js +92 -10
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +92 -10
- package/dist/codex/index.mjs.map +1 -1
- 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 +92 -10
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +92 -10
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/{express-DCXa1oqj.d.mts → express-BZajRs4i.d.mts} +1 -1
- package/dist/{express-ClNtDhhc.d.ts → express-CjCUB1k7.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 +92 -10
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +92 -10
- 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-BrNKDmiR.d.mts → index-B0cyMZDL.d.mts} +1 -1
- package/dist/{index-Dr_XiN65.d.mts → index-BRYteOqO.d.mts} +1 -1
- package/dist/{index-CfHurO1P.d.ts → index-BZQdVqNw.d.ts} +1 -1
- package/dist/{index-D2ztkumS.d.ts → index-adgKhujR.d.ts} +1 -1
- package/dist/index.d.mts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +160 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +159 -10
- 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-CEBVBsdi.d.ts → nextjs-D_iFf5k-.d.ts} +1 -1
- package/dist/{nextjs-DcQIk6Zj.d.mts → nextjs-DeUTnOBd.d.mts} +1 -1
- package/dist/{sdk-H0JCLW2y.d.ts → sdk-BM3mwEAq.d.ts} +1 -1
- package/dist/{sdk-CZkbSOeO.d.mts → sdk-_il1Q41f.d.mts} +1 -1
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/{types-sy3tq8lp.d.mts → types-BcDf9Kk0.d.mts} +118 -1
- package/dist/{types-DhFPiZ3t.d.ts → types-CHKCgDFC.d.ts} +1 -1
- package/dist/{types-cQVCMeNV.d.mts → types-DfnP7JiM.d.mts} +1 -1
- package/dist/{types-9tns4wyl.d.ts → types-fTQD448H.d.ts} +118 -1
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +15 -2
- package/dist/verify.d.ts +15 -2
- package/dist/verify.js +117 -10
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +115 -10
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
package/dist/adapters/mcp.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Request, Response, RequestHandler } from 'express';
|
|
2
|
-
import { a as AccessLevel, G as GatewayConfig,
|
|
2
|
+
import { a as AccessLevel, G as GatewayConfig, w as VerificationResult } from '../types-BcDf9Kk0.mjs';
|
|
3
3
|
import '../metadata-capture.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/adapters/mcp.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Request, Response, RequestHandler } from 'express';
|
|
2
|
-
import { a as AccessLevel, G as GatewayConfig,
|
|
2
|
+
import { a as AccessLevel, G as GatewayConfig, w as VerificationResult } from '../types-fTQD448H.js';
|
|
3
3
|
import '../metadata-capture.js';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/adapters/mcp.js
CHANGED
|
@@ -40,7 +40,7 @@ function getTrustLevel(score) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// src/version.ts
|
|
43
|
-
var SDK_VERSION = "
|
|
43
|
+
var SDK_VERSION = "4.0.0";
|
|
44
44
|
|
|
45
45
|
// src/well-known.ts
|
|
46
46
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -118,7 +118,7 @@ var DEFAULT_CONFIG = {
|
|
|
118
118
|
};
|
|
119
119
|
var initCheckPerformed = false;
|
|
120
120
|
var deprecationWarningShown = false;
|
|
121
|
-
async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
121
|
+
async function performInitCheck(apiBaseUrl, debug, strictInit, apiKey) {
|
|
122
122
|
initCheckPerformed = true;
|
|
123
123
|
try {
|
|
124
124
|
const probeUrl = `${apiBaseUrl}/agents/verify-access`;
|
|
@@ -135,6 +135,28 @@ async function performInitCheck(apiBaseUrl, debug, strictInit) {
|
|
|
135
135
|
`[VerificationGateway] init check passed for ${apiBaseUrl} (content-type: ${contentType})`
|
|
136
136
|
);
|
|
137
137
|
}
|
|
138
|
+
if (apiKey) {
|
|
139
|
+
const selfCheck = await fetch(`${apiBaseUrl}/agents/verify-access/self-check`, {
|
|
140
|
+
headers: { Authorization: `Bearer ${apiKey}` }
|
|
141
|
+
});
|
|
142
|
+
if (selfCheck.status === 401) {
|
|
143
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
144
|
+
const message = `[VerificationGateway] the configured AstraSync API key was REJECTED at startup (${body.code ?? "api_key_invalid"}: ${body.message ?? "invalid key"}). Every inbound agent will be turned away until the key is rotated` + (body.remediation?.manageUrl ? ` at ${body.remediation.manageUrl}` : "") + `.`;
|
|
145
|
+
if (strictInit) {
|
|
146
|
+
throw new Error(`${message} (strictInit=true)`);
|
|
147
|
+
}
|
|
148
|
+
console.error(message);
|
|
149
|
+
} else if (selfCheck.ok) {
|
|
150
|
+
const body = await selfCheck.json().catch(() => ({}));
|
|
151
|
+
if (typeof body.daysToExpiry === "number" && body.daysToExpiry <= 7) {
|
|
152
|
+
console.warn(
|
|
153
|
+
`[VerificationGateway] the configured AstraSync API key expires in ${body.daysToExpiry} day(s) \u2014 rotate it at Settings \u2192 Developer Tools before integrations start failing.`
|
|
154
|
+
);
|
|
155
|
+
} else if (debug) {
|
|
156
|
+
console.log("[VerificationGateway] API key self-check passed");
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
138
160
|
} catch (err) {
|
|
139
161
|
if (strictInit) {
|
|
140
162
|
throw err;
|
|
@@ -246,8 +268,17 @@ function extractCredentials(headers, query) {
|
|
|
246
268
|
function createGuidanceResponse(_config, reason, options = {}) {
|
|
247
269
|
const source = options.source ?? "no_credentials";
|
|
248
270
|
const isApiError = source === "api_error";
|
|
271
|
+
const isMisconfig = source === "merchant_misconfig";
|
|
249
272
|
const urls = options.urls;
|
|
250
|
-
const guidance =
|
|
273
|
+
const guidance = isMisconfig ? {
|
|
274
|
+
message: "This site's AstraSync integration is misconfigured (its API key was revoked, expired, or rotated). Your identity and the AstraSync platform are fine \u2014 contact the site operator. Retrying will not help.",
|
|
275
|
+
registrationUrl: urls?.registrationUrl ?? "",
|
|
276
|
+
documentationUrl: options.remediation?.docsUrl ?? urls?.documentationUrl ?? "",
|
|
277
|
+
steps: [
|
|
278
|
+
"Report the failure to the site operator \u2014 their AstraSync API key needs rotating",
|
|
279
|
+
"Do not retry: the failure is deterministic until the operator updates their key"
|
|
280
|
+
]
|
|
281
|
+
} : isApiError ? {
|
|
251
282
|
message: "Verification is temporarily unavailable. Retry with exponential backoff; if the issue persists, contact support with the correlationId.",
|
|
252
283
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
253
284
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
@@ -285,14 +316,24 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
285
316
|
// partners (and their custom onDenied handlers) can branch on
|
|
286
317
|
// dimension. Without this, the synthesised stub was indistinguishable
|
|
287
318
|
// from a real policy deny.
|
|
288
|
-
failures:
|
|
319
|
+
failures: isMisconfig ? [
|
|
320
|
+
{
|
|
321
|
+
dimension: "verify_access.merchant_misconfigured",
|
|
322
|
+
message: reason ?? "The integration API key was rejected by AstraSync",
|
|
323
|
+
guidance: guidance.message
|
|
324
|
+
}
|
|
325
|
+
] : isApiError ? [
|
|
289
326
|
{
|
|
290
327
|
dimension: "verify_access.api_error",
|
|
291
328
|
message: reason ?? "Verification temporarily unavailable",
|
|
292
329
|
guidance: guidance.message
|
|
293
330
|
}
|
|
294
331
|
] : void 0,
|
|
332
|
+
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
333
|
+
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
334
|
+
...isMisconfig && { misconfigured: true },
|
|
295
335
|
correlationId: options.correlationId,
|
|
336
|
+
attemptId: options.attemptId,
|
|
296
337
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
297
338
|
};
|
|
298
339
|
}
|
|
@@ -322,6 +363,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
322
363
|
body.runtimeChallengeOptions = requestData.runtimeChallengeOptions;
|
|
323
364
|
if (requestData.invocationProtocol) body.invocationProtocol = requestData.invocationProtocol;
|
|
324
365
|
if (requestData.commerceArtifacts) body.commerceArtifacts = requestData.commerceArtifacts;
|
|
366
|
+
if (requestData.attemptId) body.attemptId = requestData.attemptId;
|
|
367
|
+
if (requestData.considerationSet) body.considerationSet = requestData.considerationSet;
|
|
325
368
|
body.sdkVersion = SDK_VERSION;
|
|
326
369
|
if (requestData.callerMetadata || requestData.clientIp || requestData.userAgent) {
|
|
327
370
|
const meta = {
|
|
@@ -343,12 +386,16 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
343
386
|
const response = await fetch(`${config.apiBaseUrl}/agents/verify-access`, {
|
|
344
387
|
method: "POST",
|
|
345
388
|
headers,
|
|
346
|
-
body: JSON.stringify(body)
|
|
389
|
+
body: JSON.stringify(body),
|
|
390
|
+
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
347
391
|
});
|
|
348
392
|
const data = await response.json();
|
|
349
393
|
if (response.status === 410) {
|
|
350
394
|
return {
|
|
351
395
|
success: true,
|
|
396
|
+
// 3.12.0 (Trust Record): keep the server-echoed attempt handle even on
|
|
397
|
+
// the synthesised 410 deny shape (echoed on every branch).
|
|
398
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
352
399
|
access: {
|
|
353
400
|
allowed: false,
|
|
354
401
|
accessLevel: "none",
|
|
@@ -364,10 +411,22 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
364
411
|
};
|
|
365
412
|
}
|
|
366
413
|
if (!response.ok) {
|
|
414
|
+
if (response.status === 401) {
|
|
415
|
+
return {
|
|
416
|
+
success: false,
|
|
417
|
+
error: data.message || data.error || "Integration API key rejected",
|
|
418
|
+
misconfig: true,
|
|
419
|
+
misconfigCode: typeof data?.code === "string" ? data.code : void 0,
|
|
420
|
+
remediation: data?.remediation && typeof data.remediation === "object" ? data.remediation : void 0,
|
|
421
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
422
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
423
|
+
};
|
|
424
|
+
}
|
|
367
425
|
return {
|
|
368
426
|
success: false,
|
|
369
427
|
error: data.message || data.error || `API returned ${response.status}`,
|
|
370
|
-
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0
|
|
428
|
+
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
429
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
371
430
|
};
|
|
372
431
|
}
|
|
373
432
|
return data;
|
|
@@ -384,9 +443,19 @@ async function verify(config, request, options) {
|
|
|
384
443
|
const urls = mergedConfig.apiBaseUrl ? getCachedWellKnownUrls(mergedConfig.apiBaseUrl) : void 0;
|
|
385
444
|
if (!initCheckPerformed && !mergedConfig.disableInitChecks && mergedConfig.apiBaseUrl) {
|
|
386
445
|
if (mergedConfig.strictInit) {
|
|
387
|
-
await performInitCheck(
|
|
446
|
+
await performInitCheck(
|
|
447
|
+
mergedConfig.apiBaseUrl,
|
|
448
|
+
mergedConfig.debug,
|
|
449
|
+
true,
|
|
450
|
+
mergedConfig.apiKey
|
|
451
|
+
);
|
|
388
452
|
} else {
|
|
389
|
-
void performInitCheck(
|
|
453
|
+
void performInitCheck(
|
|
454
|
+
mergedConfig.apiBaseUrl,
|
|
455
|
+
mergedConfig.debug,
|
|
456
|
+
false,
|
|
457
|
+
mergedConfig.apiKey
|
|
458
|
+
);
|
|
390
459
|
}
|
|
391
460
|
}
|
|
392
461
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
@@ -401,7 +470,13 @@ async function verify(config, request, options) {
|
|
|
401
470
|
if (mergedConfig.debug) {
|
|
402
471
|
console.log("[VerificationGateway] Returning cached result");
|
|
403
472
|
}
|
|
404
|
-
|
|
473
|
+
const hit = { ...cached };
|
|
474
|
+
if (request.attemptId) {
|
|
475
|
+
hit.attemptId = request.attemptId;
|
|
476
|
+
} else {
|
|
477
|
+
delete hit.attemptId;
|
|
478
|
+
}
|
|
479
|
+
return hit;
|
|
405
480
|
}
|
|
406
481
|
}
|
|
407
482
|
const enrichedRequest = { ...request };
|
|
@@ -419,8 +494,10 @@ async function verify(config, request, options) {
|
|
|
419
494
|
const serverDenialReasons = Array.isArray(rawServerDenialReasons) && rawServerDenialReasons.length > 0 ? rawServerDenialReasons : void 0;
|
|
420
495
|
if (!apiResponse.success) {
|
|
421
496
|
return createGuidanceResponse(mergedConfig, apiResponse.error, {
|
|
422
|
-
source: "api_error",
|
|
497
|
+
source: apiResponse.misconfig ? "merchant_misconfig" : "api_error",
|
|
423
498
|
correlationId: apiResponse.correlationId,
|
|
499
|
+
attemptId: apiResponse.attemptId,
|
|
500
|
+
remediation: apiResponse.remediation,
|
|
424
501
|
urls
|
|
425
502
|
});
|
|
426
503
|
}
|
|
@@ -456,6 +533,9 @@ async function verify(config, request, options) {
|
|
|
456
533
|
// Anonymous traffic has no session → correlationId is the per-attempt
|
|
457
534
|
// linking key (the sessionId-equivalent for anonymous callers).
|
|
458
535
|
correlationId: apiResponse.correlationId,
|
|
536
|
+
// 3.12.0 (Trust Record): server echoes the attempt-chain handle on
|
|
537
|
+
// every branch — denials included (the funnel outlives one deny).
|
|
538
|
+
attemptId: apiResponse.attemptId,
|
|
459
539
|
recommendation: apiResponse.recommendation,
|
|
460
540
|
recommendationReasons: apiResponse.recommendationReasons,
|
|
461
541
|
stepUpApproval: apiResponse.stepUpApproval,
|
|
@@ -507,6 +587,8 @@ async function verify(config, request, options) {
|
|
|
507
587
|
// v2.3.10 (defect #34, round-4): anonymous responses surface correlationId
|
|
508
588
|
// (no session row exists for unverified callers).
|
|
509
589
|
correlationId: apiResponse.correlationId,
|
|
590
|
+
// 3.12.0 (Trust Record): server-echoed attempt-chain handle.
|
|
591
|
+
attemptId: apiResponse.attemptId,
|
|
510
592
|
runtimeChallenge: apiResponse.runtimeChallenge,
|
|
511
593
|
tokenGuidance: apiResponse.tokenGuidance,
|
|
512
594
|
recommendation: apiResponse.recommendation,
|
|
@@ -769,6 +851,24 @@ function dedupeFailures(result) {
|
|
|
769
851
|
}
|
|
770
852
|
function defaultMcpDenied(result, req, res) {
|
|
771
853
|
const id = req.body?.id ?? null;
|
|
854
|
+
if (result.misconfigured) {
|
|
855
|
+
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
856
|
+
res.status(503).json({
|
|
857
|
+
jsonrpc: "2.0",
|
|
858
|
+
id,
|
|
859
|
+
error: {
|
|
860
|
+
// -32002 → merchant verification misconfigured (see -32000/-32001 below)
|
|
861
|
+
code: -32002,
|
|
862
|
+
message: result.denialReasons?.[0] ?? "This server's AstraSync integration is misconfigured",
|
|
863
|
+
data: {
|
|
864
|
+
guidance: result.guidance,
|
|
865
|
+
failures: result.failures,
|
|
866
|
+
correlationId: result.correlationId
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
});
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
772
872
|
const status = !result.identityVerified ? 401 : 403;
|
|
773
873
|
res.setHeader("X-Astra-Gateway-Mode", "enforced");
|
|
774
874
|
res.status(status).json({
|
|
@@ -778,6 +878,7 @@ function defaultMcpDenied(result, req, res) {
|
|
|
778
878
|
// JSON-RPC error codes:
|
|
779
879
|
// -32000 → unauthorized (no identity resolved)
|
|
780
880
|
// -32001 → insufficient access (identity OK, policy denied)
|
|
881
|
+
// -32002 → merchant verification misconfigured (handled above)
|
|
781
882
|
code: !result.identityVerified ? -32e3 : -32001,
|
|
782
883
|
message: result.denialReasons?.[0] ?? "Access denied",
|
|
783
884
|
data: {
|