Denial of service aims to make your service unavailable. Denial of wallet aims to make it unaffordable. The attacker does not need to exhaust your capacity — they need to exhaust your budget, and against a metered inference backend that is a far cheaper attack to mount. Every request the attacker sends costs them approximately nothing and costs you real money at the provider's per-token rate.
This is not a hypothetical class of attack. Any endpoint that reaches a paid model, with authentication weak enough or generous enough that an attacker can call it repeatedly, is exposed. Agentic architectures widen the exposure considerably, because the relationship between one inbound request and total downstream spend is no longer one-to-one.
Why Agents Amplify the Attack
In a plain chat application, one user message produces roughly one model call. The cost of an inbound request is bounded and predictable within maybe an order of magnitude.
An agent breaks that relationship. One user request triggers a planning call, then a sequence of tool calls, each of whose results is appended to a growing context and fed back to the model. A ten-step task on a large-context model can cost a hundred times a single chat turn. Multi-agent orchestration multiplies again: an orchestrator that dispatches to five sub-agents, each of which runs its own loop, turns one request into potentially hundreds of billed calls.
Three properties make this dangerous:
Cost is superlinear in loop length. Because most agent loops resend accumulated context on every step, token consumption grows roughly quadratically with step count. An attacker who can induce longer loops — by supplying tasks that trigger retries, or content that keeps the agent searching — gets leverage far beyond their request volume.
Cost per request is highly variable. A short prompt to a small model and a 200k-token context sent to a frontier model can differ by four orders of magnitude in cost. A rate limit that counts requests treats them identically.
Retries multiply silently. Automatic retry on timeout or malformed output is standard and usually correct. Under adversarial input designed to produce malformed output, retry logic becomes a cost multiplier the attacker controls.
The Attack Paths That Actually Get Used
Unauthenticated or cheaply-authenticated public endpoints. A demo chat widget, a public support bot, a free trial with self-service signup. If a new identity costs the attacker nothing, per-identity limits accomplish nothing. Signup friction and per-tenant ceilings matter as much as per-request limits.
Maximum-cost request crafting. Rather than sending many requests, the attacker sends few maximally expensive ones: padded context to the model's limit, prompts that request very long outputs, requests that force the most expensive model in your routing table.
Loop induction. Content designed to make the agent keep working — ambiguous instructions, tool responses that appear to require follow-up, recursive task decomposition. This is the highest-leverage variant against agentic systems and it overlaps with runaway agent spend, the accidental version of the same failure.
Amplification through a compromised or hostile sub-agent. In federated or cross-organization deployments, a counterparty agent that posts expensive tasks can bill your side of the relationship. Cross-org spend needs its own ceiling, separate from internal budgets.
Why Rate Limiting Is Necessary but Insufficient
Rate limits are the reflexive answer and they belong in the stack. They cap request frequency, and that meaningfully bounds naive volumetric abuse. But they measure the wrong quantity. A limit of 100 requests per minute permits anywhere from a trivial bill to a catastrophic one depending on what those requests contain.
The correct unit of enforcement is spend, not count. That means the system must be able to answer, before dispatching a model call: what will this call cost, what has this principal already spent in the current window, and does the sum exceed an authorized ceiling? If the answer is yes, the call must not be made.
Two details determine whether this works:
Pre-call estimation, not post-call accounting. If you only learn the cost after the provider returns, the money is already spent. You need a pre-flight estimate — input tokens are countable exactly, output tokens are bounded by max_tokens and the model's price — checked against the remaining allowance before the request goes out. Post-call reconciliation corrects the estimate afterward.
Atomic reservation under concurrency. A hundred parallel agent calls each reading "budget remaining: $10" and each deciding they fit will collectively spend far more than $10. The check and the decrement must be a single atomic operation, or the ceiling is advisory. This is a classic time-of-check-to-time-of-use bug and it is the most common defect in homegrown budget enforcement.
For how these fit together with softer controls, see budgets versus rate limits and budget policies and hard spend caps.
The Control Stack
A workable defense layers four things.
Hard per-principal ceilings. Every agent, connection, team, and tenant gets a spend cap enforced in the request path, fail-closed. Exceeding it blocks further calls rather than emitting a warning. Caps at multiple levels matter: a per-agent cap contains one runaway agent, and a per-tenant cap contains an attacker who creates many agents.
Loop and depth bounds. Maximum steps per task, maximum delegation depth, maximum total tokens per task, maximum wall-clock duration. These convert an unbounded worst case into a bounded one even when the cost model is wrong.
Retry budgets. Retries should draw from a finite per-task allowance with exponential backoff. Unbounded retry is a cost amplifier under adversarial input.
Cost-aware admission control. Route by cost: cap the model tier reachable from untrusted surfaces, cap max_tokens on public endpoints, cap input context length. A public-facing agent does not need frontier-model access with a 200k context window, and granting it is the single most expensive default in most deployments. Model routing and cost-quality tradeoffs covers the routing side.
On top of that, anomaly detection catches what static limits miss: spend rate that deviates sharply from an established baseline, cost per task rising without a corresponding change in task type, one principal's share of total spend jumping. See anomaly detection on agent spend.
Attribution Decides How Bad the Incident Is
When spend spikes, the response depends entirely on whether you can attribute it. With per-principal attribution — which agent, which connection, which tenant, which task — you cut off the abusive principal and everyone else keeps working. Without it, your options are to disable the feature or absorb the cost, and both are bad outcomes driven purely by missing metadata.
Attribution has to be established at authentication time and carried on the session, not passed as a parameter the caller controls. A tenant identifier the client supplies is a tenant identifier the attacker can forge. See spend attribution and showback per agent and per-connection usage and cost tracking.
Common questions
Is a monthly budget alert enough?
No, for two reasons. Alerts are asynchronous — provider billing data can lag by hours, and a determined attack can spend a month's budget in minutes. And alerts are advisory: they notify a human who must then act. The gap between the spike and the human response is the entire loss. Alerts are useful for detecting slow-burn abuse; they are not a control against the fast case.
Will hard caps break legitimate workloads?
They will break workloads whose real cost exceeds their configured cap, which is information you want. The practical approach is to run in observe-only mode first, measure actual per-agent and per-tenant spend distributions, set ceilings at a multiple of the observed p99, then enforce. Legitimate growth then arrives as a visible, attributable cap-exceeded event that an operator can raise deliberately, rather than as a surprise invoice.
How do I estimate cost before the call when output length is unknown?
You bound it rather than predict it. Input tokens are exactly countable. Output is bounded by the max_tokens you set — and if you are not setting one, that is the first fix. Estimating at the worst case (full max_tokens at the output rate) is conservative and safe; reconciling against actual usage afterward returns the unspent reservation. Conservative reservation plus reconciliation is materially better than optimistic estimation, because the failure direction is a blocked call rather than an overspend.
Does this apply to self-hosted models where inference is not metered per token?
The wallet attack becomes a capacity attack, which is closer to classic DoS — the resource being exhausted is GPU time rather than provider credit. The controls are structurally the same: per-principal quotas, loop bounds, admission control by cost class. The accounting unit changes from dollars to GPU-seconds, and the ceiling still has to be enforced before dispatch rather than reconciled afterward.
How Praesidia approaches denial of wallet
Praesidia enforces spend ceilings in the request path rather than reporting on them afterward. Budget policies attach at agent, connection, team, and organization level, and those ceilings hold under real concurrency — parallel agent calls cannot collectively overrun a cap that each of them individually fit under. Exceeding a hard cap blocks the call and emits an attributable event rather than degrading silently.
Usage is metered per connection and per agent with attribution established at authentication time, so an abusive principal can be isolated without disabling the surface for everyone else. Spend, token volume, and per-task cost are exposed as time series for baselining and anomaly detection. For the wider cost-control model see FinOps for AI agents and the Praesidia documentation.