Agent Payment Authorization

Your AI agent just paid $47,000 for cloud compute. The purchase was within its delegated authority — “procure infrastructure as needed” — and the vendor invoice was legitimate. The problem: the agent interpreted “as needed” as reserving 18 months of capacity in a single transaction, draining the department’s quarterly budget in 11 seconds. The API key had permission to spend. Nothing in your authorization layer distinguished between a $200 spot instance and a $47,000 committed-use reservation. The ledger recorded it correctly. The authorization system approved it correctly. The constraints were wrong.

Agent payment authorization is not access control. Access control answers “can this identity call this endpoint?” Authorization answers “given this agent’s delegation scope, spending constraints, and the current state of the ledger, should this specific transaction proceed right now?”

The Delegation Problem

Human-to-human delegation is informal and context-rich. “Buy what you need for the project” carries implicit constraints — reasonable amounts, relevant categories, within budget. An agent receives none of that context. It receives an API key and whatever constraints you encode explicitly.

A delegation scope must specify at minimum:

{
  "agent_id": "procurement-agent-7a2f",
  "principal": "eng-director@company.com",
  "constraints": {
    "max_per_transaction": 5000,
    "max_daily_aggregate": 25000,
    "allowed_categories": ["cloud_compute", "dev_tools", "saas"],
    "allowed_counterparties": ["aws", "gcp", "azure", "github"],
    "requires_approval_above": 10000,
    "expires_at": "2026-12-31T23:59:59Z"
  }
}

Every field that is absent is a field the agent will interpret as unconstrained. An agent operating under a delegation with no max_per_transaction can spend the entire balance in one call. An agent with no allowed_categories can pay for anything. The delegation scope is not a suggestion — it is the complete boundary of the agent’s financial authority.

Delegation scopes must be explicit and complete. An implicit constraint — one that a human would “just know” — does not exist for an agent. If the constraint is not encoded, the agent does not have it.

Conditional Balance Checks

A traditional balance check is binary: does the account have sufficient funds? Agent authorization requires conditional balance checks — the balance is sufficient and the transaction satisfies the delegation constraints.

Fragment implements this with Conditions — programmable rules evaluated at transaction time, inside the same database transaction as the ledger write. A Condition can enforce:

Condition type What it checks Example
Balance floor Account balance after this entry must exceed a minimum Operating account stays above $10,000 reserve
Velocity limit Aggregate spend within a time window must not exceed a cap No more than $25,000 in rolling 24 hours
Per-entry cap Individual transaction amount must not exceed a threshold Single purchase under $5,000
Counterparty whitelist Destination account must be in an approved set Payments only to pre-approved vendors

The critical design decision: Conditions evaluate inside the transaction boundary. The balance check, the constraint evaluation, and the entry write are atomic. There is no window between “check passed” and “entry posted” where a concurrent transaction could invalidate the check.

// Fragment Condition — pseudocode
condition: {
  type: "balance_floor",
  account: "operating-budget-q4",
  minimum: 10000,
  currency: "USD"
}

If the Condition fails, the entire transaction rolls back. The entry is never posted. The balance never changes. The agent receives a rejection with the specific Condition that failed — not a generic “insufficient funds” error, but “velocity limit exceeded: $27,400 of $25,000 daily cap consumed.”

This specificity matters for agent behavior. A generic rejection triggers a retry loop. A specific rejection tells the agent why it was rejected and enables it to adjust — wait until the velocity window resets, choose a smaller amount, or escalate to a human.

The x402 Protocol

x402 brings payment authorization into the HTTP layer. Instead of pre-provisioning API keys with payment credentials, the server responds to an unauthorized request with a 402 Payment Required status and a machine-readable payment specification.

The flow:

Agent → Server: GET /api/expensive-resource
Server → Agent: 402 Payment Required
  {
    "accepts": ["exact"],
    "maxAmountRequired": "1000000",
    "currency": "USDC",
    "network": "base",
    "payTo": "0x1234...abcd",
    "resource": "/api/expensive-resource"
  }

Agent → Server: GET /api/expensive-resource
  X-PAYMENT: <signed EVM transaction>
Server → Agent: 200 OK (settles payment, returns resource)

The agent decides whether to pay based on its delegation constraints. The payment and the resource delivery are coupled — the server verifies the payment before responding. No invoicing, no billing cycle, no accounts receivable.

x402 is stateless at the protocol level. Each request carries its own payment. The server does not need to track agent accounts, balances, or credit lines. The authorization check happens at the agent’s wallet — does this payment satisfy my constraints? — and at the server — is this payment valid and sufficient?

The tradeoff: x402 requires the agent to hold on-chain funds (currently USDC on Base). Every payment is a blockchain transaction with gas costs. For high-frequency, low-value API calls, the per-transaction overhead dominates. For infrequent, high-value resource access, the overhead is negligible.

Transaction value Gas cost (Base L2) Overhead
$0.01 ~$0.001 10%
$1.00 ~$0.001 0.1%
$100 ~$0.001 0.001%

Stripe’s Machine Payments Protocol

Stripe’s Machine Payments Protocol (MPP) approaches agent payments from the existing financial infrastructure. Instead of on-chain settlement, MPP routes payments through card networks and bank rails — the same infrastructure humans use, with an authorization layer designed for agents.

MPP provides:

  • Delegated credentials. The principal (human) issues a payment credential to the agent with embedded constraints — spending limits, merchant category restrictions, time bounds. The credential is a bearer token backed by the principal’s Stripe account.
  • Per-transaction authorization. Each payment request is evaluated against the credential’s constraints before submission to the payment network. The authorization happens at the platform layer, not the network layer.
  • Audit trail. Every agent-initiated transaction records the agent identity, the delegation credential, the principal, and the constraint evaluation result. The audit trail distinguishes agent-initiated from human-initiated transactions.

The architectural advantage: MPP works with existing merchants. Any merchant that accepts card payments can receive an agent payment. The agent does not need the merchant to implement a new protocol. The disadvantage: card network settlement is T+1 to T+2, and interchange fees apply (1.5–3% for credit).

The Authorization Decision Pipeline

Regardless of the underlying payment protocol, the authorization decision follows the same pipeline:

Request → Identity → Delegation → Constraints → Balance → Approve/Reject
  1. Identity. Which agent is making this request? Verify the credential, extract the agent ID.
  2. Delegation. What delegation scope does this agent operate under? Load the delegation from the principal-agent binding.
  3. Constraints. Does this specific transaction satisfy every constraint in the delegation? Per-transaction limit, velocity limit, category restriction, counterparty whitelist, time-of-day restriction.
  4. Balance. Does the account have sufficient funds after applying the constraint floor? This is a conditional balance check, not a simple sufficiency check.
  5. Decision. All checks pass: approve. Any check fails: reject with the specific reason.

The pipeline must be synchronous and atomic. Evaluating constraints in a separate service from the balance check opens a race window — the constraints pass, then a concurrent transaction depletes the balance before the entry posts. Fragment’s Conditions solve this by embedding constraint evaluation inside the database transaction. Other architectures solve it with serialized writes (TigerBeetle) or conditional writes (DynamoDB compare-and-swap).

Velocity Controls

Per-transaction limits catch large individual purchases. Velocity limits catch agents that make many small purchases that individually satisfy constraints but collectively exceed intent.

A velocity control tracks aggregate spending across a sliding window:

SELECT COALESCE(SUM(amount), 0)
FROM entries
WHERE agent_id = $1
  AND created_at > NOW() - INTERVAL '24 hours'
  AND entry_type = 'debit';
Window Use case Typical limit
Per-transaction Prevent single large unauthorized purchase $1,000–$10,000
Hourly rolling Catch rapid-fire purchasing patterns 5–10x per-transaction limit
Daily rolling Budget pacing within a day Department daily budget
Monthly rolling Align with accounting periods Monthly allocation

The velocity query must be consistent with the current transaction. If the agent is submitting entry N, the velocity check must include entries 1 through N−1 and evaluate whether adding entry N would breach the limit. Running the velocity check outside the transaction boundary allows a burst of concurrent requests to each pass the check individually while collectively exceeding the limit.

See Idempotency at Scale. Agent retry behavior amplifies the risk of duplicate entries. An agent that receives a timeout will retry. If the original entry posted but the response was lost, the retry creates a duplicate charge. Velocity controls count both entries. Idempotency keys prevent the duplicate from posting in the first place.

Tiered Authorization

Not every transaction needs the same authorization rigor. A $3 API call and a $30,000 vendor payment should not pass through the same approval gate.

Tier Amount range Authorization
Auto-approve Below per-transaction limit Constraints + balance check only
Soft approval Above per-transaction limit, below escalation threshold Async human notification, 15-minute approval window, auto-approve on timeout
Hard approval Above escalation threshold Synchronous human approval required, agent blocks until approved or denied
Prohibited Above absolute ceiling or outside allowed categories Rejected immediately, alert to principal

The tier boundaries come from the delegation scope. The platform enforces them — the agent cannot bypass a tier by splitting a purchase into smaller transactions if velocity controls are in place.

The soft-approval tier deserves attention. An agent operating autonomously should not block indefinitely waiting for human approval that may never come. A 15-minute timeout with auto-approve (for amounts below a secondary threshold) or auto-deny (for amounts above it) keeps the agent productive while maintaining oversight.

Audit Trail for Agent Entries

Every entry initiated by an agent must carry metadata that a human auditor — or an automated compliance system — can trace back to the authorization decision.

{
  "entry_id": "ent_8f2a3b",
  "amount": -4200,
  "currency": "USD",
  "account_id": "operating-budget-q4",
  "initiated_by": {
    "type": "agent",
    "agent_id": "procurement-agent-7a2f",
    "principal": "eng-director@company.com",
    "delegation_id": "del_2024_q4_eng",
    "session_id": "sess_ab12cd"
  },
  "authorization": {
    "constraints_evaluated": 4,
    "constraints_passed": 4,
    "velocity_at_decision": 18700,
    "velocity_limit": 25000,
    "tier": "auto-approve",
    "decision_time_ms": 12
  }
}

The audit trail answers five questions:

  1. Who authorized the agent? The principal in the delegation.
  2. What was the agent allowed to do? The delegation scope.
  3. Did this transaction satisfy the constraints? The constraint evaluation result.
  4. What was the system state at decision time? The velocity counter, balance, and constraint values.
  5. Could a human have intervened? The tier and whether human approval was required or bypassed.

Financial regulators have not yet issued specific guidance on agent-initiated transactions. When they do, the audit trail is what they will examine. Recording the authorization decision — not just the outcome — is the difference between an auditable system and one that can only prove money moved.

Revocation

An agent’s delegation must be revocable in real time. If the principal discovers misuse, the next transaction must be rejected — not the next transaction after a cache expires or a token rotation occurs.

Revocation has two modes:

  • Immediate. The delegation is marked revoked in the authorization store. The next constraint check reads the revocation flag and rejects the transaction. This requires the authorization check to hit a consistent store on every transaction, which is the default for Fragment Conditions and any system that evaluates constraints inside the database transaction.
  • Credential-based. The delegation credential (API key, JWT) is added to a revocation list. If the authorization system caches credentials, revocation is delayed by the cache TTL. For financial systems, this delay is unacceptable — a compromised agent credential with a 5-minute cache TTL can execute 5 minutes of unauthorized transactions.

The safe default: evaluate delegation validity on every transaction, from a consistent store, inside the transaction boundary. Caching delegation status for performance is permissible only if the cache TTL is shorter than the blast radius you are willing to accept.