How it works
Least privilege is a design rule you enforce at the boundary between the agent and the world: for each task, the agent receives the smallest capability set that still lets it finish. Everything else is absent, not merely forbidden by the prompt. In a harness this usually means:
- Scope the tool surface. Register only the tools this task needs. A summarizer gets read access; it never sees
delete,deploy, orsend_email. - Scope the data. Bind credentials to one project, one bucket, one table — not the whole account. Prefer read-only tokens unless a write is genuinely required.
- Scope in time. Grant elevated permissions for a single step and revoke them after, rather than holding a standing grant for the whole run.
- Scope by identity. Give each agent or subagent its own credential so its actions are attributable and independently revocable.
The test is subtractive. Start from nothing and add a capability only when a concrete step fails without it. This inverts the common default, where an agent inherits the operator's full toolbelt because that was easiest to wire up. Least privilege trades a little setup friction for a permission surface small enough to reason about.
Why it matters in an agent harness
Agents are non-deterministic and steerable by their inputs, so you cannot rely on the model choosing not to do damage. Least privilege converts an intent problem into a structural one: an action the agent lacks the permission to perform cannot happen regardless of what the model decides or what a poisoned document tells it to do.
The concrete payoffs are containment and legibility. When a run misbehaves, the worst it can do is bounded by the permissions it held, so your incident is proportional to the grant, not to the model's imagination. A prompt injection that reaches a read-only agent can exfiltrate nothing it couldn't already read and can write nothing at all. Attribution gets easier too: per-agent credentials mean the audit log tells you which actor did what. And a small surface is a reviewable surface — you can look at a task's tool list and actually hold its capabilities in your head, which is the precondition for trusting an autonomous loop at all.
Least privilege vs sandboxing
These are complementary, and conflating them leaves gaps. Least privilege is about which capabilities exist for the agent; sandboxing is about where the agent runs and what the surrounding environment can touch.
| Least privilege | Sandboxing | |
|---|---|---|
| Controls | Granted tools, scopes, credentials | Execution environment, filesystem, network |
| Failure it contains | Misuse of an authorized-but-broad grant | Escape or side effects of code the agent runs |
| Granularity | Per tool, per token, per task | Per process or per environment |
| Question it answers | "What is this agent allowed to do?" | "What can the machine it runs on reach?" |
You want both. A tightly sandboxed agent that still holds a god-mode API key can wreck production without ever escaping its container. A least-privileged agent running unsandboxed code can still be pivoted through arbitrary code execution. The permission boundary and the execution boundary are different walls.
The Rifty take
We start every task from zero capability and add back only what a failing step proves it needs. We would rather pay setup friction and re-grant a missing permission than ship an agent with a surface too large to reason about. The value of a grant is not what it enables on the happy path; it is what it enables on the worst path, when the model is confused or the input is hostile. Narrow scope is not a constraint on the agent — it is what makes handing the agent real authority defensible.
Implementation checks
- Default deny. New tasks inherit no tools or credentials; every capability is an explicit, justified addition.
- Read before write. Issue read-only scopes unless a step genuinely mutates state, and split read and write into separate grants.
- One credential per actor. Give each agent and subagent its own revocable identity so blast radius and attribution stay per-agent.
- Expire elevation. Scope high-risk permissions to a single step and revoke them, rather than holding standing grants across a run.
- Audit the surface, not the intent. Review the actual registered tool list and token scopes for each task; do not trust prompt language that merely asks the agent to behave.
- Re-scope on reuse. When you repurpose an agent for a new task, re-derive its permissions from the new task, not from what it happened to carry before.
Frequently asked questions
How is least privilege different from a guardrail?
A guardrail inspects and may block an action the agent is otherwise able to perform; least privilege removes the capability so the action never becomes possible. Guardrails are checks layered on a granted surface, while least privilege shrinks the surface itself. Use both: structural scoping first, guardrails for what remains.
How do I decide the minimum permissions for a task?
Work subtractively. Start the agent with no tools or credentials, run the task, and add back only the specific capability whose absence causes a concrete step to fail. Prefer read-only and single-resource scopes. The minimum is what the worst path can tolerate, not what the happy path finds convenient.
Does least privilege help against prompt injection?
Yes, structurally. Injection steers the model's intent, but an agent cannot execute an action it lacks the permission to perform. A read-only, narrowly scoped agent that ingests a poisoned document can leak nothing beyond what it could already read and can write nothing at all, so the injection's reach is capped by the grant.
What is the cost of applying least privilege?
Mostly setup friction and occasional re-grants when a task turns out to need a capability you withheld. That cost is front-loaded and cheap to fix. The alternative — a broad standing grant — is cheap to wire but expensive on the worst day, when a confused or hijacked agent acts with more authority than it needed.
Should each subagent get its own permissions?
Yes. Give every agent and subagent its own credential scoped to its task, rather than sharing one broad token. Per-actor identity keeps blast radius contained to a single agent, makes actions individually revocable, and gives your audit log a clear answer to which actor performed which action.