Skip to content
All insights

Tool permissions for agents: the least privilege nobody applies

5 min readAI SecurityAgentsOWASP
Permission matrix for an agent: for each tool, whether the action is allowed on its own, requires human approval or is denied, with read and write kept separate

There is a question we ask in every diagnostic that almost never gets a good answer: which identity does the agent act with when it calls a tool.

The answers fall into three groups. With the OAuth token of the person who set it up, which keeps working even after that person has left the project. With a service account created for "the integration", which has admin rights because that way nothing failed during testing. Or with the platform's API key, shared with three other agents.

All three mean the same thing: the agent can do far more than its task needs, and when someone injects an instruction through an email or a document, the damage will come from the permission, not from the model.

Why the model is not the control

Least privilege is the oldest principle in security and the one that travels worst to agents. The reason is that the conversation about agents centres on the model: how well it follows instructions, how resistant it is to injection, which guardrails it ships with.

None of that is a control. The model decides which tool to call by reading text, and some of that text is written by someone who is not you. Indirect injection is not a bug to be fixed in the next release: it is the consequence of data and instructions travelling down the same channel. The OWASP Top 10 for Agentic Applications lists it under tool misuse and under identity and privilege abuse, and both are on the list for the same reason: the permission is what turns a malicious instruction into an action.

So the control has to sit on what the agent can do, not on what it decides to do. If the support agent has no permission to delete contacts, it does not matter how hard it is talked into it.

Six rules

These are the rules we apply. They do not require a product. They require taking seriously that an agent is one more principal in the identity system.

1. An identity of its own per agent

Every agent has its own identity in the identity provider, with its name, its owner and its credentials. Not a person's, not a shared one. It is what allows attributing every action, revoking without breaking the others and auditing per agent. If your platform cannot create workload identities, that is the first problem to solve.

2. An allowlist of tools, not a blocklist

The agent sees only the tools its task needs. Everything else does not exist for it. A ticket-triage agent needs to read tickets, read the knowledge base and write a comment. It does not need to close tickets, it does not need to send email, it does not need the billing connector even if the platform offers it.

The check is simple: the tool list in the agent's configuration against the list of actions it performs on a normal day. If the first is longer, there are permissions to remove.

3. Read and write are different permissions

Almost every connector groups permissions by system: access to the CRM, access to email. The agent that only needs to read the CRM ends up with permission to write to it. Where the connector allows it, split the scopes. Where it does not, put a thin layer in between that exposes only the read operation. It is the rule that shrinks the blast radius of an injection the most, because most agents in production only need to write to one or two places.

4. Constraints at argument level

Allowing "send email" is not enough. The question is to whom. An agent that emails the company's customers should not be able to send to an arbitrary external domain, and one that queries a database should not be able to run a statement that deletes. The policy has to look at the arguments of the call, and in particular where they came from: if the email recipient appeared in a document retrieved by the RAG and not in the user's request, that is a sign someone put it there.

It is exactly what the Agent Control Standard models when it requires every argument to travel with its provenance, and what a policy engine like Cedar lets you express in a few lines:

permit (
  principal == Agent::"support-triage",
  action == Action::"email.send",
  resource
) when {
  resource.to_domain in ["company.com", "company-customers.com"] &&
  resource.to_provenance == "user_request"
};

5. The irreversible waits for a person

Payments, deletions, sends outside the company, permission changes, deployments. For those actions the policy does not return a yes or a no, it returns a wait: the call is held, with the rule that triggered it in view, and does not proceed until someone approves it. The person does not oversee every action of the agent, they oversee the dozen a day that cannot be undone. It is the practical way to meet the human oversight the Regulation asks for without putting anyone in front of a console for eight hours.

6. Short-lived credentials and controlled egress

The agent's tokens expire in hours, not months, and are issued for the task. And the agent can only talk to the destinations its task needs: if an internal agent ends up making requests to a domain nobody authorised, that is the clearest exfiltration signal you will get. Egress control is cheap and almost nobody applies it to agents.

The one-afternoon audit

With one agent in production you can check all of this in an afternoon and without new tooling:

  1. Open the agent's real configuration and copy the tool list. Not the documentation, the configuration.
  2. For each tool, note which credential it authenticates with and who owns it.
  3. Mark which ones write, delete, send outside or move money.
  4. For each of those, check whether a human approval exists before it runs and who receives it.
  5. Ask for the last twenty-four hours of logs and check that every action can be attributed to the agent, not to a person.

What comes out is half of area 3 of the agent control checklist, and it is usually the half with the most noes.

How we do it in the lab

In DELIA, our detection and response layer for LLM, RAG and agent pipelines, these rules are enforced from outside the agent and ahead of the action: every tool call goes through a deterministic Cedar policy that looks at the tool, the arguments and their provenance, and the approval queue holds the ones the policy marks as irreversible until a person decides. The trace of every decision leaves for the SIEM in OCSF.

But the order matters: the six rules come before any product, ours included. An agent with its own identity, a short allowlist and read separated from write has already removed most of the risk. What is left is what deserves a runtime control, and to find out how much is left in your case, the control diagnostic starts precisely here.