@metamynd/agentsafe-signer 0.20.0 → 0.20.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/policy-core.mjs +57 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamynd/agentsafe-signer",
3
- "version": "0.20.0",
3
+ "version": "0.20.1",
4
4
  "description": "Local signer daemon for AgentSafe agent/service keys \u2014 the key never enters the calling guard's own process. See docs/design/agent-key-custody-local-signer-daemon-plan.md.",
5
5
  "type": "module",
6
6
  "main": "./daemon.mjs",
package/policy-core.mjs CHANGED
@@ -43,6 +43,57 @@ function riskFloorFor(mandate, target) {
43
43
  }
44
44
  return floor;
45
45
  }
46
+ var DEFAULT_AMOUNT_SHARE_HIGH = 0.7;
47
+ function grantsFor(mandate, target) {
48
+ return (mandate?.permission ?? []).filter((p) => !!p && typeof p === "object" && (p.target ?? mandate?.target) === target);
49
+ }
50
+ function perTxnCapFor(mandate, target) {
51
+ let cap = null;
52
+ for (const p of grantsFor(mandate, target)) {
53
+ for (const c of p.constraint ?? []) {
54
+ if (c?.leftOperand !== "mm:payAmount") continue;
55
+ const n = Number(c.rightOperand);
56
+ if (Number.isFinite(n) && n > 0 && (cap === null || n < cap)) cap = n;
57
+ }
58
+ }
59
+ return cap;
60
+ }
61
+ function hasMerchantAllowList(mandate, target) {
62
+ return grantsFor(mandate, target).some((p) => (p.constraint ?? []).some((c) => c?.leftOperand === "mm:merchant"));
63
+ }
64
+ function riskSignalSettings(mandate, target) {
65
+ const grants = grantsFor(mandate, target);
66
+ if (grants.length === 0) return { amountShare: DEFAULT_AMOUNT_SHARE_HIGH, newMerchant: true };
67
+ let amountShare = null;
68
+ let newMerchant = false;
69
+ for (const p of grants) {
70
+ const s = p.riskSignals;
71
+ if (s === false) continue;
72
+ const cfg = s && typeof s === "object" ? s : {};
73
+ const share = cfg.amountShare === false ? null : cfg.amountShare === void 0 ? DEFAULT_AMOUNT_SHARE_HIGH : Number(cfg.amountShare);
74
+ if (share !== null && Number.isFinite(share) && share > 0 && share <= 1 && (amountShare === null || share < amountShare)) amountShare = share;
75
+ if (cfg.newMerchant !== false) newMerchant = true;
76
+ }
77
+ return { amountShare, newMerchant };
78
+ }
79
+ function riskSignalsFor(mandate, target, amount, opts = {}) {
80
+ const out = [];
81
+ const tier = riskFloorFor(mandate, target);
82
+ if (tier) out.push({ signal: "owner-tier", level: tier, detail: `the owner's risk tier for ${target}` });
83
+ const settings = riskSignalSettings(mandate, target);
84
+ const n = typeof amount === "number" ? amount : Number(amount);
85
+ const cap = perTxnCapFor(mandate, target);
86
+ if (settings.amountShare !== null && cap !== null && Number.isFinite(n) && n > 0 && n >= settings.amountShare * cap) {
87
+ out.push({ signal: "amount-share", level: "high", detail: `${Math.round(n / cap * 100)}% of the ${cap} per-transaction cap (review from ${Math.round(settings.amountShare * 100)}%)` });
88
+ }
89
+ if (opts.newMerchant === true && settings.newMerchant && !hasMerchantAllowList(mandate, target)) {
90
+ out.push({ signal: "new-merchant", level: "high", detail: "the first payment to this merchant" });
91
+ }
92
+ return out;
93
+ }
94
+ function effectiveRiskFloor(mandate, target, amount, opts = {}) {
95
+ return maxRisk(...riskSignalsFor(mandate, target, amount, opts).map((s) => s.level));
96
+ }
46
97
  function requiresPayloadBindingFor(mandate, target) {
47
98
  if (!mandate) return false;
48
99
  for (const p of mandate.permission ?? []) {
@@ -793,6 +844,7 @@ export {
793
844
  AUTH_MESSAGE_V2_TAG,
794
845
  CATALOGUED_ATOMS,
795
846
  CONTEXT_UNVERIFIABLE,
847
+ DEFAULT_AMOUNT_SHARE_HIGH,
796
848
  JURISDICTION_ATOM,
797
849
  MODES_BY_RANK,
798
850
  MODE_RANK,
@@ -815,10 +867,12 @@ export {
815
867
  canAuthorize,
816
868
  contextFieldProblem,
817
869
  documentEnforcesJurisdiction,
870
+ effectiveRiskFloor,
818
871
  evaluate,
819
872
  evaluateBoundStandards,
820
873
  evaluateMandate,
821
874
  evaluateStandardRules,
875
+ hasMerchantAllowList,
822
876
  isAuthorityFailure,
823
877
  isOperatingMode,
824
878
  isProvenance,
@@ -829,6 +883,7 @@ export {
829
883
  moreRestrictive,
830
884
  normalizeRiskLevel,
831
885
  operatingModeGate,
886
+ perTxnCapFor,
832
887
  provenanceOf,
833
888
  releaseHold,
834
889
  remainingBudget,
@@ -836,6 +891,8 @@ export {
836
891
  requiredContextOf,
837
892
  requiresPayloadBindingFor,
838
893
  riskFloorFor,
894
+ riskSignalSettings,
895
+ riskSignalsFor,
839
896
  sumEventField,
840
897
  validateMolecules
841
898
  };