{"slug": "your-ai-agent-is-authenticated-what-is-it-allowed-to-buy", "title": "Your AI Agent Is Authenticated. What Is It Allowed to Buy?", "summary": "Authentication alone does not authorize an AI agent to spend, according to a technical post that separates authentication, delegated authority, purchase approval and payment authorization into four distinct checks with separate evidence. The post walks through a fictional Northwind Labs research agent buying a $42 market report under a policy capping purchases at $50 each, requiring a named human approver above $25, and limiting merchants to an allow-list, and it warns that a $50 per-purchase cap still permits $2,000 across forty purchases unless a cumulative budget is enforced. It recommends atomic budget reservation via a ledger.reserve call to prevent concurrent overspend and idempotency keys such as OpenAI ACP's Idempotency-Key header, with the Delegated Payment Spec returning a 409 when the same key arrives with different parameters.", "body_md": "# Your AI Agent Is Authenticated. What Is It Allowed to Buy?\n\nAuthentication is not authorization to spend. Per-purchase caps, cumulative budgets, retries and concurrency, with a documented AWS AgentCore example and OAuth 2.0 and OpenAI ACP context.\n\nAn agent presents a valid OAuth token. Your API accepts it. That settled one thing: the caller is who the token says it is. It did not settle whether this agent may buy this item from this merchant for this reason right now.\n\nAuthentication, delegated authority, purchase approval and payment authorization are separate events with separate evidence. This post shows where each check lives, using a fictional scenario.\n\n## The scenario (fictional)\n\nA research agent at a made-up company, Northwind Labs, asks to buy a market report. The request:\n\n```\n{\n  \"agent_id\": \"agent-research-07\",\n  \"merchant\": \"reports.example-vendor.test\",\n  \"amount\": 42.00,\n  \"currency\": \"USD\",\n  \"purpose\": \"Q4 competitor analysis (approved project P-1187)\",\n  \"expires_at\": \"2026-10-08T18:00:00Z\"\n}\n```\n\nThe policy attached to that agent: maximum **$50 per purchase**, merchants limited to an allow-list, purpose must match an approved project, requests expire, and anything over $25 needs a named human approver.\n\n## Where each check happens\n\n| Event | Question | Who establishes it | Evidence | \n|---|---|---|---|\n| Authentication | Who is calling? | Your identity layer | Token, client credentials | \n| Delegated authority | What was this agent given the right to do? | The agent's owner, in your policy store | Policy record, owner, scope | \n| Purchase approval | Did an accountable person OK *this* purchase? | Your application | Approval record tied to request | \n| Payment authorization | Did the payment network or PSP accept it? | PSP / chain | Authorization ID | \n\nAn OAuth token can carry scopes, but a scope like `purchase` does not encode \"$50 at this merchant for project P-1187.\" That logic lives in your application.\n\n## Application-side policy check\n\n``` python\ndef authorize_purchase(req, policy, ledger, approvals):\n    if req.merchant not in policy.allowed_merchants:      raise Denied(\"merchant\")\n    if req.purpose_project not in policy.approved_projects: raise Denied(\"purpose\")\n    if req.expires_at <= now():                           raise Denied(\"expired\")\n    if req.amount > policy.per_purchase_cap:              raise Denied(\"per-purchase cap\")\n\n    if req.amount > policy.approval_threshold:\n        if not approvals.has_valid(req.request_id):       raise NeedsApproval()\n\n    # cumulative budget: reserve atomically, don't check-then-spend\n    if not ledger.reserve(req.agent_id, req.request_id, req.amount):\n        raise Denied(\"budget exhausted\")\n    return Allowed(req.request_id)\n```\n\nThe atomic `ledger.reserve` call at the end is the important part; see the section on concurrent purchases below.\n\n## Per-purchase cap vs cumulative budget\n\nThey guard different failures.\n\n- A **per-purchase cap** ($50) limits the damage of one bad decision.\n- A **cumulative budget** (say $200 per run or per month) limits the sum of many small decisions, each individually legal.\n\nAn agent that stays under $50 forty times has spent $2,000. Only the cumulative control sees that.\n\n## Retries and concurrent purchases\n\nAgents retry, and they run in parallel. Two failure modes follow:\n\n- **Retry double-spend.** If a network timeout hides a success, the agent retries. Key every purchase by a stable`request_id` and make the ledger and the downstream call idempotent on that key. OpenAI's ACP specs require an`Idempotency-Key` header, and the Delegated Payment Spec returns a 409 when the same key arrives with different parameters.\n- **Concurrent overspend.** Two parallel requests each read \"$30 remaining\" and each spend $25. Check-then-act races like this are solved by atomically reserving budget before the payment call and releasing it if the payment fails.\n\n## A documented example, not a ContextIQ feature\n\nOpenAI's [controlled agentic commerce cookbook](https://developers.openai.com/cookbook/examples/partners/aws/controlled_agentic_commerce_with_agentcore_payments/controlled_agentic_commerce) demonstrates this layering with AWS AgentCore Payments. In the example, a per-transaction `maximum_amount` and a per-run cumulative limit are both enforced by the application, human approval is recorded as an `ApprovalGrant` with `approved_by` and `approved_at`, and an unapproved request fails with `PolicyDenied`. The cookbook states that the application checks merchant, purpose, amount and approval before a payment can occur, and its sample runs on synthetic payments unless operators opt in. We cite it as a pattern; ContextIQ is not part of it.\n\nLikewise, OpenAI's [Delegated Payment Spec](https://developers.openai.com/commerce/specs/payment) lets a payment credential carry an `allowance` (maximum amount, currency, merchant, checkout session, expiry). That limits the credential, but it does not replace your own policy: your application still decides whether to ask for the credential at all.\n\n## The pending-approval pattern\n\nThe OpenID Foundation's AuthZEN working group has approved a draft Access Request and Approval Profile (AARP) for the case where policy cannot yet authorize an action because an approval, consent or delegated authority is missing; the system signals what is pending and re-evaluates once it is satisfied ([OIDF announcement](https://openid.net/openid-foundation-advances-authorization-for-the-agent-era-with-new-authzen-working-group-drafts/)). It is a working-group draft, and the `NeedsApproval` branch above is our own simplification of the same idea, not an implementation of AARP.\n\n## Developer checklist\n\n- Authenticate the agent, then look up its policy by agent identity, not by anything in the request body.\n- Name an accountable human owner for every agent identity.\n- Validate merchant, purpose, amount, currency and expiry server-side.\n- Enforce a per-purchase cap and a cumulative budget.\n- Require approval above a threshold, and bind each approval to one request ID.\n- Reserve budget atomically; release on failure.\n- Use idempotency keys end to end.\n- Log the decision and its inputs, including denials.\n\n## Where ContextIQ fits\n\nContextIQ does not authorize purchases or enforce spending limits; that belongs to your application. What it offers is endpoint inspection: the [Agent Protocol Inspector](https://contextiq.trango-compute.com/agent-readiness-detector) can scan an MCP, A2A or ARD endpoint, and the [x402 Inspector](https://contextiq.trango-compute.com/x402-inspector) can validate a payment endpoint's 402 challenge before your policy code decides whether to pay it.\n\n## Sources\n\nFollow Trango Compute on LinkedIn\n\nWe post updates on new tools, context engineering patterns, and LLM cost research.\n\n[Follow on LinkedIn](https://www.linkedin.com/company/trango-compute)", "url": "https://wpnews.pro/news/your-ai-agent-is-authenticated-what-is-it-allowed-to-buy", "canonical_source": "https://contextiq.trango-compute.com/blog/ai-agent-authenticated-what-is-it-allowed-to-buy", "published_at": "2026-10-08 00:00:00+00:00", "updated_at": "2026-10-09 00:17:26.276454+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-policy"], "entities": ["Northwind Labs", "OpenAI", "AWS AgentCore", "OAuth 2.0", "OpenAI ACP", "Delegated Payment Spec"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/your-ai-agent-is-authenticated-what-is-it-allowed-to-buy", "markdown": "https://wpnews.pro/news/your-ai-agent-is-authenticated-what-is-it-allowed-to-buy.md", "text": "https://wpnews.pro/news/your-ai-agent-is-authenticated-what-is-it-allowed-to-buy.txt", "jsonld": "https://wpnews.pro/news/your-ai-agent-is-authenticated-what-is-it-allowed-to-buy.jsonld"}}