The Agent Permission Matrix
One page for deciding what an AI agent is allowed to do on its own: by how privileged the tool is, and by where the instruction came from. Free, no email required.
Once an LLM gets tools, failures stop being “the model said something weird” and start being “the model did something expensive.” The incident shape is almost always the same:
Untrusted text enters context → the model treats it as instruction → a privileged tool fires.
So the useful permission models are the ones that don’t depend on the model behaving.
The two axes
-
Tool class
What privilege does this tool represent? Read, reversible write, irreversible write, exfiltration, privilege escalation.
-
Source trust
Where did the instruction originate? Trusted (T), semi-trusted (S), or untrusted (U), where U dominates across everything that contributed to the call.
The matrix
| Tool class | Trusted (T) | Semi-trusted (S) | Untrusted (U) |
|---|---|---|---|
| Read | ALLOW | ALLOW (SCOPED) | ALLOW (SCOPED) |
| Write (reversible) | ALLOW | CONFIRM | DENY |
| Write (irreversible) | CONFIRM | DENY | DENY |
| Exfil (send/export/share/upload) | CONFIRM | DENY | DENY |
| Privilege escalation (roles/keys/identities) | DENYexcept explicit admin flows | DENY | DENY |
ALLOW · ALLOW (SCOPED) deterministic limits, allowlists, redaction · CONFIRM out-of-band human approval · DENY
If you only take one rule
U → {exfil, irreversible writes, privilege escalation} = DENY
Untrusted provenance never reaches a privileged tool. That single invariant carries most of the weight.
What it compiles to
Enforce it at one choke point: a gateway, middleware, or proxy. The point is to keep policy out of prompt templates. It is a per-tool-call decision: compute worst_trust across the minimal slice of context that actually built the arguments, not the whole conversation.
risk = tool.class
worst_trust = toolcall.provenance.worst_trust // T/S/U, U dominates
if worst_trust == U and risk in {EXFIL, WRITE_IRREV, PRIV_ESC}:
deny("untrusted_to_privileged")
A working Python implementation (the matrix, the invariant, and a gateway to enforce them) is at acebot712/agent-permission-matrix. MIT, no dependencies.
The long version
This page is the summary. The full write-up covers provenance tracking, over-tainting, and how the framing overlaps with the OWASP Top 10 for LLM Applications: A One-Page Policy Matrix for Agent Tools (Read vs Write vs Irreversible).
Get the next one
I write about agent tooling and applied AI. New posts go out on Telegram and RSS.
Follow on Telegram