Skip to main content

Overview

The Financial pack provides critical guardrails for AI agents that handle payments, wire transfers, or any financial operations. It enforces transaction limits, currency restrictions, and cumulative spending caps to prevent unauthorized or excessive money movement. Use this pack for:
  • Payment processing agents
  • Banking automation tools
  • Invoice payment systems
  • Treasury management agents
  • Expense approval workflows

Complete Policy

financial.yaml
version: "1.0"
name: financial-pack
description: Guardrails for payment and transfer operations.
rules:
  - id: financial-transfer-limit-per-transaction
    name: Enforce per-transaction transfer limit
    description: Require approval for transactions above the configured threshold.
    enabled: true
    severity: high
    action: require_approval
    tools:
      - transfer_funds
      - wire_transfer
      - send_money
    conditions:
      - field: arguments.amount
        operator: greater_than
        value: 10000

  - id: financial-currency-allowlist
    name: Restrict transfer currencies
    description: Block unsupported transfer currencies.
    enabled: true
    severity: high
    action: block
    tools:
      - transfer_funds
      - wire_transfer
      - send_money
    conditions:
      - field: arguments.currency
        operator: not_in
        value:
          - USD
          - EUR
          - GBP

  - id: financial-cumulative-transfer-cap
    name: Enforce cumulative transfer cap
    description: Require approval after a high-value transfer in the same session window.
    enabled: true
    severity: critical
    action: require_approval
    tools:
      - transfer_funds
      - wire_transfer
      - send_money
    blocked_by:
      - tool: transfer_funds
        within: 86400
        conditions:
          - field: arguments.amount
            operator: greater_than
            value: 5000
      - tool: wire_transfer
        within: 86400
        conditions:
          - field: arguments.amount
            operator: greater_than
            value: 5000
      - tool: send_money
        within: 86400
        conditions:
          - field: arguments.amount
            operator: greater_than
            value: 5000

Rules Explained

1. Per-Transaction Transfer Limit

Rule ID: financial-transfer-limit-per-transaction What it does: Requires human approval for any single transaction over $10,000. Why it’s important: Large individual transactions represent significant financial risk. Even if an AI agent is authorized to make payments, transactions above a threshold should be reviewed by a human to prevent:
  • Incorrect payment amounts (misinterpreted instructions)
  • Unauthorized recipient changes
  • Duplicate payment errors
  • Social engineering attacks on the AI
Example:
// This requires human approval:
await transferFunds({ 
  amount: 15000, 
  currency: "USD",
  recipient: "[email protected]" 
});

// User sees: "Approve transfer of $15,000 USD to [email protected]?"
Customizing the threshold:
rules:
  - id: financial-transfer-limit-per-transaction
    conditions:
      - field: arguments.amount
        operator: greater_than
        value: 50000  # Raise threshold to $50k

2. Currency Allowlist

Rule ID: financial-currency-allowlist What it does: Blocks transfers in currencies other than USD, EUR, and GBP. Why it’s important:
  • Prevents accidental transfers in wrong currencies
  • Reduces risk of currency conversion errors
  • Blocks potential money laundering through obscure currencies
  • Ensures compliance with your organization’s supported payment methods
Example blocked call:
// This is blocked:
await transferFunds({ 
  amount: 5000, 
  currency: "BTC",  // Cryptocurrency not in allowlist
  recipient: "wallet-address" 
});
// Error: Unsupported currency BTC
Adding more currencies:
rules:
  - id: financial-currency-allowlist
    conditions:
      - field: arguments.currency
        operator: not_in
        value:
          - USD
          - EUR
          - GBP
          - JPY  # Add Japanese Yen
          - CAD  # Add Canadian Dollar

3. Cumulative Transfer Cap

Rule ID: financial-cumulative-transfer-cap What it does: Requires approval for additional transfers after a high-value transfer ($5,000+) within a 24-hour window. Why it’s important: An AI agent might be compromised or misused to drain accounts via multiple smaller transactions. This rule detects unusual spending velocity. How it works:
  • First transfer of $6,000: Allowed (if under per-transaction limit)
  • Second transfer attempt (same day): Requires approval
  • Window resets after 86,400 seconds (24 hours)
Example scenario:
// 10:00 AM - First transfer succeeds
await transferFunds({ amount: 6000, currency: "USD", recipient: "A" });
// ✓ Allowed

// 2:00 PM - Second transfer requires approval
await transferFunds({ amount: 3000, currency: "USD", recipient: "B" });
// ⏳ Requires approval (cumulative cap triggered)

// Next day at 10:01 AM - Window reset, allowed again
await transferFunds({ amount: 6000, currency: "USD", recipient: "C" });
// ✓ Allowed (new 24-hour window)
Adjusting the window:
rules:
  - id: financial-cumulative-transfer-cap
    blocked_by:
      - tool: transfer_funds
        within: 3600  # 1 hour instead of 24 hours
        conditions:
          - field: arguments.amount
            operator: greater_than
            value: 5000

Usage Example

Basic Setup

veto.config.yaml
version: "1.0"
extends: "@veto/financial"

mode: "strict"

# Configure approval workflow
approval:
  callbackUrl: "https://your-approval-service.com/approve"
  timeout: 60000  # 60 seconds
  timeoutBehavior: "block"  # Block if no response

With TypeScript SDK

import { Veto } from 'veto-sdk';

const veto = await Veto.init();

const financialTools = [
  {
    name: 'transfer_funds',
    description: 'Transfer money to a recipient',
    handler: async ({ amount, currency, recipient }: {
      amount: number;
      currency: string;
      recipient: string;
    }) => {
      // Call your payment API
      const result = await paymentAPI.transfer({ amount, currency, recipient });
      return { transactionId: result.id, status: 'completed' };
    },
  },
];

const wrappedTools = veto.wrap(financialTools);

// Use with your AI agent
// Large transfers automatically trigger approval flow

Customization

Different Limits by Recipient Type

Allow higher limits for verified vendors:
rules:
  # Override default limit for verified vendors
  - id: financial-transfer-verified-vendor-limit
    name: Higher limit for verified vendors
    action: require_approval
    tools:
      - transfer_funds
    conditions:
      - field: arguments.amount
        operator: greater_than
        value: 50000
      - field: arguments.recipient_type
        operator: equals
        value: "verified_vendor"
  
  # Keep original limit for others
  - id: financial-transfer-limit-per-transaction
    enabled: true

Block International Transfers

Add geographic restrictions:
rules:
  - id: custom-block-international-transfers
    name: Block international wire transfers
    action: block
    severity: critical
    tools:
      - wire_transfer
    conditions:
      - field: arguments.recipient_country
        operator: not_equals
        value: "US"

Require Approval for All Transfers

Maximum security mode - approve every transaction:
rules:
  - id: financial-approve-all-transfers
    name: Approve all financial transfers
    action: require_approval
    severity: critical
    tools:
      - transfer_funds
      - wire_transfer
      - send_money
    # No conditions = applies to ALL calls

Add Refund Protection

Prevent unauthorized refunds:
rules:
  - id: custom-restrict-refunds
    name: Require approval for refunds over $100
    action: require_approval
    severity: high
    tools:
      - issue_refund
      - process_refund
    conditions:
      - field: arguments.amount
        operator: greater_than
        value: 100

Human-in-the-Loop Setup

To handle approval requests, you need an approval callback service:
approval-service.ts
import express from 'express';

const app = express();

app.post('/approve', async (req, res) => {
  const { toolName, arguments: args, requestId } = req.body;
  
  // Send approval request to Slack/email/dashboard
  await notifyApprovers({
    message: `Approve ${toolName}?`,
    amount: args.amount,
    currency: args.currency,
    recipient: args.recipient,
    approveUrl: `https://dashboard.example.com/approve/${requestId}`,
  });
  
  // Return pending status
  res.json({ status: 'pending' });
});

app.listen(8787);
See the Human-in-the-Loop guide for complete setup instructions.

Testing

Test your financial rules before deploying:
# Test a large transfer
npx veto-cli guard check \
  --tool transfer_funds \
  --args '{"amount": 15000, "currency": "USD", "recipient": "[email protected]"}' \
  --json

# Output:
# {
#   "action": "require_approval",
#   "rule": "financial-transfer-limit-per-transaction",
#   "reason": "Transaction amount exceeds $10,000 limit"
# }

# Test blocked currency
npx veto-cli guard check \
  --tool transfer_funds \
  --args '{"amount": 5000, "currency": "BTC"}' \
  --json

# Output:
# {
#   "action": "deny",
#   "rule": "financial-currency-allowlist",
#   "reason": "Currency BTC not in allowlist"
# }

Compliance Considerations

This policy pack provides technical guardrails, not legal compliance. For production financial systems, you must:
  • Implement proper audit logging (all transactions)
  • Store approval records for regulatory review
  • Follow PCI DSS standards for payment data
  • Comply with regional regulations (GDPR, SOC 2, etc.)
  • Implement fraud detection beyond these rules

Policy Pack Overview

Learn about all available policy packs

Human-in-the-Loop Guide

Set up approval workflows for sensitive operations

Data Access Pack

Additional protection for customer financial data

Budget Tracking

Monitor and cap total agent spending

Build docs developers (and LLMs) love