ArmorPay Concepts

How ArmorPay bundle templates compile to a standard ArmorIQ policy document, and how amount, velocity, recipient, and transaction-type rules resolve at enforcement time.

ArmorPay is a specialized editor and template layer over ArmorIQ's normal policy engine, not a separate enforcement system. Everything you configure in the Policy Studio - member roles, thresholds, velocity caps, recipient rules - compiles down to one document type: kind: Policy, apiVersion: armor.io/v1.

ArmorPay does not use a distinct FinancialPolicy kind on the backend. The Policy Studio's guided sections are a friendlier editor for the same Policy document every ArmorIQ product targets an agent or MCP server with.

Shape of a compiled policy

apiVersion: armor.io/v1
kind: Policy
metadata:
  name: standard-ap-controls
  orgId: "<your-org-id>"
  targetType: agent
  targetId: "<ap-agent-id>"
spec:
  priority: 100
  status: active
  defaultEnforcementAction: allow_log
  memberRules:
    "*":
      allowedTools: [create_invoice, record_payment, list_customers]
      enforcementAction: allow_log
      amountThreshold:
        maxPerTransaction: 10000
        requireApprovalAbove: 5000
        currency: USD
      velocityLimit:
        maxTransactionsPerHour: 200
        maxCumulativePerDay: 50000
        currency: USD
      recipientValidation:
        approvedVendors: []
        blockPersonalAccounts: true
        blockNewRecipients: false
      transactionTypeControl:
        allowedTypes: [invoice, payment]
        blockedTypes: [wire_transfer]
        readOnlyCategories: [balance]

memberRules is keyed by member email for per-person rules, or "*" for a rule that applies to everyone the policy targets. Assigning a member to a role (Finance, AP, Payroll, Accountant, Finance Manager, CFO) in the Member Roles section is what creates a per-email entry instead of relying on the wildcard.

Domain-specific fields

FieldLives underWhat it controls
allowedToolsmemberRules.<key>Which tools this member/role can call at all
toolEnforcementmemberRules.<key>Per-tool override of the enforcement action (see resolution order below)
amountThresholdmemberRules.<key>maxPerTransaction, requireApprovalAbove, currency
velocityLimitmemberRules.<key>maxTransactionsPerHour, maxCumulativePerDay, currency
recipientValidationmemberRules.<key>approvedVendors, blockPersonalAccounts, blockNewRecipients
transactionTypeControlmemberRules.<key>allowedTypes, blockedTypes, readOnlyCategories
multiPartyApprovalmemberRules.<key>requiredApprovers, approverRoles, channels for the approval workflow on held actions

These map directly to the Policy Studio's Amount Threshold, Velocity Limit, Recipient Validation, and Transaction Types sections - the form is a view over these YAML fields, not a separate model.

Enforcement resolution order

For every tool call, ArmorIQ resolves the enforcement action in this order, and the first match wins:

  1. toolEnforcement[toolName] on the matched member rule
  2. rule.enforcementAction on the matched member rule
  3. policy.spec.defaultEnforcementAction
  4. block (fail-closed default when nothing else matches)

amountThreshold and velocityLimit don't set the enforcement action directly - they're inputs a policy author uses to decide what action to attach (for example, "hold anything over $5,000" means setting requireApprovalAbove: 5000 and enforcementAction: hold together).

Enforcement actions

ActionEffect
allowCall proceeds, no log emphasis
allow_logCall proceeds, logged for audit
holdCall is paused pending a delegation/approval decision
blockCall is refused
denyCall is refused (equivalent outcome to block at the SDK boundary)
alertCall proceeds, and an alert is raised
quarantineCall's output is isolated pending review rather than returned directly

From bundle template to active policy

Applying a bundle template from the Dashboard does three things:

  1. Deactivates any existing active policy on that agent (a clean slate - ArmorPay does not layer partial bundles).
  2. Imports the bundle's YAML via upsert-by-name.
  3. Activates the resulting policy immediately - the next SDK call from that agent is evaluated against it.

Customizing a bundle in the Policy Studio edits the same document before deploy; nothing about the compiled YAML changes shape based on whether it started from a template or a blank policy.

How this reaches the agent at runtime

The policy above is only enforced once the agent actually calls through the SDK. See Getting Started for wiring an AP, Finance, or Payroll agent's invokeWithPolicy() call, and Observability for where the resulting decisions show up.

On this page