@astrasyncai/verification-gateway 4.5.1 → 5.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/README.md +1 -1
- 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 +11 -33
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +11 -33
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +2 -2
- package/dist/adapters/mcp.d.ts +2 -2
- package/dist/adapters/mcp.js +28 -65
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +27 -64
- 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 +9 -30
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +9 -30
- 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 +8 -124
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +8 -122
- 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 +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 +63 -41
- package/dist/bin/astrasync-codex-hook.js +63 -41
- package/dist/bin/astrasync-guard.js +63 -41
- package/dist/bin/astrasync.js +75 -48
- package/dist/browser/background.js +63 -41
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +63 -41
- 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/cli/index.js +33 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +33 -6
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.d.mts +2 -2
- package/dist/codex/index.d.ts +2 -2
- package/dist/codex/index.js +63 -41
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +63 -41
- 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 +63 -41
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +63 -41
- 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 +1 -3
- package/dist/edge-core/index.d.ts +1 -3
- package/dist/edge-core/index.js +11 -33
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +11 -33
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/{express-DaqL11tx.d.ts → express-B5lWuemA.d.ts} +1 -1
- package/dist/{express-CR6F3njD.d.mts → express-Dm-snUuY.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 +63 -41
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +63 -41
- 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-Cub7lK-T.d.mts → index-B5k_vUmK.d.mts} +1 -1
- package/dist/{index-BfIxCYIZ.d.ts → index-BOzM6xUq.d.mts} +1 -2
- package/dist/{index-CwAh7Tln.d.mts → index-dRfxUdFA.d.ts} +1 -2
- package/dist/{index-B5Ts1WtM.d.ts → index-y8xToocF.d.ts} +1 -1
- package/dist/index.d.mts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +30 -217
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +30 -210
- 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 +22 -7
- package/dist/local-evaluator/evaluator.js.map +1 -1
- package/dist/local-evaluator/evaluator.mjs +22 -7
- package/dist/local-evaluator/evaluator.mjs.map +1 -1
- package/dist/{mcp-BgBJu4Jl.d.mts → mcp-DgsyQiQq.d.mts} +53 -52
- package/dist/{mcp--DgKOwfu.d.ts → mcp-OosmAcKf.d.ts} +53 -52
- package/dist/{nextjs-DlX6xwbU.d.mts → nextjs-B1sBdEav.d.mts} +1 -1
- package/dist/{nextjs-DL6uE1ye.d.ts → nextjs-DoRmhV_Z.d.ts} +1 -1
- package/dist/registration/index.d.mts +5 -1
- package/dist/registration/index.d.ts +5 -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/sdk-B83N3xKc.d.mts +142 -0
- package/dist/sdk-H_9BTNBS.d.ts +142 -0
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- 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-DwSfO7Sb.d.ts → types-BK2POWNc.d.ts} +23 -50
- package/dist/{types-C0zfSXMB.d.mts → types-CJjZvPr9.d.mts} +23 -50
- package/dist/{types-C7Rb-w0d.d.mts → types-CXf3q4kZ.d.ts} +14 -3
- package/dist/{types-nIh3HtuA.d.ts → types-DQmop7ZW.d.mts} +14 -3
- package/dist/ui/index.d.mts +2 -17
- package/dist/ui/index.d.ts +2 -17
- package/dist/ui/index.js +1 -43
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/index.mjs +1 -42
- package/dist/ui/index.mjs.map +1 -1
- package/dist/verify.d.mts +3 -4
- package/dist/verify.d.ts +3 -4
- package/dist/verify.js +8 -28
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +8 -28
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/sdk-Bbh9B_dw.d.mts +0 -215
- package/dist/sdk-C6SASmsh.d.ts +0 -215
|
@@ -3137,10 +3137,16 @@ function validatePurpose(purpose, path2) {
|
|
|
3137
3137
|
errors.push({ path: `${path2}.targets`, message: "targets must be an array of strings" });
|
|
3138
3138
|
}
|
|
3139
3139
|
if (p.blockedPatterns !== void 0 && !isStringArray(p.blockedPatterns)) {
|
|
3140
|
-
errors.push({
|
|
3140
|
+
errors.push({
|
|
3141
|
+
path: `${path2}.blockedPatterns`,
|
|
3142
|
+
message: "blockedPatterns must be an array of strings"
|
|
3143
|
+
});
|
|
3141
3144
|
}
|
|
3142
3145
|
if (p.requiresApproval !== void 0 && typeof p.requiresApproval !== "boolean") {
|
|
3143
|
-
errors.push({
|
|
3146
|
+
errors.push({
|
|
3147
|
+
path: `${path2}.requiresApproval`,
|
|
3148
|
+
message: "requiresApproval must be a boolean"
|
|
3149
|
+
});
|
|
3144
3150
|
}
|
|
3145
3151
|
return errors;
|
|
3146
3152
|
}
|
|
@@ -3163,11 +3169,29 @@ function validateLimits(limits, path2) {
|
|
|
3163
3169
|
return [{ path: path2, message: "limits must be an object" }];
|
|
3164
3170
|
}
|
|
3165
3171
|
const l = limits;
|
|
3172
|
+
if (l.autonomousThreshold !== void 0 && typeof l.autonomousThreshold !== "number") {
|
|
3173
|
+
errors.push({
|
|
3174
|
+
path: `${path2}.autonomousThreshold`,
|
|
3175
|
+
message: "autonomousThreshold must be a number"
|
|
3176
|
+
});
|
|
3177
|
+
}
|
|
3166
3178
|
if (l.maxTransactionAmount !== void 0 && typeof l.maxTransactionAmount !== "number") {
|
|
3167
|
-
errors.push({
|
|
3179
|
+
errors.push({
|
|
3180
|
+
path: `${path2}.maxTransactionAmount`,
|
|
3181
|
+
message: "maxTransactionAmount must be a number"
|
|
3182
|
+
});
|
|
3183
|
+
}
|
|
3184
|
+
if (typeof l.autonomousThreshold === "number" && typeof l.maxTransactionAmount === "number" && l.autonomousThreshold > l.maxTransactionAmount) {
|
|
3185
|
+
errors.push({
|
|
3186
|
+
path: `${path2}.autonomousThreshold`,
|
|
3187
|
+
message: "autonomousThreshold (Autonomous Limit) must be <= maxTransactionAmount (Hard Limit)"
|
|
3188
|
+
});
|
|
3168
3189
|
}
|
|
3169
3190
|
if (l.maxRequestsPerHour !== void 0 && typeof l.maxRequestsPerHour !== "number") {
|
|
3170
|
-
errors.push({
|
|
3191
|
+
errors.push({
|
|
3192
|
+
path: `${path2}.maxRequestsPerHour`,
|
|
3193
|
+
message: "maxRequestsPerHour must be a number"
|
|
3194
|
+
});
|
|
3171
3195
|
}
|
|
3172
3196
|
if (l.currency !== void 0 && typeof l.currency !== "string") {
|
|
3173
3197
|
errors.push({ path: `${path2}.currency`, message: "currency must be a string" });
|
|
@@ -3182,7 +3206,10 @@ function validateRiskThresholds(thresholds, path2) {
|
|
|
3182
3206
|
const t = thresholds;
|
|
3183
3207
|
for (const range of ["autoAllow", "requireApproval", "autoBlock"]) {
|
|
3184
3208
|
if (!t[range] || typeof t[range] !== "object") {
|
|
3185
|
-
errors.push({
|
|
3209
|
+
errors.push({
|
|
3210
|
+
path: `${path2}.${range}`,
|
|
3211
|
+
message: `${range} is required and must be an object with min and max`
|
|
3212
|
+
});
|
|
3186
3213
|
continue;
|
|
3187
3214
|
}
|
|
3188
3215
|
const r = t[range];
|
|
@@ -3678,7 +3705,7 @@ Policy saved to ${outputPath}`);
|
|
|
3678
3705
|
};
|
|
3679
3706
|
|
|
3680
3707
|
// src/version.ts
|
|
3681
|
-
var SDK_VERSION = "
|
|
3708
|
+
var SDK_VERSION = "5.0.0";
|
|
3682
3709
|
|
|
3683
3710
|
// src/http.ts
|
|
3684
3711
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -4419,9 +4446,9 @@ var LocalEvaluator = class {
|
|
|
4419
4446
|
if (scopeBlock) {
|
|
4420
4447
|
return { recommendation: "DENY", reason: scopeBlock };
|
|
4421
4448
|
}
|
|
4422
|
-
const
|
|
4423
|
-
if (
|
|
4424
|
-
return
|
|
4449
|
+
const limitDecision = this.checkLimits(context);
|
|
4450
|
+
if (limitDecision) {
|
|
4451
|
+
return limitDecision;
|
|
4425
4452
|
}
|
|
4426
4453
|
if (context.purpose === "sub_agent.spawn" && this.policy.selfInstantiation) {
|
|
4427
4454
|
if (!this.policy.selfInstantiation.allowed) {
|
|
@@ -4486,9 +4513,21 @@ var LocalEvaluator = class {
|
|
|
4486
4513
|
checkLimits(context) {
|
|
4487
4514
|
const limits = this.policy.limits;
|
|
4488
4515
|
if (!limits) return null;
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4516
|
+
const value = context.transactionValue;
|
|
4517
|
+
if (value !== void 0 && value > 0 && (limits.autonomousThreshold !== void 0 || limits.maxTransactionAmount !== void 0)) {
|
|
4518
|
+
const autonomousThreshold = limits.autonomousThreshold ?? 0;
|
|
4519
|
+
const hardLimit = limits.maxTransactionAmount ?? limits.autonomousThreshold ?? 0;
|
|
4520
|
+
if (value > autonomousThreshold) {
|
|
4521
|
+
if (value >= hardLimit) {
|
|
4522
|
+
return {
|
|
4523
|
+
recommendation: "DENY",
|
|
4524
|
+
reason: `Transaction value ${value} at or above Hard Limit ${hardLimit}`
|
|
4525
|
+
};
|
|
4526
|
+
}
|
|
4527
|
+
return {
|
|
4528
|
+
recommendation: "MANUAL_REVIEW",
|
|
4529
|
+
reason: `Transaction value ${value} is in the human-approval band (${autonomousThreshold}, ${hardLimit})`
|
|
4530
|
+
};
|
|
4492
4531
|
}
|
|
4493
4532
|
}
|
|
4494
4533
|
if (limits.maxRequestsPerHour !== void 0) {
|
|
@@ -4501,7 +4540,10 @@ var LocalEvaluator = class {
|
|
|
4501
4540
|
} else {
|
|
4502
4541
|
entry.count++;
|
|
4503
4542
|
if (entry.count > limits.maxRequestsPerHour) {
|
|
4504
|
-
return
|
|
4543
|
+
return {
|
|
4544
|
+
recommendation: "DENY",
|
|
4545
|
+
reason: `Rate limit exceeded: ${entry.count}/${limits.maxRequestsPerHour} requests per hour`
|
|
4546
|
+
};
|
|
4505
4547
|
}
|
|
4506
4548
|
}
|
|
4507
4549
|
}
|
|
@@ -4621,7 +4663,7 @@ function verifyLocal(evaluator, context) {
|
|
|
4621
4663
|
return evaluator.evaluate(context);
|
|
4622
4664
|
}
|
|
4623
4665
|
|
|
4624
|
-
// src/
|
|
4666
|
+
// src/trust-levels.ts
|
|
4625
4667
|
function getTrustLevel(score) {
|
|
4626
4668
|
if (score >= 80) return "PLATINUM";
|
|
4627
4669
|
if (score >= 60) return "GOLD";
|
|
@@ -4639,11 +4681,6 @@ function getCachedWellKnownUrls(apiBaseUrl) {
|
|
|
4639
4681
|
// src/verify.ts
|
|
4640
4682
|
var DEFAULT_CONFIG = {
|
|
4641
4683
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
4642
|
-
// v2.3.9 (defect #30): default for unconfigured callers is `'none'` (no
|
|
4643
|
-
// access). Pre-rename this defaulted to `'guidance'`, which combined with
|
|
4644
|
-
// a route gated at `'guidance'` to silently let unverified traffic
|
|
4645
|
-
// through (`hasMinimumAccess('guidance', 'guidance') === true`).
|
|
4646
|
-
defaultAccessLevel: "none",
|
|
4647
4684
|
// minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
|
|
4648
4685
|
// cacheTtl deliberately unset. When undefined, cacheResult applies the 60s
|
|
4649
4686
|
// default; the caller's explicit value is honoured for cacheable results.
|
|
@@ -4804,13 +4841,6 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
4804
4841
|
// policy is not evaluated (we never reached the gate).
|
|
4805
4842
|
identityVerified: false,
|
|
4806
4843
|
policyAllowed: false,
|
|
4807
|
-
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
4808
|
-
// Adapters additionally short-circuit on `!identityVerified ||
|
|
4809
|
-
// !policyAllowed` before the gate check, but the access level still has
|
|
4810
|
-
// to be honest at the data layer so downstream consumers (SDK adapters
|
|
4811
|
-
// in other languages, custom integrations) inherit the correct
|
|
4812
|
-
// semantics.
|
|
4813
|
-
accessLevel: "none",
|
|
4814
4844
|
guidance,
|
|
4815
4845
|
denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
|
|
4816
4846
|
// Round-10 (#47, O5): on API-error fallback, surface a typed failure so
|
|
@@ -4833,6 +4863,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
4833
4863
|
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
4834
4864
|
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
4835
4865
|
...isMisconfig && { misconfigured: true },
|
|
4866
|
+
// 4.6.0: a transient api_error is retryable — mark it so consumers surface
|
|
4867
|
+
// "temporarily unavailable, retry" (recommendation 'error') instead of
|
|
4868
|
+
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
4869
|
+
// deterministic and intentionally NOT marked retryable.
|
|
4870
|
+
...isApiError && { retryable: true },
|
|
4836
4871
|
correlationId: options.correlationId,
|
|
4837
4872
|
attemptId: options.attemptId,
|
|
4838
4873
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -4899,7 +4934,6 @@ async function callVerifyAccessAPI(config, request2) {
|
|
|
4899
4934
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
4900
4935
|
access: {
|
|
4901
4936
|
allowed: false,
|
|
4902
|
-
accessLevel: "none",
|
|
4903
4937
|
reason: "endpoint_deactivated",
|
|
4904
4938
|
failures: [
|
|
4905
4939
|
{
|
|
@@ -4962,7 +4996,7 @@ async function verify(config, request2, options) {
|
|
|
4962
4996
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
4963
4997
|
deprecationWarningShown = true;
|
|
4964
4998
|
console.warn(
|
|
4965
|
-
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access
|
|
4999
|
+
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access decisions (verified ID + runtime challenge + PDLSS + trust score). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
|
|
4966
5000
|
);
|
|
4967
5001
|
}
|
|
4968
5002
|
if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache) {
|
|
@@ -5008,14 +5042,6 @@ async function verify(config, request2, options) {
|
|
|
5008
5042
|
const result2 = {
|
|
5009
5043
|
identityVerified: idVerifiedFromBackend,
|
|
5010
5044
|
policyAllowed: false,
|
|
5011
|
-
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
5012
|
-
// Pre-rename this hardcoded `'guidance'`, which conflated with the
|
|
5013
|
-
// colocated `guidance: {...}` help-payload object below and let
|
|
5014
|
-
// denied requests pass any route gated at `'guidance'` because
|
|
5015
|
-
// `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now
|
|
5016
|
-
// ALSO short-circuit on `!identityVerified || !policyAllowed` before
|
|
5017
|
-
// the gate check — belt-and-braces.
|
|
5018
|
-
accessLevel: "none",
|
|
5019
5045
|
// 3.6.0: the server now emits top-level denialReasons on every deny
|
|
5020
5046
|
// path — prefer it verbatim; the failure-message reconstruction remains
|
|
5021
5047
|
// as the fallback for older backends.
|
|
@@ -5064,7 +5090,6 @@ async function verify(config, request2, options) {
|
|
|
5064
5090
|
trustScore: apiResponse.organization.trustScore
|
|
5065
5091
|
} : void 0;
|
|
5066
5092
|
const verificationContext = apiResponse.verificationContext;
|
|
5067
|
-
const accessLevel = apiResponse.access?.accessLevel ?? "standard";
|
|
5068
5093
|
const result = {
|
|
5069
5094
|
// 4.5.0 (probe F1): read idVerified from verificationContext with the
|
|
5070
5095
|
// SAME absent⇒false default as the deny branch. The previous `!== false`
|
|
@@ -5076,7 +5101,6 @@ async function verify(config, request2, options) {
|
|
|
5076
5101
|
// this load-bearing must never be defaulted on.
|
|
5077
5102
|
identityVerified: apiResponse.verificationContext?.idVerified === true,
|
|
5078
5103
|
policyAllowed: true,
|
|
5079
|
-
accessLevel,
|
|
5080
5104
|
agent,
|
|
5081
5105
|
developer,
|
|
5082
5106
|
organization,
|
|
@@ -5103,7 +5127,6 @@ async function verify(config, request2, options) {
|
|
|
5103
5127
|
};
|
|
5104
5128
|
if (result.recommendation === "deny") {
|
|
5105
5129
|
result.policyAllowed = false;
|
|
5106
|
-
result.accessLevel = "none";
|
|
5107
5130
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Access denied by AstraSync recommendation"];
|
|
5108
5131
|
result.guidance = result.runtimeChallenge ? {
|
|
5109
5132
|
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
@@ -5216,7 +5239,6 @@ function toGatewayConfig(config) {
|
|
|
5216
5239
|
return {
|
|
5217
5240
|
apiBaseUrl: config.apiBaseUrl || "https://api.astrasync.ai",
|
|
5218
5241
|
apiKey: config.apiKey,
|
|
5219
|
-
defaultAccessLevel: config.defaultAccessLevel,
|
|
5220
5242
|
minTrustScore: config.minTrustScore,
|
|
5221
5243
|
minTrustScoreForFull: config.minTrustScoreForFull,
|
|
5222
5244
|
cacheTtl: config.cacheTtl,
|
|
@@ -5244,7 +5266,7 @@ function toDecision(result) {
|
|
|
5244
5266
|
if (result.identityVerified && result.policyAllowed) {
|
|
5245
5267
|
return {
|
|
5246
5268
|
recommendation: "ALLOW",
|
|
5247
|
-
reason: `Verified
|
|
5269
|
+
reason: result.agent?.trustScore ? `Verified (trust score ${result.agent.trustScore})` : "Verified",
|
|
5248
5270
|
trustScore: result.agent?.trustScore,
|
|
5249
5271
|
sessionId: "sessionId" in result ? result.sessionId : void 0
|
|
5250
5272
|
};
|
package/dist/bin/astrasync.js
CHANGED
|
@@ -6,8 +6,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __esm = (fn, res) => function __init() {
|
|
10
|
-
|
|
9
|
+
var __esm = (fn, res, err) => function __init() {
|
|
10
|
+
if (err) throw err[0];
|
|
11
|
+
try {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
13
|
+
} catch (e) {
|
|
14
|
+
throw err = [e], e;
|
|
15
|
+
}
|
|
11
16
|
};
|
|
12
17
|
var __copyProps = (to, from, except, desc) => {
|
|
13
18
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
@@ -31,7 +36,7 @@ var SDK_VERSION;
|
|
|
31
36
|
var init_version = __esm({
|
|
32
37
|
"src/version.ts"() {
|
|
33
38
|
"use strict";
|
|
34
|
-
SDK_VERSION = "
|
|
39
|
+
SDK_VERSION = "5.0.0";
|
|
35
40
|
}
|
|
36
41
|
});
|
|
37
42
|
|
|
@@ -3477,10 +3482,16 @@ function validatePurpose(purpose, path2) {
|
|
|
3477
3482
|
errors.push({ path: `${path2}.targets`, message: "targets must be an array of strings" });
|
|
3478
3483
|
}
|
|
3479
3484
|
if (p.blockedPatterns !== void 0 && !isStringArray(p.blockedPatterns)) {
|
|
3480
|
-
errors.push({
|
|
3485
|
+
errors.push({
|
|
3486
|
+
path: `${path2}.blockedPatterns`,
|
|
3487
|
+
message: "blockedPatterns must be an array of strings"
|
|
3488
|
+
});
|
|
3481
3489
|
}
|
|
3482
3490
|
if (p.requiresApproval !== void 0 && typeof p.requiresApproval !== "boolean") {
|
|
3483
|
-
errors.push({
|
|
3491
|
+
errors.push({
|
|
3492
|
+
path: `${path2}.requiresApproval`,
|
|
3493
|
+
message: "requiresApproval must be a boolean"
|
|
3494
|
+
});
|
|
3484
3495
|
}
|
|
3485
3496
|
return errors;
|
|
3486
3497
|
}
|
|
@@ -3503,11 +3514,29 @@ function validateLimits(limits, path2) {
|
|
|
3503
3514
|
return [{ path: path2, message: "limits must be an object" }];
|
|
3504
3515
|
}
|
|
3505
3516
|
const l = limits;
|
|
3517
|
+
if (l.autonomousThreshold !== void 0 && typeof l.autonomousThreshold !== "number") {
|
|
3518
|
+
errors.push({
|
|
3519
|
+
path: `${path2}.autonomousThreshold`,
|
|
3520
|
+
message: "autonomousThreshold must be a number"
|
|
3521
|
+
});
|
|
3522
|
+
}
|
|
3506
3523
|
if (l.maxTransactionAmount !== void 0 && typeof l.maxTransactionAmount !== "number") {
|
|
3507
|
-
errors.push({
|
|
3524
|
+
errors.push({
|
|
3525
|
+
path: `${path2}.maxTransactionAmount`,
|
|
3526
|
+
message: "maxTransactionAmount must be a number"
|
|
3527
|
+
});
|
|
3528
|
+
}
|
|
3529
|
+
if (typeof l.autonomousThreshold === "number" && typeof l.maxTransactionAmount === "number" && l.autonomousThreshold > l.maxTransactionAmount) {
|
|
3530
|
+
errors.push({
|
|
3531
|
+
path: `${path2}.autonomousThreshold`,
|
|
3532
|
+
message: "autonomousThreshold (Autonomous Limit) must be <= maxTransactionAmount (Hard Limit)"
|
|
3533
|
+
});
|
|
3508
3534
|
}
|
|
3509
3535
|
if (l.maxRequestsPerHour !== void 0 && typeof l.maxRequestsPerHour !== "number") {
|
|
3510
|
-
errors.push({
|
|
3536
|
+
errors.push({
|
|
3537
|
+
path: `${path2}.maxRequestsPerHour`,
|
|
3538
|
+
message: "maxRequestsPerHour must be a number"
|
|
3539
|
+
});
|
|
3511
3540
|
}
|
|
3512
3541
|
if (l.currency !== void 0 && typeof l.currency !== "string") {
|
|
3513
3542
|
errors.push({ path: `${path2}.currency`, message: "currency must be a string" });
|
|
@@ -3522,7 +3551,10 @@ function validateRiskThresholds(thresholds, path2) {
|
|
|
3522
3551
|
const t = thresholds;
|
|
3523
3552
|
for (const range of ["autoAllow", "requireApproval", "autoBlock"]) {
|
|
3524
3553
|
if (!t[range] || typeof t[range] !== "object") {
|
|
3525
|
-
errors.push({
|
|
3554
|
+
errors.push({
|
|
3555
|
+
path: `${path2}.${range}`,
|
|
3556
|
+
message: `${range} is required and must be an object with min and max`
|
|
3557
|
+
});
|
|
3526
3558
|
continue;
|
|
3527
3559
|
}
|
|
3528
3560
|
const r = t[range];
|
|
@@ -4807,9 +4839,9 @@ var init_evaluator = __esm({
|
|
|
4807
4839
|
if (scopeBlock) {
|
|
4808
4840
|
return { recommendation: "DENY", reason: scopeBlock };
|
|
4809
4841
|
}
|
|
4810
|
-
const
|
|
4811
|
-
if (
|
|
4812
|
-
return
|
|
4842
|
+
const limitDecision = this.checkLimits(context);
|
|
4843
|
+
if (limitDecision) {
|
|
4844
|
+
return limitDecision;
|
|
4813
4845
|
}
|
|
4814
4846
|
if (context.purpose === "sub_agent.spawn" && this.policy.selfInstantiation) {
|
|
4815
4847
|
if (!this.policy.selfInstantiation.allowed) {
|
|
@@ -4874,9 +4906,21 @@ var init_evaluator = __esm({
|
|
|
4874
4906
|
checkLimits(context) {
|
|
4875
4907
|
const limits = this.policy.limits;
|
|
4876
4908
|
if (!limits) return null;
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4909
|
+
const value = context.transactionValue;
|
|
4910
|
+
if (value !== void 0 && value > 0 && (limits.autonomousThreshold !== void 0 || limits.maxTransactionAmount !== void 0)) {
|
|
4911
|
+
const autonomousThreshold = limits.autonomousThreshold ?? 0;
|
|
4912
|
+
const hardLimit = limits.maxTransactionAmount ?? limits.autonomousThreshold ?? 0;
|
|
4913
|
+
if (value > autonomousThreshold) {
|
|
4914
|
+
if (value >= hardLimit) {
|
|
4915
|
+
return {
|
|
4916
|
+
recommendation: "DENY",
|
|
4917
|
+
reason: `Transaction value ${value} at or above Hard Limit ${hardLimit}`
|
|
4918
|
+
};
|
|
4919
|
+
}
|
|
4920
|
+
return {
|
|
4921
|
+
recommendation: "MANUAL_REVIEW",
|
|
4922
|
+
reason: `Transaction value ${value} is in the human-approval band (${autonomousThreshold}, ${hardLimit})`
|
|
4923
|
+
};
|
|
4880
4924
|
}
|
|
4881
4925
|
}
|
|
4882
4926
|
if (limits.maxRequestsPerHour !== void 0) {
|
|
@@ -4889,7 +4933,10 @@ var init_evaluator = __esm({
|
|
|
4889
4933
|
} else {
|
|
4890
4934
|
entry.count++;
|
|
4891
4935
|
if (entry.count > limits.maxRequestsPerHour) {
|
|
4892
|
-
return
|
|
4936
|
+
return {
|
|
4937
|
+
recommendation: "DENY",
|
|
4938
|
+
reason: `Rate limit exceeded: ${entry.count}/${limits.maxRequestsPerHour} requests per hour`
|
|
4939
|
+
};
|
|
4893
4940
|
}
|
|
4894
4941
|
}
|
|
4895
4942
|
}
|
|
@@ -5018,15 +5065,15 @@ var init_local = __esm({
|
|
|
5018
5065
|
}
|
|
5019
5066
|
});
|
|
5020
5067
|
|
|
5021
|
-
// src/
|
|
5068
|
+
// src/trust-levels.ts
|
|
5022
5069
|
function getTrustLevel(score) {
|
|
5023
5070
|
if (score >= 80) return "PLATINUM";
|
|
5024
5071
|
if (score >= 60) return "GOLD";
|
|
5025
5072
|
if (score >= 40) return "SILVER";
|
|
5026
5073
|
return "BRONZE";
|
|
5027
5074
|
}
|
|
5028
|
-
var
|
|
5029
|
-
"src/
|
|
5075
|
+
var init_trust_levels = __esm({
|
|
5076
|
+
"src/trust-levels.ts"() {
|
|
5030
5077
|
"use strict";
|
|
5031
5078
|
}
|
|
5032
5079
|
});
|
|
@@ -5195,13 +5242,6 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
5195
5242
|
// policy is not evaluated (we never reached the gate).
|
|
5196
5243
|
identityVerified: false,
|
|
5197
5244
|
policyAllowed: false,
|
|
5198
|
-
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
5199
|
-
// Adapters additionally short-circuit on `!identityVerified ||
|
|
5200
|
-
// !policyAllowed` before the gate check, but the access level still has
|
|
5201
|
-
// to be honest at the data layer so downstream consumers (SDK adapters
|
|
5202
|
-
// in other languages, custom integrations) inherit the correct
|
|
5203
|
-
// semantics.
|
|
5204
|
-
accessLevel: "none",
|
|
5205
5245
|
guidance,
|
|
5206
5246
|
denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
|
|
5207
5247
|
// Round-10 (#47, O5): on API-error fallback, surface a typed failure so
|
|
@@ -5224,6 +5264,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
5224
5264
|
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
5225
5265
|
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
5226
5266
|
...isMisconfig && { misconfigured: true },
|
|
5267
|
+
// 4.6.0: a transient api_error is retryable — mark it so consumers surface
|
|
5268
|
+
// "temporarily unavailable, retry" (recommendation 'error') instead of
|
|
5269
|
+
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
5270
|
+
// deterministic and intentionally NOT marked retryable.
|
|
5271
|
+
...isApiError && { retryable: true },
|
|
5227
5272
|
correlationId: options.correlationId,
|
|
5228
5273
|
attemptId: options.attemptId,
|
|
5229
5274
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -5290,7 +5335,6 @@ async function callVerifyAccessAPI(config, request2) {
|
|
|
5290
5335
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
5291
5336
|
access: {
|
|
5292
5337
|
allowed: false,
|
|
5293
|
-
accessLevel: "none",
|
|
5294
5338
|
reason: "endpoint_deactivated",
|
|
5295
5339
|
failures: [
|
|
5296
5340
|
{
|
|
@@ -5353,7 +5397,7 @@ async function verify(config, request2, options) {
|
|
|
5353
5397
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
5354
5398
|
deprecationWarningShown = true;
|
|
5355
5399
|
console.warn(
|
|
5356
|
-
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access
|
|
5400
|
+
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access decisions (verified ID + runtime challenge + PDLSS + trust score). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
|
|
5357
5401
|
);
|
|
5358
5402
|
}
|
|
5359
5403
|
if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache) {
|
|
@@ -5399,14 +5443,6 @@ async function verify(config, request2, options) {
|
|
|
5399
5443
|
const result2 = {
|
|
5400
5444
|
identityVerified: idVerifiedFromBackend,
|
|
5401
5445
|
policyAllowed: false,
|
|
5402
|
-
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
5403
|
-
// Pre-rename this hardcoded `'guidance'`, which conflated with the
|
|
5404
|
-
// colocated `guidance: {...}` help-payload object below and let
|
|
5405
|
-
// denied requests pass any route gated at `'guidance'` because
|
|
5406
|
-
// `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now
|
|
5407
|
-
// ALSO short-circuit on `!identityVerified || !policyAllowed` before
|
|
5408
|
-
// the gate check — belt-and-braces.
|
|
5409
|
-
accessLevel: "none",
|
|
5410
5446
|
// 3.6.0: the server now emits top-level denialReasons on every deny
|
|
5411
5447
|
// path — prefer it verbatim; the failure-message reconstruction remains
|
|
5412
5448
|
// as the fallback for older backends.
|
|
@@ -5455,7 +5491,6 @@ async function verify(config, request2, options) {
|
|
|
5455
5491
|
trustScore: apiResponse.organization.trustScore
|
|
5456
5492
|
} : void 0;
|
|
5457
5493
|
const verificationContext = apiResponse.verificationContext;
|
|
5458
|
-
const accessLevel = apiResponse.access?.accessLevel ?? "standard";
|
|
5459
5494
|
const result = {
|
|
5460
5495
|
// 4.5.0 (probe F1): read idVerified from verificationContext with the
|
|
5461
5496
|
// SAME absent⇒false default as the deny branch. The previous `!== false`
|
|
@@ -5467,7 +5502,6 @@ async function verify(config, request2, options) {
|
|
|
5467
5502
|
// this load-bearing must never be defaulted on.
|
|
5468
5503
|
identityVerified: apiResponse.verificationContext?.idVerified === true,
|
|
5469
5504
|
policyAllowed: true,
|
|
5470
|
-
accessLevel,
|
|
5471
5505
|
agent,
|
|
5472
5506
|
developer,
|
|
5473
5507
|
organization,
|
|
@@ -5494,7 +5528,6 @@ async function verify(config, request2, options) {
|
|
|
5494
5528
|
};
|
|
5495
5529
|
if (result.recommendation === "deny") {
|
|
5496
5530
|
result.policyAllowed = false;
|
|
5497
|
-
result.accessLevel = "none";
|
|
5498
5531
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Access denied by AstraSync recommendation"];
|
|
5499
5532
|
result.guidance = result.runtimeChallenge ? {
|
|
5500
5533
|
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
@@ -5520,16 +5553,11 @@ var init_verify = __esm({
|
|
|
5520
5553
|
"src/verify.ts"() {
|
|
5521
5554
|
"use strict";
|
|
5522
5555
|
init_http();
|
|
5523
|
-
|
|
5556
|
+
init_trust_levels();
|
|
5524
5557
|
init_version();
|
|
5525
5558
|
init_well_known();
|
|
5526
5559
|
DEFAULT_CONFIG = {
|
|
5527
5560
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
5528
|
-
// v2.3.9 (defect #30): default for unconfigured callers is `'none'` (no
|
|
5529
|
-
// access). Pre-rename this defaulted to `'guidance'`, which combined with
|
|
5530
|
-
// a route gated at `'guidance'` to silently let unverified traffic
|
|
5531
|
-
// through (`hasMinimumAccess('guidance', 'guidance') === true`).
|
|
5532
|
-
defaultAccessLevel: "none",
|
|
5533
5561
|
// minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
|
|
5534
5562
|
// cacheTtl deliberately unset. When undefined, cacheResult applies the 60s
|
|
5535
5563
|
// default; the caller's explicit value is honoured for cacheable results.
|
|
@@ -5726,7 +5754,7 @@ var init_sdk = __esm({
|
|
|
5726
5754
|
"src/adapters/sdk.ts"() {
|
|
5727
5755
|
"use strict";
|
|
5728
5756
|
init_verify();
|
|
5729
|
-
|
|
5757
|
+
init_trust_levels();
|
|
5730
5758
|
}
|
|
5731
5759
|
});
|
|
5732
5760
|
|
|
@@ -6120,7 +6148,7 @@ var init_runtime_signatures = __esm({
|
|
|
6120
6148
|
var init_src = __esm({
|
|
6121
6149
|
"src/index.ts"() {
|
|
6122
6150
|
"use strict";
|
|
6123
|
-
|
|
6151
|
+
init_trust_levels();
|
|
6124
6152
|
init_verify();
|
|
6125
6153
|
init_stepup_poll();
|
|
6126
6154
|
init_settlement();
|
|
@@ -6153,7 +6181,6 @@ function toGatewayConfig(config) {
|
|
|
6153
6181
|
return {
|
|
6154
6182
|
apiBaseUrl: config.apiBaseUrl || "https://api.astrasync.ai",
|
|
6155
6183
|
apiKey: config.apiKey,
|
|
6156
|
-
defaultAccessLevel: config.defaultAccessLevel,
|
|
6157
6184
|
minTrustScore: config.minTrustScore,
|
|
6158
6185
|
minTrustScoreForFull: config.minTrustScoreForFull,
|
|
6159
6186
|
cacheTtl: config.cacheTtl,
|
|
@@ -6181,7 +6208,7 @@ function toDecision(result) {
|
|
|
6181
6208
|
if (result.identityVerified && result.policyAllowed) {
|
|
6182
6209
|
return {
|
|
6183
6210
|
recommendation: "ALLOW",
|
|
6184
|
-
reason: `Verified
|
|
6211
|
+
reason: result.agent?.trustScore ? `Verified (trust score ${result.agent.trustScore})` : "Verified",
|
|
6185
6212
|
trustScore: result.agent?.trustScore,
|
|
6186
6213
|
sessionId: "sessionId" in result ? result.sessionId : void 0
|
|
6187
6214
|
};
|