Published: 2026-08-22
Deep dive

Give the Agent a Budget, Not a Token: Four Primitives for Agent Permissions

Chapters / key moments (click to jump — plays here on the page)

Sachin Malhotra, an engineer on Anthropic's CI team, opens with an incident: an agent tidying up after itself ran a delete whose selector filter evaluated to nothing, so the selector matched everything. Two hundred workloads across twenty engineers were gone in ninety seconds, including uncheckpointed training jobs. Nothing was malicious and the agent did nothing its token forbade — which is exactly the point. The talk replaces the "here is a token and a tool list" model with four primitives you can actually enforce, and one question you use to size them.

Source video

"Give the Agent a Budget, Not a Token — Sachin Malhotra, Anthropic" by AI EngineerWatch on YouTube →

Why a token is the wrong shape

A token is a boolean — a static list of scopes you either hold or don't. Too tight and the agent is useless; too wide and you're writing a postmortem. A budget has four dimensions instead: how much the agent can do, how fast it can do it, what it can undo on its own, and who notices while it acts. Each primitive below moves one of those dimensions.

Step-by-Step Breakdown

  1. Primitive 1 — Sort your verbs by how loudly they fail

    Stop thinking about resources and think about operations. Two actions can look the same size and have wildly different blast radii. In their CI system, unskip a test fails loudly: if the agent gets it wrong, builds go red, a human sees it immediately, and the fix is cheap. Skip a test fails silently: nothing turns red, and a real bug walks into production behind green checks. The rule that follows is mechanical — give the agent the verbs that fail loudly on a dashboard, and put a human on the ones that fail quietly.

  2. Primitive 2 — Put a refilling ceiling on every write

    Every caller gets a small allowance of disruptive actions per time window, spendable however they like with no approval and no waiting. Cross the line and the request bounces back with a count telling you that you exceeded your budget; wait, and the limit refills. Every write gets a rate limit with no exceptions — what varies is the size. Deleting in your own namespace gets a higher limit than touching a shared one. Because it refills, nobody has to file a ticket to get unblocked.

  3. Primitive 3 — Prefer trip wires to allow lists

    An allow list is a guess you make up front, before you have any data on how the agent behaves — and it goes stale rather than improving. A trip wire is how you get that data after the fact: let the agent act on cheap operations, record every action with the actor's stamped identity, and watch the aggregate rather than individual calls. Rate limits are the enforcement; trip wires are the observation. Critically, a trip wire has to page someone — one that nobody sees is useless. It is a smoke detector, not a lock on the door.

  4. The lens — apply the undo test

    This one is not enforced in code; it is the question you ask when sizing the other three. Two parts: can the agent put it back by itself? and how bad is the impact if it got this wrong? If the agent can roll back its own change and the blast radius is acceptable, log it and let it run. If either answer is no, you need a second key — held by someone who is not the agent — plus an audit record of why it was used. Note this is a different question from asymmetric verbs: verbs ask whether you would notice the failure, undo asks whether you could recover from it.

  5. Put the policy in two places, because you need both

    Text — prompts and markdown context files the agent reads before acting. Cheap to change, can explain the reasoning behind a rule, works about 80% of the time, and needs gardening as the files grow. At the end of the day it is advice with no enforcement. Infrastructure — a proxy layer that never reads the prompt, doesn't know why the agent wants something, sees a delete crossing a budget and returns a 403. Narrow, deterministic, and immune to being talked out of the rule by a prompt injection. Text shapes what the agent tries to do; infrastructure bounds how wrong it can go.

  6. Make identity come from the proxy, never from the request

    This is the load-bearing rule of the whole design. Every agent session runs its own proxy alongside it, and every outbound call goes through it. The proxy holds the real credentials and stamps each call with the identity it already knows — not the one the agent claims. If the agent could set its own identity in a header, hitting a limit would be fixed by changing the header, and you would not have a rate limit, you would have a suggestion. In their Kubernetes setup the stamp is written onto the job as a label, every child job inherits it, and ownership, quotas, rate limits, approvals, and trip wires all key off that one label. The proxy also issues a per-session ID so you can tell which of your concurrent sessions is misbehaving.

Worked Examples From Their Production Setup

Rate-limiting deletes with an admission webhook

The team's fix for the opening incident was an admission webhook whose only job is to cap deletes at a fixed number per hour, per resource kind, per namespace. There is a bypass flag for genuine on-call situations — and the detail worth stealing is what the flag does inside an agent session: it refuses to work at all, and tells the agent to ask a human to run the command. The agent gets the rate limit; the human keeps the override.

A scoped key for feature flags

Their agent holds a key for the feature-flag service that gives it the full dial on canary — staging traffic and dogfooding customers — where it can ramp a flag from 0 to 100, watch for filed bugs, and toggle it back off. The key is deliberately not scoped to promote a flag to real production; the most the agent can do there is propose that a human promote it. The second key is not a new authorization system, just a separately scoped credential.

A trip wire that produced a one-line fix

They track one number: investigation threads launched per hour for a given test-job failure. One morning the number ran far above baseline and the trip wire paged on-call. The agent had spun up dozens of investigation threads for jobs that were all failing with the same error signature — each thread reasonable on its own, but in aggregate obviously one infrastructure failure. The fix was a sentence added to the agent's context telling it to correlate failures across test jobs before launching separate investigations. Next time, it did. That is the trip-wire loop working: watch the aggregate, and most fixes are one or two lines of context, not a code change.

Gotchas & Caveats

  • Narrowing token scope is the reflex fix and it does not hold. Taking the delete verb away works for a week or two, then you are sitting there pressing enter by hand for every legitimate delete. You would not strip a whole verb from a new hire either.
  • A trip wire nobody sees is not a control. It has to page. And it fires after the write has happened — it is detection, not prevention. Pair it with a rate limit, which is the thing that actually caps the damage.
  • Text-layer policy is advice, not enforcement. The same sentence written in a markdown context file works roughly 80% of the time. A prompt injection can argue with it. It cannot argue with a proxy returning 403.
  • The agent must not write its own audit row. In their design the proxy stamps provenance, not the agent — "the agent never holds the pen on its own provenance."
  • You don't need every check on every write. Only some primitives are relevant to any given action. Use the undo test to decide which.
  • Context files grow. The text layer is cheap to change, which is exactly why it accumulates. It needs active pruning.

Key Takeaways

  • The failure mode is not a bad model. In the opening incident the agent did nothing its token forbade — it was handed unbounded power over an action nobody was watching closely.
  • Replace the yes/no token question with a budget across four dimensions: how much, how fast, what's reversible, and who's watching.
  • Give agents verbs that fail loudly; keep humans on verbs that fail silently.
  • Rate-limit every write with a ceiling that refills on its own, so nobody files tickets to get unstuck.
  • Watch aggregates, not individual calls — and expect most resulting fixes to be a sentence of context.
  • Identity must be stamped by infrastructure, never claimed by the agent. Get that one rule right and everything else is tuning.
  • The whole thing is an onboarding checklist you already wrote for humans: what can they touch, how much rope do they get, who signs off, and how do you know it's working.
Related reading on this site

The permission model here maps directly onto our cross-platform Security Center and the per-platform hardening guides — OpenClaw security, IronClaw skill allowlisting, and Hermes security.

Weekly Digest — In Your Inbox

Get the week's top AI agent news, updates, and guides — every Friday.