How it works
An agent can only call tools that are present in its registered tool set for a given turn. That registered set is the tool surface. The model reasons over the prompt and the tool schemas it was handed, then emits a call; the harness rejects anything not on the surface. So the surface is a hard capability boundary, enforced by the runtime rather than by the model's judgment.
A tool surface is shaped by three levers:
- Registration — which tools are exposed at all. A read-only research agent never receives a
deleteordeploytool, so those actions are unreachable. - Scoping — the parameters and permissions attached to each exposed tool. A
write_filetool may be present but confined to one directory; a database tool may be bound to a read replica. - Conditioning — narrowing or widening the surface as state changes. Tools can be added after a plan is approved, or removed after a budget is spent or a checkpoint is passed.
The surface is not static. The same agent can hold a small surface during exploration and a larger one only after a gate. What matters is that at every step, the set of callable actions is explicit, inspectable, and smaller than "everything the model can imagine."
Why it matters in an agent harness
The tool surface is where an agent's autonomy meets a hard limit you control. The model's output is stochastic; the surface is not. That makes it the most reliable place to enforce safety, because it holds even when the model is confused, jailbroken, or wrong.
A tight surface shrinks blast radius. An agent that was never given a destructive tool cannot take a destructive action, so you spend far less effort reasoning about every path it might take. It sharpens observability too: a small, named surface makes the agent's possible moves enumerable, so logs and traces map onto a known action space instead of an open one. And it is your main defense against prompt injection — untrusted text can steer the model's intent, but it cannot conjure a tool that isn't registered.
The surface also composes with the rest of the harness. Least privilege is a policy; the tool surface is where you implement it. Approval gates work by widening the surface only after a human or check clears. Subagents get narrower surfaces than their orchestrator so a delegated task cannot exceed its mandate.
Tool surface vs tool budget
These are easy to conflate and control different things. The surface governs what is callable; the budget governs how much calling is allowed.
| Tool surface | Tool budget | |
|---|---|---|
| Controls | Which actions exist | How many calls are permitted |
| Boundary type | Capability | Consumption |
| Failure it prevents | Unauthorized action | Runaway loops, cost blowups |
| Enforced by | Registration and scoping | Counters and quotas |
A generous surface with a tight budget still lets an agent do something dangerous once. A tight surface with a generous budget lets it churn harmlessly. You usually want both, but the surface is the one that decides whether a catastrophic action is even reachable, so it deserves the stricter default.
The Rifty take
We treat the tool surface as the first thing to design and the last thing to loosen. Start from the smallest surface that lets the agent make progress, and widen it deliberately behind gates rather than granting broad access up front and hoping the prompt holds the line. We accept that a narrow surface means more explicit widening steps and occasionally a blocked-but-legitimate action; that friction is cheaper than reasoning about an action space we didn't bound. Capability belongs in the runtime, not in the model's discretion.
Common failure modes
- Convenience creep — tools added "to be safe" that quietly widen the surface until least privilege is gone. Audit the registered set, not the intended one.
- Broad tools with narrow names — a friendly-sounding
run_commandtool that is actually arbitrary code execution. Name and scope tools by what they can do, not what you hope they'll do. - Static maximal surface — handing every tool to every agent for every task instead of conditioning the surface on stage or role.
- Unscoped parameters — the right tool with no bound on its target, so a
writetool can reach any path or table. - Surface drift across subagents — delegated agents inheriting the orchestrator's full surface, erasing the containment delegation was supposed to buy.
- Untracked surface — no log of what was callable at each step, so a post-incident review can't reconstruct what the agent could have done.
Frequently asked questions
What is the difference between a tool surface and a guardrail?
A tool surface decides whether an action is callable at all; a guardrail decides what happens when a callable action is invoked. The surface is a capability boundary enforced at registration. Guardrails inspect, gate, or veto specific calls. Use the surface to remove actions and guardrails to constrain the ones you keep.
How small should an agent's tool surface be?
Start with the smallest surface that lets the agent make progress on its task, then widen deliberately behind gates. Default to excluding any destructive or high-privilege tool until a stage or approval requires it. A narrow surface costs some explicit widening steps but bounds the action space you have to reason about.
Does a narrow tool surface protect against prompt injection?
Partly, and it is one of your strongest defenses. Injected text can hijack the model's intent but cannot invoke a tool that was never registered. So a narrow surface caps the damage of a successful injection: the attacker inherits only the actions you exposed, not everything the agent might imagine.
Should subagents share the orchestrator's tool surface?
No. Give each subagent the narrowest surface its task needs, smaller than the orchestrator's. Sharing the full surface erases the containment that delegation is meant to provide, letting a delegated task exceed its mandate. Scope tools per role so a worker cannot reach actions outside its job.
How do I audit a tool surface?
Enumerate the tools actually registered per agent and per stage, not the ones you intended to expose, and record what was callable at each step. Check each tool's real capability against its name and its parameters against their scope. Broad, unscoped, or convenience-added tools are where least privilege silently erodes.