Approval policies
Recipes for the most common approval shapes used by governed plans.
Single-role approval
Most contract calls only need one approver with a specific role. Bind a PolicySet of type contract:call with a role-derived gate:
- id: allow-admin-call
type: contract:call
defaultEffect: allow
rules:
- match:
actor:
role: admin
effect: allow
- effect: denyN-of-M signed approvals
For larger transfers or governance changes use #[require_approval] on the contract method (Rust SDK) and bind a multi-signature policy:
#[call]
#[require_role("admin")]
#[require_approval(threshold = 2, role = "board_member")]
pub fn large_withdraw(&mut self, amount: U256) -> Result<(), Error> { ... }The ApprovalStore collects signed envelopes and the InvalidationChecker re-verifies the role-derivation chain so a stale derivation can never close the gate.
Separation of duties
For DvP / settlement flows, require the approver role to be disjoint from the actor role:
- id: settlement-sod
type: settlement:reserve
defaultEffect: deny
rules:
- match:
actor:
role: trader
approval:
role: ops-manager
effect: allowTrust-drift gate
Bind TrustResponseOrchestrator to the pipeline so when a referenced TrustProfile degrades the in-flight plan flips to TrustDriftBlocked=true and the executor exits via the canonical Gap 4-C halt.