Skip to main content
Service accounts can act as automated approvers in policy workflows. A user initiates a transaction, the policy engine flags it for approval, and a service account evaluates it: routine requests are approved instantly, exceptions are escalated to humans. Every decision is cryptographically signed, maintaining full non-repudiation regardless of who approves.

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
  • serviceAccountsCanApprove enabled on your organization (contact Dfns support)
  • A webhook endpoint to receive policy.approval.pending events
  • 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. Set serviceAccountsCanApprove: 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 for policy.approval.pending events. When the event fires, the service account:
  1. Fetches the approval details
  2. Runs your business logic against the transaction
  3. Approves if the checks pass, or notifies a human if they don’t
See the developer guide for the webhook handler implementation.

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

ComponentConfiguration
Service accountcompliance-bot, permissions: PolicyApprovals:Read, PolicyApprovals:Approve
Policy ruleTransactionAmountLimit, $5,000 USD
Approval group1-of-3 quorum: compliance-bot + 2 compliance officers, serviceAccountsCanApprove: true
Webhookpolicy.approval.pending to compliance service

Flow

1

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.
2

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.
3

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
4

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.

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
Last modified on March 26, 2026