Policy Engine

Codify your rules. Enforce them cryptographically.

Approval quorums, velocity caps, allowlists, KYT integration — the rule engine that runs your treasury, your transactions, your token operations. Configured visually. Enforced by MPC. Audited by default.

Policy Engine dashboard
Rules, in code

TransactionAmountLimit. TransactionVelocity. RecipientWhitelist. AlwaysTrigger. KYT. Composable primitives, version-controlled like any other infrastructure.

Approvals that scale

M-of-N quorums. Multiple groups required. Service accounts in the mix. Compliance signs off without anyone leaving the dashboard.

Enforcement by cryptography

MPC-backed signing. No policy bypass, no shadow approvers, no exceptions hidden in code. Rules apply to every wallet, every transaction, every chain.

KYT and Travel Rule built in

Chainalysis, Global Ledger, Notabene — first-class rule conditions. Block, freeze, or escalate on red flags, not after.


Policies are the new approval matrix

Run your governance the way you run your code — versioned, scoped, tested, enforced everywhere.

Rules

Pre-built conditions
for every governance need

Amount limits in USD. Velocity caps over time windows. Recipient allowlists. KYT screening. Travel Rule. Compose them. Layer them. Apply them to every wallet, every chain.

Limits & velocity

Single-transaction caps, hourly velocity, daily caps, frequency limits. Set in USD, evaluated in real time, applied per-wallet or per-tag.

Allowlists

Restrict transfers to known counterparties. Maintain the address book centrally. Non-whitelisted recipients require approval or get blocked outright.

Compliance screening

Chainalysis KYT, Global Ledger KYT, Notabene Travel Rule — first-class rule kinds. Red flags trigger policies, not support tickets.

Wallets dashboard
Actions

Block, or require approval
— your call

When a rule triggers, the platform either blocks the action outright or holds it until enough approvers sign off. Block on certainty. Approve on judgment. Audit either way.

Approval quorums

M-of-N from any group. Name specific users or wildcard the role. Set auto-reject timeouts. Capture rejection reasons.

Multi-group approval

Compliance signs off AND treasury signs off. Each group has its own quorum. The transaction only proceeds when every group reaches its threshold.

Service account approvers

Machine identities in the approval group. Service accounts handle the routine cases programmatically. Humans handle the exceptions. The four-eyes principle, encoded.

Wallets dashboard
Scope

Policies target exactly
what they should

Apply by wallet, wallet tag, or activity kind. Different rules for hot, warm, and cold wallets. Different rules for treasury vs operations. Different rules for token issuance vs settlement.

Wallet tags

Tag wallets by entity, function, risk band. Target policies by tag. Hot wallets get tight caps. Treasury wallets get full quorum approval. One engine, many regimes.

Activity kinds

Policies apply to Wallets:Sign, but also to permission grants, policy modifications, credential rotations. Foundation policies protect the configuration itself.

Filters and exclusions

Untagged wallets bypass tagged-only policies. Automated wallets stay automated. Human-controlled wallets stay supervised. Same engine, different scopes.

Wallets dashboard
Enforcement

Cryptographic guarantees,
not optimistic guardrails

Every policy evaluation runs inside the MPC signing path. No “we forgot to check.” No “the admin overrode it.” Either the policy passes, or the signature doesn’t happen.

No bypass

Policies are enforced at the signing layer, not the application layer. Even DFNS staff can't override an active policy on your wallets.

All policies, all evaluated

Every matching policy runs. Any Block blocks. Every RequestApproval collects approvals. No order-dependent gotchas, no policy precedence games.

Audit by construction

Every triggered policy, every approval, every decision is signed and timestamped. The audit trail isn't generated after the fact — it's what actually happened.

Wallets dashboard

Discover how Zodia Custody governs on DFNS.

“Thanks to their collaborative team and institutional-grade wallet platform, we've enhanced our operational capabilities and widened our business lines. Our security framework has also been reinforced by their state-of-the-art MPC cryptography.”

Rules, in code

TransactionAmountLimit. TransactionVelocity. RecipientWhitelist. AlwaysTrigger. KYT. Composable primitives, version-controlled like any other infrastructure.

Approvals that scale

M-of-N quorums. Multiple groups required. Service accounts in the mix. Compliance signs off without anyone leaving the dashboard.

Enforcement by cryptography

MPC-backed signing. No policy bypass, no shadow approvers, no exceptions hidden in code. Rules apply to every wallet, every transaction, every chain.

KYT and Travel Rule built in

Chainalysis, Global Ledger, Notabene — first-class rule conditions. Block, freeze, or escalate on red flags, not after.

Thierry Janaudy CTO, Zodia Custody

Four steps to a policy that holds up

Define the rule. Set the scope. Wire the approvers. Watch it enforce. The same engine, whether the rule comes from compliance, treasury, or risk.

Pick a rule. Set a threshold.

Choose from pre-built rule kinds. Set the amount, the velocity, the allowlist. No DSL. No custom parsing. The rule definition is the source of truth.

// Trigger approval when a single transaction exceeds $100,000
const rule = {
  kind: "TransactionAmountLimit",
  configuration: { limit: "100000", currency: "USD" }
};

// Or velocity-based: cap outflows at $500k per 24-hour window
const velocityRule = {
  kind: "TransactionAmountVelocity",
  configuration: { limit: "500000", currency: "USD", timeframeSeconds: 86400 }
};

// Or KYT-based: block transactions flagged Severe by Chainalysis
const kytRule = {
  kind: "ChainalysisTransactionPrescreening",
  configuration: { riskScore: "Severe" }
};
Stack rules. A single wallet can have an amount cap, a velocity cap, AND a KYT screen — they're additive. Any one of them triggers the action. Layered rules, defense in depth.

Target exactly what the rule applies to.

Wallet tags, wallet IDs, activity kinds. Apply broadly, narrow precisely. Hot wallets get one policy. Treasury wallets get another. Issuance wallets get a third.

// Scope to wallets tagged 'treasury' OR 'cold-storage'
const filters = {
  walletTags: { hasAny: ["treasury", "cold-storage"] }
};

// Or by activity kind — protect the policy configuration itself
// 'Policies:Modify' requires approval from the Risk Committee
const metaPolicy = {
  name: "Policy Modification Protection",
  activityKind: "Policies:Modify",
  rule: { kind: "AlwaysTrigger" },
  action: {
    kind: "RequestApproval",
    approvalGroups: [{
      name: "Risk Committee",
      quorum: 3,
      approvers: { userId: { in: [/* 5 risk officers */] } }
    }]
  }
};
Always protect your policy configuration with a meta-policy. Policy modifications themselves should require approval — otherwise the rule is only as strong as the least-trusted admin.

Configure the approval matrix.

One quorum or two. One group or two. Service accounts can vote alongside humans. Initiators can't approve their own transactions. The four-eyes principle, encoded in JSON.

// Two-group approval: compliance signs off AND treasury signs off
const action = {
  kind: "RequestApproval",
  approvalGroups: [
    {
      name: "Compliance",
      quorum: 1,
      approvers: { userId: { in: ["us-compliance-1", "us-compliance-2", "us-compliance-3"] } }
    },
    {
      name: "Treasury Council",
      quorum: 2,
      approvers: { userId: { in: ["us-treasurer-1", "us-treasurer-2", "us-treasurer-3"] } }
    }
  ],
  autoRejectTimeout: 86400,        // auto-reject after 24h
  initiatorCanApprove: false       // four-eyes principle enforced
};
Use multi-group approval for high-risk actions. Compliance and treasury aren't the same function — both should sign off independently. Keep initiatorCanApprove: false unless you have an explicit reason otherwise.

Activate. Watch. Audit.

Activate the policy. Every matching action runs through it. Every triggered approval is signed and stored. Every decision queryable forever.

const policy = await dfnsApi.policies.createPolicy({
  body: {
    name: "Large Transfer Approval",
    activityKind: "Wallets:Sign",
    rule, action, filters,
    status: "Active"
  }
});

// Subscribe to policy events for live dashboards and alerting
await dfnsApi.webhooks.createWebhook({
  body: {
    url: "https://risk.yourbank.com/dfns/policies",
    events: [
      "policy.approval.pending",
      "policy.approval.resolved",
      "policy.triggered.block"
    ]
  }
});

// Pull the audit trail anytime
const decisions = await dfnsApi.policies.listApprovalDecisions({
  query: { policyId: policy.id, dateFrom: "2026-05-01" }
});
Watch the metrics. Approval latency, escalation rate, block rate. If a policy never triggers, the threshold may be too loose. If it always triggers, the threshold may be too tight. Tune like any other production system.
Org → Policies → New Policy → Rule Type → Configure
Org → Policies → New Policy → Rule Type → Configure
New Policy → Filters → Wallet Tags / Activity Kind
New Policy → Filters → Wallet Tags / Activity Kind
New Policy → Approval Matrix Builder → Add Group → Quorum + Members
New Policy → Approval Matrix Builder → Add Group → Quorum + Members
Org → Policies → Active Policies → Decisions Log
Org → Policies → Active Policies → Decisions Log

Ready to see DFNS in action?

The new core for every fintech and institution going onchain.

Documentation

APIs, SDKs, and guides for builders.

Pricing

Per-transaction pricing, no hidden fees.

Contact us