@astrasyncai/verification-gateway 5.11.0 → 5.12.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/README.md +4 -0
- package/dist/adapters/express.d.mts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +359 -30
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +359 -30
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +5 -1
- package/dist/adapters/mcp.d.ts +5 -1
- package/dist/adapters/mcp.js +168 -41
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +168 -41
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +1 -1
- package/dist/adapters/nextjs.d.ts +1 -1
- package/dist/adapters/nextjs.js +352 -13
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +352 -13
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +9 -1
- package/dist/adapters/sdk.d.ts +9 -1
- package/dist/adapters/sdk.js +100 -8
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +100 -8
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +284 -7
- package/dist/bin/astrasync-codex-hook.js +284 -7
- package/dist/bin/astrasync-guard.js +284 -7
- package/dist/bin/astrasync.js +297 -9
- package/dist/browser/background.js +284 -7
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +284 -7
- package/dist/browser/background.mjs.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.js +284 -7
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +284 -7
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/extension.js +284 -7
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +284 -7
- 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/edge-config.js +1 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +1 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +128 -13
- package/dist/edge-core/index.d.ts +128 -13
- package/dist/edge-core/index.js +337 -55
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +334 -55
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/gateway/gateway.js +284 -7
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +284 -7
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +1 -1
- package/dist/git-trigger/git-hooks.d.ts +1 -1
- package/dist/index.d.mts +118 -5
- package/dist/index.d.ts +118 -5
- package/dist/index.js +486 -63
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +480 -63
- package/dist/index.mjs.map +1 -1
- package/dist/platform-signatures.js +4 -1
- package/dist/platform-signatures.js.map +1 -1
- package/dist/platform-signatures.mjs +4 -1
- package/dist/platform-signatures.mjs.map +1 -1
- package/dist/registration/index.js +1 -1
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +1 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/transport/index.js +1 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +1 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-CTmUpNpS.d.mts → types-BCkwBA84.d.mts} +12 -0
- package/dist/{types-CTmUpNpS.d.ts → types-BCkwBA84.d.ts} +12 -0
- package/dist/{types-CtFXmDzm.d.ts → types-C_b4QTyO.d.ts} +18 -0
- package/dist/{types-DQrn_kei.d.mts → types-DlshIIR-.d.mts} +18 -0
- package/dist/ui/index.d.mts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/verify.d.mts +35 -4
- package/dist/verify.d.ts +35 -4
- package/dist/verify.js +130 -16
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +129 -16
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
package/dist/verify.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/version.ts
|
|
2
|
-
var SDK_VERSION = "5.
|
|
2
|
+
var SDK_VERSION = "5.12.0";
|
|
3
3
|
|
|
4
4
|
// src/http.ts
|
|
5
5
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -34,6 +34,29 @@ function getCachedWellKnownUrls(apiBaseUrl) {
|
|
|
34
34
|
return cache.get(apiBaseUrl)?.data;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// src/failure-posture.ts
|
|
38
|
+
var DEFAULT_UNAVAILABLE_RETRY_AFTER_S = 30;
|
|
39
|
+
var REJECTED_IDENTITY_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
40
|
+
"identity.invalid_agent_id",
|
|
41
|
+
"identity.unknown_agent",
|
|
42
|
+
"agent.lookup"
|
|
43
|
+
]);
|
|
44
|
+
var UNKNOWN_AGENT_GUIDANCE = "Register your agent with AstraSync (or, inside an MCP host, add the AstraSync MCP connector for keyless, human-approved registration), then present the canonical ASTRA-* id issued after owner approval.";
|
|
45
|
+
var UNAVAILABLE_DIMENSIONS = /* @__PURE__ */ new Set([
|
|
46
|
+
"verify_access.api_error",
|
|
47
|
+
"middleware.internal_error"
|
|
48
|
+
]);
|
|
49
|
+
function isVerificationUnavailable(result) {
|
|
50
|
+
if (result.misconfigured) return false;
|
|
51
|
+
return (result.failures ?? []).some((f) => UNAVAILABLE_DIMENSIONS.has(f.dimension));
|
|
52
|
+
}
|
|
53
|
+
function unavailableRetryAfterSeconds(result) {
|
|
54
|
+
if (typeof result.retryAfterMs === "number" && Number.isFinite(result.retryAfterMs)) {
|
|
55
|
+
return Math.max(1, Math.ceil(result.retryAfterMs / 1e3));
|
|
56
|
+
}
|
|
57
|
+
return DEFAULT_UNAVAILABLE_RETRY_AFTER_S;
|
|
58
|
+
}
|
|
59
|
+
|
|
37
60
|
// src/verify.ts
|
|
38
61
|
var DEFAULT_CONFIG = {
|
|
39
62
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
@@ -288,11 +311,44 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
288
311
|
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
289
312
|
// deterministic and intentionally NOT marked retryable.
|
|
290
313
|
...isApiError && { retryable: true },
|
|
314
|
+
...options.httpStatus !== void 0 && { httpStatus: options.httpStatus },
|
|
315
|
+
...options.retryAfterMs !== void 0 && { retryAfterMs: options.retryAfterMs },
|
|
291
316
|
correlationId: options.correlationId,
|
|
292
317
|
attemptId: options.attemptId,
|
|
293
318
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
294
319
|
};
|
|
295
320
|
}
|
|
321
|
+
async function readJsonSafe(response) {
|
|
322
|
+
try {
|
|
323
|
+
const parsed = await response.json();
|
|
324
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
325
|
+
} catch {
|
|
326
|
+
return {};
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function rejectedIdentityGuidance(failures) {
|
|
330
|
+
const f = failures?.find((x) => REJECTED_IDENTITY_DIMENSIONS.has(x.dimension));
|
|
331
|
+
if (!f) return void 0;
|
|
332
|
+
if (f.dimension === "agent.lookup") {
|
|
333
|
+
return `The presented agent identifier is not registered with AstraSync. ${UNKNOWN_AGENT_GUIDANCE}`;
|
|
334
|
+
}
|
|
335
|
+
return f.guidance ? `${f.message} ${f.guidance}` : f.message;
|
|
336
|
+
}
|
|
337
|
+
var MAX_RETRY_AFTER_MS = 15 * 60 * 1e3;
|
|
338
|
+
function parseRetryAfterMs(response) {
|
|
339
|
+
const raw = response.headers?.get?.("retry-after");
|
|
340
|
+
if (!raw) return void 0;
|
|
341
|
+
const trimmed = raw.trim();
|
|
342
|
+
let ms;
|
|
343
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
344
|
+
ms = Number(trimmed) * 1e3;
|
|
345
|
+
} else {
|
|
346
|
+
const at = Date.parse(trimmed);
|
|
347
|
+
if (Number.isNaN(at)) return void 0;
|
|
348
|
+
ms = at - Date.now();
|
|
349
|
+
}
|
|
350
|
+
return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, Math.round(ms)));
|
|
351
|
+
}
|
|
296
352
|
async function callVerifyAccessAPI(config, request) {
|
|
297
353
|
const { credentials, ...requestData } = request;
|
|
298
354
|
const body = {
|
|
@@ -349,7 +405,8 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
349
405
|
body: JSON.stringify(body),
|
|
350
406
|
signal: AbortSignal.timeout(config.verifyTimeoutMs ?? 1e4)
|
|
351
407
|
});
|
|
352
|
-
const data = await response
|
|
408
|
+
const data = await readJsonSafe(response);
|
|
409
|
+
const retryAfterMs = parseRetryAfterMs(response);
|
|
353
410
|
if (response.status === 410) {
|
|
354
411
|
return {
|
|
355
412
|
success: true,
|
|
@@ -387,6 +444,23 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
387
444
|
}
|
|
388
445
|
};
|
|
389
446
|
}
|
|
447
|
+
if (response.status === 404 && credentials.astraId && (data?.error === "AGENT_NOT_FOUND" || typeof data?.message === "string" && /agent/i.test(data.message))) {
|
|
448
|
+
return {
|
|
449
|
+
success: true,
|
|
450
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
451
|
+
access: {
|
|
452
|
+
allowed: false,
|
|
453
|
+
reason: "unknown_agent",
|
|
454
|
+
failures: [
|
|
455
|
+
{
|
|
456
|
+
dimension: "identity.unknown_agent",
|
|
457
|
+
message: "The presented agent identifier is not registered with AstraSync.",
|
|
458
|
+
guidance: UNKNOWN_AGENT_GUIDANCE
|
|
459
|
+
}
|
|
460
|
+
]
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
}
|
|
390
464
|
if (!response.ok) {
|
|
391
465
|
if (response.status === 401) {
|
|
392
466
|
return {
|
|
@@ -401,9 +475,11 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
401
475
|
}
|
|
402
476
|
return {
|
|
403
477
|
success: false,
|
|
404
|
-
error: data.message || data.error || `API returned ${response.status}`,
|
|
478
|
+
error: typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || `API returned ${response.status}`,
|
|
405
479
|
correlationId: typeof data?.correlationId === "string" ? data.correlationId : void 0,
|
|
406
|
-
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0
|
|
480
|
+
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
481
|
+
httpStatus: response.status,
|
|
482
|
+
...retryAfterMs !== void 0 && { retryAfterMs }
|
|
407
483
|
};
|
|
408
484
|
}
|
|
409
485
|
return data;
|
|
@@ -475,12 +551,14 @@ async function verify(config, request, options) {
|
|
|
475
551
|
correlationId: apiResponse.correlationId,
|
|
476
552
|
attemptId: apiResponse.attemptId,
|
|
477
553
|
remediation: apiResponse.remediation,
|
|
554
|
+
httpStatus: apiResponse.httpStatus,
|
|
555
|
+
retryAfterMs: apiResponse.retryAfterMs,
|
|
478
556
|
urls
|
|
479
557
|
});
|
|
480
558
|
}
|
|
481
559
|
if (!apiResponse.access?.allowed) {
|
|
482
560
|
const aggregatedFailures = apiResponse.access?.failures;
|
|
483
|
-
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true;
|
|
561
|
+
const idVerifiedFromBackend = apiResponse.verificationContext?.idVerified === true && !aggregatedFailures?.some((f) => REJECTED_IDENTITY_DIMENSIONS.has(f.dimension));
|
|
484
562
|
const result2 = {
|
|
485
563
|
identityVerified: idVerifiedFromBackend,
|
|
486
564
|
policyAllowed: false,
|
|
@@ -492,7 +570,10 @@ async function verify(config, request, options) {
|
|
|
492
570
|
requiresStepUp: apiResponse.access?.requiresStepUp,
|
|
493
571
|
requiresApproval: apiResponse.access?.requiresApproval,
|
|
494
572
|
guidance: {
|
|
495
|
-
|
|
573
|
+
// 5.12.0: a presented-but-rejected id (malformed / unknown) carries
|
|
574
|
+
// actionable registration guidance on its failure — surface it
|
|
575
|
+
// instead of the bare machine reason ('unknown_agent').
|
|
576
|
+
message: rejectedIdentityGuidance(aggregatedFailures) ?? (apiResponse.access?.reason || "Access denied by PDLSS policy"),
|
|
496
577
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
497
578
|
documentationUrl: urls?.documentationUrl ?? "",
|
|
498
579
|
// 5.1.0: anonymous callers land on this branch — steer MCP-hosted
|
|
@@ -592,7 +673,7 @@ async function verify(config, request, options) {
|
|
|
592
673
|
registrationUrl: urls?.registrationUrl ?? "",
|
|
593
674
|
documentationUrl: urls?.documentationUrl ?? ""
|
|
594
675
|
};
|
|
595
|
-
} else if (result.recommendation === "step_up_required") {
|
|
676
|
+
} else if (result.recommendation === "step_up_required" && result.identityVerified) {
|
|
596
677
|
result.requiresStepUp = true;
|
|
597
678
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Step-up verification required"];
|
|
598
679
|
}
|
|
@@ -615,7 +696,7 @@ async function recordDecision(config, sessionId, decision, reason) {
|
|
|
615
696
|
}).catch(() => {
|
|
616
697
|
});
|
|
617
698
|
}
|
|
618
|
-
async function reportAttempt(config, report) {
|
|
699
|
+
async function reportAttempt(config, report, options = {}) {
|
|
619
700
|
const apiBaseUrl = config.apiBaseUrl || DEFAULT_CONFIG.apiBaseUrl;
|
|
620
701
|
const headers = { "Content-Type": "application/json" };
|
|
621
702
|
if (config.apiKey) {
|
|
@@ -626,13 +707,37 @@ async function reportAttempt(config, report) {
|
|
|
626
707
|
...report,
|
|
627
708
|
...!report.counterpartyId && config.counterpartyId && { counterpartyId: config.counterpartyId }
|
|
628
709
|
};
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
710
|
+
const url = `${apiBaseUrl}/agents/verify-access/attempt-report`;
|
|
711
|
+
const init = { method: "POST", headers, body: JSON.stringify(body) };
|
|
712
|
+
const fail = (failure) => {
|
|
713
|
+
try {
|
|
714
|
+
options.onFailure?.(failure);
|
|
715
|
+
} catch {
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
let response;
|
|
719
|
+
try {
|
|
720
|
+
response = await sdkFetch(url, init);
|
|
721
|
+
} catch (err) {
|
|
722
|
+
fail({ error: err instanceof Error ? err.message : String(err), retried: false });
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
if (response.ok) return;
|
|
726
|
+
if (response.status !== 429 && response.status < 500) {
|
|
727
|
+
fail({ status: response.status, retried: false });
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
const delayMs = Math.min(ATTEMPT_REPORT_MAX_RETRY_DELAY_MS, parseRetryAfterMs(response) ?? 500);
|
|
731
|
+
const timer = setTimeout(() => {
|
|
732
|
+
sdkFetch(url, init).then((retry) => {
|
|
733
|
+
if (!retry.ok) fail({ status: retry.status, retried: true });
|
|
734
|
+
}).catch((err) => {
|
|
735
|
+
fail({ error: err instanceof Error ? err.message : String(err), retried: true });
|
|
736
|
+
});
|
|
737
|
+
}, delayMs);
|
|
738
|
+
timer.unref?.();
|
|
635
739
|
}
|
|
740
|
+
var ATTEMPT_REPORT_MAX_RETRY_DELAY_MS = 2e3;
|
|
636
741
|
async function fetchRoutes(config, counterpartyId) {
|
|
637
742
|
if (!counterpartyId) return null;
|
|
638
743
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -677,7 +782,10 @@ async function reportUnregisteredAttempt(config, data) {
|
|
|
677
782
|
};
|
|
678
783
|
await sdkFetch(`${apiBaseUrl}/verification-activity/unregistered-attempt`, {
|
|
679
784
|
method: "POST",
|
|
680
|
-
headers: {
|
|
785
|
+
headers: {
|
|
786
|
+
"Content-Type": "application/json",
|
|
787
|
+
...config.apiKey && { Authorization: `Bearer ${config.apiKey}` }
|
|
788
|
+
},
|
|
681
789
|
body: JSON.stringify(body)
|
|
682
790
|
}).catch(() => {
|
|
683
791
|
});
|
|
@@ -699,7 +807,11 @@ async function quickVerify(config, credentials) {
|
|
|
699
807
|
return {
|
|
700
808
|
identityVerified: result.identityVerified,
|
|
701
809
|
policyAllowed: result.policyAllowed,
|
|
702
|
-
reason: result.denialReasons?.[0]
|
|
810
|
+
reason: result.denialReasons?.[0],
|
|
811
|
+
...isVerificationUnavailable(result) && {
|
|
812
|
+
unavailable: true,
|
|
813
|
+
retryAfterMs: unavailableRetryAfterSeconds(result) * 1e3
|
|
814
|
+
}
|
|
703
815
|
};
|
|
704
816
|
}
|
|
705
817
|
export {
|
|
@@ -708,6 +820,7 @@ export {
|
|
|
708
820
|
extractCredentials,
|
|
709
821
|
fetchRoutes,
|
|
710
822
|
hasCredentials,
|
|
823
|
+
parseRetryAfterMs,
|
|
711
824
|
quickVerify,
|
|
712
825
|
recordDecision,
|
|
713
826
|
reportAttempt,
|