Agent sandboxing: a key that opens everything opens too much

Last time we looked at what happens when an AI agent holds a token that reaches straight into production.

A breach that cost users money they never spent

A contrast of shared versus scoped credentials showing that a breach gives the attacker whatever the key allows.

AI tools need credentials to work. They call external APIs, read databases, and run code on your behalf. Most of the time, that's exactly what you want. The risk appears when those credentials cover more ground than any single task needs, and someone else gets hold of them.

In October 2026, attackers broke into the hosted console of an AI coding tool. They stole API keys belonging to 1.4% of its online users. Those keys worked exactly as intended, just from the wrong machines. TechCrunch reported that the attackers used them to call three major AI providers until the bills reached hundreds, sometimes over a thousand, dollars per account.

The users never made those requests. The keys did. The attackers didn't need to read anyone's code or understand the tool's purpose. A live credential carries its own access, and it takes that access to whoever holds it.

A credentials breach at an AI tool is easy to monetise. The attacker doesn't need to understand the codebase. They only need to know how to call the same API the victim was already using.

Why the credential is the real risk

An agent can't do useful work without credentials. Read a database, push a code change, call a billing service: all of it requires the agent to identify itself. What the agent can do is entirely defined by what those credentials allow. When something goes wrong, the attacker inherits exactly those permissions.

The agent itself is rarely the weak point. The credential it carries is.

Think of a building with a master key: one key, every door. If a contractor loses it, every room is at risk. If each contractor carries only the key for the room they need today, a lost key means one room. The principle that addresses this is called least-privilege access: each task gets exactly the credential it needs, scoped as tightly as possible, and nothing extra travels with it.

The asymmetry between what an agent needs for any single step and what it routinely holds is where most of the risk sits. Agents often carry a credential configured once, for the widest use case, and then left that way. Every step in the run carries the whole credential, whether or not that step uses even half of what it allows.

This is especially worth watching with agents that run many steps in sequence. A pipeline that checks code, runs tests, and then deploys a change makes several different kinds of request. Each one is a moment the credential is active. The more steps, the more moments.

GitGuardian's research on agentic AI security notes that an attacker doesn't always need to steal a credential outright. If they can manipulate what an agent is told to do, they can make the agent use its own access against you. The agent becomes both target and tool. The permissions it holds set the ceiling on how much damage can follow. That ceiling is the blast radius: the total reach an attacker gets from a single compromise. The wider the access, the higher the ceiling.

What least-privilege access means in practice

A legend showing two dimensions of credential scoping: permission level and reach, with a third item on per-task clarity.

Scope has two dimensions worth thinking through. The first is permission level: can the credential read, write, delete, or administer? If a step only fetches rows to produce a report, give it a read credential. A compromised read step has no way to delete a table if the credential never allowed deletes. The second dimension is reach: which system, which database, which table does the credential cover? A credential scoped to one table is far less dangerous than one covering an entire instance, even if both are technically read-only.

The common mistake is convenience. Teams reach for whatever credential is already in the environment, because scoping a new one per task takes time. This works fine until a step leaks or behaves unexpectedly. At that point, "we used the admin key because it was already there" is a difficult explanation.

Scoping credentials per task also has a useful side effect: it forces the question of what each task actually does. Teams that go through this exercise often find steps doing more than anyone remembered.

The OWASP Top 10 for Large Language Model Applications is a ranked guide to security risks in tools built on AI language models. It names excessive permissions as one of three root causes of dangerous autonomous behaviour. The other two are agents given too many capabilities and agents given too much independence. The fix it prescribes is minimum permission rights enforced in the downstream systems the agent connects to. In practice, that means the database connection uses a read-only user when read is all the task needs. The API token is scoped to the endpoints the step actually calls. Many services let you scope a token to specific actions. The extra step is usually small.

Three ways a credential gets into an agent, and what each one costs you

A flow of three credential patterns from ambient to runtime to demand-fetched, showing how each one narrows the blast radius.

How a credential arrives in an agent determines how much an attacker can reach from a single breach. Three patterns, each with a different cost.

  1. Credentials already in the environment. These are the secrets loaded at startup: environment variables set at the machine or container level, config files read when the host initialises, whatever the platform makes available by default. They're convenient. The agent picks them up without any extra code. The cost is that every step running in that environment shares the same access, whether or not any individual step needs all of it. An agent proofreading a document carries the same database password as an agent writing a deployment record. If one step is compromised, everything the environment holds is reachable. This is the widest pattern, and the easiest to inherit from an existing setup without making an explicit choice about access.

  2. Credentials passed in when the task starts. Here, the system that kicks off the task also hands the agent credentials scoped to that task's specific needs. The agent holds nothing persistent. When the task ends, the credential ends with it. A step that checks code for issues gets a read token for the project it's reviewing, and nothing else. A step that sends a notification gets a write token for the notification service, valid for this run only. A leaked token from one step has no access to operations it wasn't handed for that run. The real work is deciding, before each task starts, what that task actually needs. This discipline is usually what teams find hardest about the approach. But the blast radius of any leak is bounded to the task's scope.

  3. Credentials fetched at the moment they're needed. In this pattern, the agent holds no credential at rest. When it's about to run an operation, it requests a short-lived token from a dedicated secrets store, scoped to exactly that operation. The token expires in seconds or is cancelled the moment the operation finishes. An attacker who reaches the agent mid-run finds nothing to take. This is the narrowest pattern and gives an attacker the smallest window. The trade-off is real: you need a secrets store that can issue scoped, short-lived tokens on request. Your agent code also needs to ask for them at the right moment. More to build. But when a token leaks, it covers one operation, and then it's gone.

The further along this list you operate, the less an attacker gains from any single breach.

A setup where the keys stay short

In my own agent runs, unattended steps hold no database password. A step that reads logs or checks a test result gets a read-scoped token, nothing more. A step that writes a result back gets a narrower token, valid for that operation only, cancelled when it completes.

The other half is that every unattended run is stoppable from outside. If a step behaves unexpectedly, I can cut the run without revoking anything permanent, because the agent was never handed anything permanent to begin with.

Secrets expiry runs a little loose on timing in the current setup, and that's the part I'd tighten next. But a credential leak from one step costs one step, bounded by what that step was allowed to do. That's a much smaller problem to contain than a wide credential running loose.

Shrink the key, shrink the blast radius

Three patterns, three different ceilings. Ambient credentials give an attacker wide reach. Runtime-injected credentials narrow that reach to the task. Demand-fetched, short-lived credentials narrow it to the single operation.

The October 2026 incident shows what happens at the wide end. A stolen key opens the same doors for whoever holds it, because nothing scoped it to the original user or their specific task. The blast radius was set entirely by what the key allowed.

A useful check before your next run: for each credential your agent uses, ask whether a narrower version of it would cover the task. A read token works just as well as an admin token for reading. A token scoped to one service has no access to another.

The damage a breach causes is determined by what the agent can reach. Scope each agent's credentials to exactly what its current task needs, and you've already set the ceiling on the worst case, before anything goes wrong.

One question before you move on

What is the widest credential your agent currently holds, and does every step in its run actually need that much access?

Sources

OWASP Top 10 for Large Language Model Applications 2025, LLM06:2025 Excessive Agency: covers three root causes of dangerous autonomous behaviour in AI-powered tools, namely excessive functionality, excessive permissions, and excessive autonomy, and prescribes granting each agent only the minimum access its specific task requires, enforced in downstream systems.

The post on one page
The post on one page