The short answer
OWASP’s LLM06:2025, Excessive Agency, is “the vulnerability that enables damaging actions to be performed in response to unexpected, ambiguous or manipulated outputs from an LLM.”1 The cause of the bad output doesn’t matter: a hallucination, a prompt injection or a plain misunderstanding all count. What matters is that the system let the bad output turn into a damaging action.
OWASP traces it to three causes: excessive functionality (tools the agent doesn’t need), excessive permissions (tools holding more access than the task needs) and excessive autonomy (high-impact actions with no independent check).1 The fix is to cut each one, which is easier to do with a list in front of you.
Deedglass
A tool call meets your rules before it runs
Asks to run
DELETE FROM visits;
Deletes every row in visits
Deedglass checks your rules
- Reading dataAllowed
- Deleting a whole table (DROP, TRUNCATE)Never
- Changing or deleting rows without saying which (WHERE)This one
- Other changesWait for a person
The three causes
OWASP’s examples make each cause concrete:1
| Cause | OWASP example | The agent version |
|---|---|---|
| Excessive functionality | A read-only document extension also has modify and delete functions | A “read the docs” MCP server that also exposes write_file |
| Excessive functionality | An extension that was trialled and replaced is still available | An old MCP server still in .mcp.json after you switched tools |
| Excessive functionality | An extension meant to run one shell command doesn’t block others | A “run tests” tool that passes its argument to a shell |
| Excessive permissions | A read-only extension’s database identity can also update, insert and delete | A Postgres MCP server connected as the app’s owner role |
| Excessive permissions | A per-user extension connects with a generic privileged account that reaches every user’s files | One API token shared by all users of an agent |
| Excessive autonomy | Documents get deleted with no user confirmation | “Always allow” on a delete tool |
Note what’s absent: none of these is about the model being clever or malicious. They’re about what the system around the model permits.
The eight mitigations
OWASP lists these, in this order:1
- Minimise extensions. Offer only the tools the agent needs.
- Minimise extension functionality. Each tool implements only the functions it requires.
- Avoid open-ended extensions. Prefer a dedicated tool, such as a file writer, over general shell access.
- Minimise extension permissions. Downstream access at the level needed, enforced by the identity’s permissions.
- Execute in the user’s context. Act as the specific user with minimum privileges, such as scoped OAuth.
- Require user approval for high-impact actions.
- Complete mediation. Enforce authorisation in the downstream systems, not by relying on the LLM to decide.
- Sanitise LLM inputs and outputs, with secure coding practice and testing.
OWASP adds that logging, monitoring and rate limiting don’t prevent Excessive Agency, but limit the damage.1
Number 7 is the one teams skip most. “The model knows not to drop tables” is relying on the LLM. A database role that can’t drop tables is mediation.
A worked audit
Here’s a common coding-agent setup, as an .mcp.json plus habits, and how it scores against the eight. It’s a composite, not one real team.
Code Data in JSON, the format software uses to pass records and settings.
{
"mcpServers": {
"postgres": { "command": "npx", "args": ["-y", "some-postgres-mcp", "postgres://app_owner:...@prod-db/app"] },
"filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me"] },
"github": { "command": "npx", "args": ["-y", "some-github-mcp"], "env": { "GITHUB_TOKEN": "ghp_... (all repos)" } },
"old-search": { "command": "npx", "args": ["-y", "some-search-mcp"] }
}
}
Habits: the developer clicked “always allow” on SQL queries in week one; the agent also has a shell tool.
| # | Mitigation | Result | Why |
|---|---|---|---|
| 1 | Minimise extensions | Fail | old-search was replaced months ago and is still loaded |
| 2 | Minimise functionality | Fail | The filesystem server’s write tools are on for a read-only task |
| 3 | Avoid open-ended tools | Fail | A shell tool sits next to the narrow ones |
| 4 | Minimise permissions | Fail | app_owner on production; filesystem rooted at the home directory; a token for all repos |
| 5 | User’s context | Pass, partly | The GitHub token is the developer’s own, though wider than needed |
| 6 | User approval | Fail | “Always allow” on SQL |
| 7 | Complete mediation | Partial | GitHub enforces its token’s scopes; the database role enforces almost nothing |
| 8 | Sanitise inputs and outputs | Unknown | Depends on the MCP servers’ code |
Five clear fails out of eight. Each fix is small:
- Delete
old-search. - Root the filesystem server at the project’s
src, or mount it read-only. - Connect Postgres as a read-only role on a branch, not
app_owneron production. Our post on what rds_superuser and neon_superuser hand an agent shows how to check a role. - Use a fine-grained token for the one repository.
- Turn “always allow” off for anything that writes, and require human-in-the-loop approval for it.
- Run the shell in a sandbox, or remove it for this task.
The blast radius of the same agent drops from “production database, every repo, your home directory” to “one branch, one repo, one folder.”
OWASP’s email example
OWASP’s attack scenario is a personal assistant with mailbox access whose extension can also send. A crafted incoming email uses indirect prompt injection to make the agent search the inbox for sensitive information and forward it to the attacker. OWASP’s fixes: an extension that only reads, a read-only OAuth scope, and the user manually sending every drafted email; rate-limiting the send interface reduces the damage.1
That’s one fix per cause: functionality (no send), permissions (read-only scope), autonomy (a person sends). It’s also the lethal trifecta broken at the outbound leg.
What LLM06 doesn’t ask for
- A smarter model. None of the eight mitigations is “use a better model.”
- Perfect prompt-injection filtering. Mitigation 8 is about secure handling of inputs and outputs, not about catching every malicious instruction.
- Logging instead of controls. OWASP is explicit that logs limit damage and don’t prevent it.1
To run an audit like the one above on your own machine, paste your MCP config into the check page or run npx deedglass scan (how the grade works), which lists write paths and the first thing to fix; to try rules on tool calls in your browser, open the playground.
Questions people ask
What is LLM06 in the OWASP Top 10 for LLM Applications?
LLM06:2025 is Excessive Agency: damaging actions performed in response to unexpected, ambiguous or manipulated LLM output.1
What are the causes of Excessive Agency?
Excessive functionality, excessive permissions and excessive autonomy.1
Does logging fix Excessive Agency?
No. OWASP says logging, monitoring and rate limiting don’t prevent it, though they can limit the damage.1
Written with AI assistance and checked against our claims register.