The usual way agents get tools is a list in a config file. The usual way they get credentials is an environment variable with a broad API key. Together these produce an agent that can do anything the key can do, steered only by a paragraph of instructions.
Two identities, always
Every tool call has two principals:
- The agent, the software identity that is making the call.
- The user, the person or system on whose behalf it acts.
Good authorization requires both. The agent identity answers "is this agent allowed to use this tool at all?" The user identity answers "may this user perform this action on this record?" Dropping either produces a classic failure: the agent becomes a confused deputy that lets a low-privilege user reach a high-privilege system.
Patterns that hold up
- Delegated, short-lived tokens. Exchange the user's identity for a narrow token scoped to one tool and one run. Expiry measured in minutes.
- Capability-shaped tools. Prefer
refund_order(order_id, amount ≤ limit)overrun_sql(query). The narrower the tool, the less the prompt has to defend. - Argument-level policy. Authorize on arguments, not just tool names. "Update contact" is fine; "update contact owner to external domain" may not be.
- Read and write separation. Give reading tools broadly and writing tools sparingly, with approval for irreversible writes.
- Deny by default. A new tool is invisible to every agent until a policy grants it.
Protocols help, they do not decide
Standards such as the Model Context Protocol make it easy to expose tools to agents in a uniform way. That uniformity is a gift to integration and a risk to security: connecting a server is one click, and every tool on it becomes reachable. Treat each connected server like a new third-party dependency. Review its tools, pin versions, and put it behind the same policy layer as your internal APIs.
Prompt injection is an authorization test
Retrieved documents, emails, and web pages can contain instructions. You cannot reliably stop a model from reading them. You can make sure that even a fully manipulated agent has limited blast radius, because its credentials are scoped to what the *user* could do and what the *task* needs. If your safety story depends on the model ignoring hostile text, you do not have a safety story yet.
A review checklist
- Can I list every tool each agent can call, and why?
- Does each call carry both agent and user identity?
- What is the worst thing a compromised run could do with its token?
- Which tools are irreversible, and do they require approval?
When the answers are boring, the system is probably safe.