When to use this
- Compliance checks: screen transactions against sanctions lists or internal rules before they execute
- Spending controls: auto-approve transactions that meet your business rules, escalate the rest
- Speed: remove human bottlenecks for routine operations while keeping oversight on exceptions
How it works
The service account never rejects. If it can’t approve, it abstains and lets a human decide. This works because the approval group includes both the service account and human approvers with a quorum of 1: whoever approves first satisfies the requirement.What you’ll need
- A service account with permissions to read approvals and submit decisions
serviceAccountsCanApproveenabled on your organization (contact Dfns support)- A webhook endpoint to receive
policy.approval.pendingevents - Understanding of policies and approval groups
Components to configure
1. Policy with service account approver
Create a policy where the approval group includes your service account alongside human fallbacks. SetserviceAccountsCanApprove: true on the group.
The key design choice: a 1-of-N quorum where N includes both the service account and human approvers. The service account processes the approval first. If it approves, the quorum is met instantly. If it can’t, humans in the same group can still approve.
See the developer guide for the full policy creation code.
2. Webhook listener
Configure a webhook forpolicy.approval.pending events. When the event fires, the service account:
- Fetches the approval details
- Runs your business logic against the transaction
- Approves if the checks pass, or notifies a human if they don’t
3. Human escalation path
When the service account can’t approve, it alerts a human approver through your internal channels (Slack, email, PagerDuty). The human then reviews and submits their decision through the dashboard or API.Example: transaction compliance review
A financial services company wants automated compliance screening on outbound transfers above $5,000, with human review as fallback.Setup
| Component | Configuration |
|---|---|
| Service account | compliance-bot, permissions: PolicyApprovals:Read, PolicyApprovals:Approve |
| Policy rule | TransactionAmountLimit, $5,000 USD |
| Approval group | 1-of-3 quorum: compliance-bot + 2 compliance officers, serviceAccountsCanApprove: true |
| Webhook | policy.approval.pending to compliance service |
Flow
User initiates a transfer
An operator sends a $15,000 USDC transfer from the treasury wallet. The policy engine evaluates the transaction against active policies.
Policy triggers approval
The transaction exceeds the $5,000 threshold. Dfns creates a pending approval and fires a
policy.approval.pending webhook to the compliance service.Service account evaluates
The compliance service receives the webhook, fetches the approval details, and runs its checks:
- Recipient address against sanctions lists
- Transaction amount against internal daily limits
- Destination chain risk score
Decision
If all checks pass: the service account approves the transaction. Quorum is met (1-of-3), and the transfer executes immediately.If any check fails or is inconclusive: the service account does not submit a decision. Instead, it sends a Slack message to the compliance team with the flagged details. A compliance officer reviews the transaction in the Dfns dashboard and approves or rejects.
Accountability
Every approval is signed by the entity that submitted it, whether that’s the service account or a human. The audit log shows exactly who approved what and when, providing full non-repudiation for compliance reporting.Design considerations
Never reject from automation
A service account rejection is final and irrevocable. It denies the entire approval with no override. Design your service to either approve or abstain. When in doubt, escalate to a human.Separate automation from initiation
Don’t use the same service account to both initiate transactions and approve them. The policy engine prevents self-approval by default (initiatorCanApprove is false), but keeping these roles separate is a stronger security posture.
Monitor your automation
Track approval latency, escalation rates, and false positives. If the service account escalates too often, your automated rules may be too strict. If it never escalates, the checks may not be thorough enough.Related
Managing policies via API
Implementation code for automated approvals
Treasury policies
Spending limits and approval quorums
Compliance
KYT/AML screening integration
Automated payments
Service account payout workflows
