Agent Payment Authorization
Prerequisite: API Design, Controls and Access
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).
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.
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:
- Who authorized the agent? The principal in the delegation.
- What was the agent allowed to do? The delegation scope.
- Did this transaction satisfy the constraints? The constraint evaluation result.
- What was the system state at decision time? The velocity counter, balance, and constraint values.
- 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.