
One Agent Cannot Check Itself: Separation of Duties for AI
A control architecture for separating proposal, approval, execution, and reconciliation when AI can trigger consequential business actions.
Read MoreZharfAI Team

An operations team gives eight AI agents access to paid data tools and a shared monthly limit. At 10:00, the ledger says $900 remains. Five agents read that balance, each decides a $250 purchase fits, and each submits. No single request breaks its per-action limit. Together they create $1,250 of new commitments against $900 of capacity.
The dashboard may alert later. The agents may all explain that they checked. Neither fact changes the overspend.
The practical decision is: may this exact action spend now, must it first reserve capacity, does it need a bound approval, or must it be denied? For cumulative limits, the durable rule is to reserve the maximum credible exposure atomically at the final action boundary. A billing report is evidence about cost. It is not economic authority.
This guide is an engineering and control framework, not accounting, payment, or legal advice. Currency treatment, tax, procurement authority, card-network rules, and approval duties vary by organization and jurisdiction.
Three objects are often called a “budget,” but they answer different questions:
Only the third object belongs on the synchronous path to a consequential action. Monthly cloud reports remain valuable for forecasting, allocation, anomalies, and accountability. They usually observe cost after usage begins and may group it more broadly than the business decision being authorized.
The distinction is visible in current provider documentation. AWS Budgets warns that charges can be incurred before usage is billed and before a notification arrives. Google’s current Cloud Billing spend-cap documentation describes a stronger preview control for certain services, but enforcement is not instantaneous, in-flight requests complete, some persistent costs continue, and overages caused by reporting latency are billed. These controls reduce exposure; they do not prove that a particular supplier order, API call, or delegated purchase was within its business authority when committed.
The general security rule is least privilege. NIST’s SP 800-53 control catalog includes least privilege, separation of duties, authorization, auditing, and system-use limits. It is a flexible catalog, not an AI-agent spending architecture.
OWASP’s Excessive Agency guidance locates damage in excessive functionality, permissions, or autonomy and recommends limiting tools, permissions, and high-impact actions. Rate limits can reduce the blast radius. They still cannot decide whether ten individually valid actions fit one shared monetary ceiling.
Other systems supply useful mechanics. Kubernetes ResourceQuota tracks aggregate use and rejects a request that would violate a hard namespace limit. PostgreSQL documents how serializable transactions make successfully committed concurrent work equivalent to some one-at-a-time order, with serialization failures that applications must handle. Neither system defines financial policy. They demonstrate two properties an economic gate needs: reject before admission and protect a shared invariant under concurrency.
Verified facts: the cited systems document delayed billing signals, hard admission checks, least privilege, and concurrency guarantees with explicit limitations. ZharfAI analysis: bind those ideas into a separate spend-authority service that reserves exposure before an agent reaches the provider or payment boundary. This reservation ledger is an implementation pattern, not a standard or a claim that one database setting makes spending safe.
“Cost” may mean model tokens, a paid search, cloud compute, a supplier order, a refund, a card authorization, or a contract with future minimums. These effects differ in timing and reversibility. Inventory every tool that can create economic exposure, including tools that appear operational rather than financial.
For each action class, record:
| Field | Decision question |
|---|---|
| Commitment point | Which response, message, or external state makes the organization liable? |
| Maximum exposure | What is the highest amount that can settle, including tax, tips, fees, quantity changes, and retries? |
| Currency and valuation | In which smallest unit is authority kept, and which exchange-rate source and buffer apply? |
| Scope | Which tenant, team, project, vendor, category, geography, and time window consume the balance? |
| Reversibility | Can the commitment be voided, partially reversed, refunded, or only compensated later? |
| Evidence | Which quote, price version, approval, reservation, idempotency key, and external receipt prove the path? |
The measurement contract for units, currency, and rounding explains why a bare number is not a decision-ready quantity. Never let the model convert a displayed price into the authorization amount by itself. Deterministic code should normalize minor units, currency, tax rules, quantity, and a bounded contingency.
The policy engine should return one of four results:
“Warn” is telemetry, not a fifth authorization result. “Ask the model to reconsider” is another model invocation. Both may improve behavior, but neither consumes or protects shared capacity.
This also narrows tool authority. The agent should propose an action envelope; a trusted component should price, authorize, reserve, and execute it. The companion guide to least-privilege tool permissions covers the capability boundary. The spend gate adds the aggregate economic invariant that an ordinary permission check lacks.
A useful budget is more specific than “agent: $5,000 per month.” Bind it to:
budget_id, policy_version, owner, funding_source
subject, actor, tenant, workflow, purpose
allowed_action_classes, vendors, categories, destinations
period_start, period_end, timezone
currency, valuation_source, valuation_time, contingency_rule
single_action_limit, cumulative_limit, approval_threshold
committed, reserved, available
reservation_ttl, release_rule, overrun_rule, fallback
Keep overlapping limits. One action may consume an agent limit, a workflow limit, a team limit, a vendor limit, and an organization-wide emergency ceiling. Approval cannot expand a parent ceiling unless the approver has a separately defined power to amend that ceiling. Apply the most restrictive applicable result.
Periods need precise boundaries. “Daily” must name a timezone and daylight-saving behavior. Budget versions should not mutate the meaning of existing reservations. An amendment creates a new version and an attributable decision, while open reservations retain an explicit migration or expiry rule.
The central invariant is simple:
committed + active_reservations + requested_max <= limit
The check and the reservation write must be one atomic operation over every applicable balance. Reading available, deciding in application code, and writing later creates a race. A cache, vector store, or model context is not the authority of record.
Serializable transactions are one implementation option. Explicit row locks, compare-and-swap with versions, or a purpose-built strongly consistent ledger can also work. The choice depends on throughput and failure model. The contract is more important than the product: two concurrent requests must not both spend the same remaining unit. A serialization or version conflict is an ordinary denied attempt that may be retried against fresh state; it is not permission to bypass the ledger.
Put this operation as close as practical to the external commitment. If an agent can call the paid provider directly, the gate is advisory. Issue a short-lived, single-intent capability only after reservation, or let the broker execute the action itself. The credential pattern in short-lived agent access applies here: authority should be narrow, task-bound, and useless after expiry.
One “spent” boolean cannot describe the lifecycle. Use a state machine:
Transitions need immutable event IDs and an idempotency key tied to canonical arguments. A timeout after submission is not a clean failure: the provider may have accepted the action. Follow the retry and idempotency guide: query the external system by a stable reference before resubmitting, and never create a new reservation merely because a transport response was lost.
The authorization amount is rarely the final settled amount. Model pricing can vary with uncached input, generated tokens, tool calls, storage, regional routes, and retries. Purchases can add tax, shipping, tips, partial capture, or exchange-rate movement.
Reserve the maximum credible amount, not the optimistic estimate. The buffer should come from contract terms and measured error, not an invented percentage. Then settle actual cost, release the remainder, and route any excess through a declared rule: absorb within a separate variance reserve, request incremental authorization, pause, or reconcile manually.
Stripe’s official Issuing spending-controls documentation is a useful real-world example of layered limits and their limits: controls can run before authorization, amounts use the card’s smallest currency unit, aggregation can lag, and later fees can exceed a limit. Its real-time authorization documentation shows a synchronous approve-or-decline decision and an amount that can be held, while also requiring an explicit timeout behavior. Use a provider control as a second enforcement boundary, not as a replacement for the organization’s purpose, workflow, and multi-tool budget.
A person should see the supplier or service, exact item, quantity, currency, maximum exposure, evidence, destination, recurring terms, remaining budget after the reservation, and expiry. Bind approval cryptographically or by immutable identifiers to those terms and to the reservation ID.
If the amount, vendor, quantity, destination, purpose, policy version, or material evidence changes, invalidate the approval and reprice. A screenshot saying “approved” is not reusable authority. Nor should approval happen before capacity is protected: two reviewers can approve two actions that were each affordable when viewed.
For high-impact actions, keep the proposer, approver, executor, and reconciler independent where practical. Separation of duties for AI explains why several prompts inside one control domain do not create independent oversight.
A sourcing workflow has a $1,000 weekly paid-data allowance, a $300 single-action ceiling, and a $600 vendor ceiling. Six agents research different suppliers. Three simultaneously request reports priced at $250 from the same provider.
The gate normalizes each request to USD minor units, verifies the report SKU and purpose, and locks the workflow and vendor balances in one transaction. The first two reservations succeed. The third would make vendor exposure $750, so it is denied even though the workflow still has $500 available. An operator may choose another source; they cannot approve through the vendor ceiling without authority to amend it.
One provider request times out after submission. Its $250 remains submitted, not released. The workflow queries by the external reference. The provider confirms a $230 authorization, so the ledger commits $230 and releases $20. The other report settles at $258 after tax; $250 was not a credible maximum, so the event enters reconciliation and the pricing rule must be corrected before this SKU is used autonomously again.
This example separates model judgment—whether a report is useful—from deterministic authority—whether this exact purchase fits every current limit.
Run concurrency tests with the balance almost exhausted. Submit many actions at once and prove accepted maximum exposure never exceeds any applicable ceiling. Inject database conflicts, worker crashes, delayed webhooks, duplicate messages, provider timeouts, late settlement, partial reversal, expired reservations, clock skew, and budget amendments.
Measure:
committed + reserved against each ceiling;A zero-overspend chart is weak evidence if some paid routes bypass instrumentation. Reconcile the authority ledger with provider usage, card authorizations, invoices, purchase orders, and the general ledger at an appropriate cadence. Unknown differences are control findings, not rounding noise.
There is no free concurrency. Strong coordination adds latency and operational complexity. Apply it where commitments are cumulative or consequential; low-risk metered calls may use smaller prepaid pools or provider quotas. State the residual overshoot explicitly wherever the downstream system cannot offer hard pre-authorization.
Before granting an agent spend authority, confirm that:
Revisit the design when a new paid tool, provider, currency, pricing model, recurring commitment, fallback route, or delegation layer enters the workflow. The system is ready to spend only when a concurrent request cannot turn yesterday’s budget plan into today’s unauthorized liability.
Sources reviewed on September 5, 2026:

A control architecture for separating proposal, approval, execution, and reconciliation when AI can trigger consequential business actions.
Read More
Turn agent loops, graph orchestration, scoped retries, evidence gates, and human approval into one testable production architecture.
Read More
A source-checked build guide for six ledger-owning agents, one routing desk, evidence-bound handoffs, and human control over consequential actions.
Read MoreIf this note maps to a real system in your organisation, start with the services page or a shipped case study.