Tool-call policy

Last checked · 3 min read

A tool-call policy is a set of rules, evaluated outside the model, that decides each tool call an AI agent makes before it runs: allow it, refuse it with a reason, or hold it for a person. Rules read the tool, its arguments and who is asking, so the decision doesn't depend on the prompt.

Why the rules live outside the model

A system prompt that says “never drop a table” is a request, not a rule. The model can misread it, a prompt injection can talk it out of it, and nothing records whether it was followed. A tool-call policy moves the decision to code that runs between the agent and the tool. The agent still chooses what to ask for; the policy decides what actually runs.

OWASP’s Top 10 for LLM applications describes this risk as “Excessive Agency”: the vulnerability that enables damaging actions in response to unexpected, ambiguous or manipulated model output. It names three usual causes: excessive functionality, excessive permissions and excessive autonomy.4 Narrow credentials shrink what a tool can do at all. A policy narrows it further, call by call.

What a rule can read

The useful rules read facts about the call, not the agent’s description of it:

  • The tool and its server, such as postgres.execute or stripe.refunds.create.
  • The arguments. For SQL that means the kind of statement, the tables it names, whether an UPDATE or DELETE has a WHERE clause, and whether several statements are packed into one call.
  • Who is asking: which agent, on whose behalf, in which session.
  • Context: the time, and how many calls or how much money the agent has used in the last minute, hour or day.

Tool descriptions and annotations aren’t facts in this sense. The MCP specification says clients must treat tool annotations, such as a hint that a tool only reads, as untrusted unless they come from trusted servers.1

The three decisions

Most policy engines settle on three outcomes. Allow runs the call. Deny refuses it and returns a reason the agent can act on, such as “send one statement per call”. Hold sends it to a person first; see human-in-the-loop approval. What happens when no rule matches matters as much as the rules: a default of deny means a new tool does nothing until someone allows it. Deedglass starts new orgs on a default-deny policy (source 5).

Writing rules that hold up

  • Fail closed. If the engine can’t parse the arguments, or the SQL is ambiguous, refuse the call instead of guessing.
  • Test rules like code. Keep cases that must be allowed and cases that must be refused next to the policy, and run them in CI. Each Deedglass starter policy carries its own test cases, which run in CI.3
  • Try before you enforce. Run a new version alongside the current one, record what it would have decided, then switch.
  • Record every decision, with the rule and the policy version that made it.

What a policy can’t do

A policy decides on the request. It can’t see what the system did afterwards: a trigger that changed 300 more rows, or a tool that reported success and failed. And a call that is within policy is allowed even if the agent was tricked into making it. Rules, budgets and approvals narrow that risk; they don’t remove it.

An example

examples/policies/postgres-safe.yaml (excerpt)yaml
defaults:
  decision: deny
  reason: No rule allows this action. Add a rule in Console › Policies to allow it.

rules:
  - id: block-destructive-sql
    match: { connector_type: postgres }
    when: sql.kind in ["drop", "truncate"]
    decision: deny
    reason: DROP and TRUNCATE are never allowed for agents.
  - id: block-unbounded-writes
    match: { connector_type: postgres }
    when: sql.unbounded_write
    decision: deny
    reason: UPDATE and DELETE need a WHERE clause that names the rows to change.

How Deedglass uses it

Deedglass's rules decide each tool call before it runs, and a rule can send a call to a person instead.2 The starter that deedglass init turns on never allows DROP or TRUNCATE, never runs schema and permission changes through agents, needs a WHERE clause on UPDATE and DELETE, allows reads, and holds other writes for a person.3

Related on this site

Sources

  1. 1MCP specification 2026-07-28: Tools · modelcontextprotocol.io · checked 18 October 2026
  2. 2Deedglass docs: Policies · docs.deedglass.com · checked 18 October 2026
  3. 3Deedglass docs: Policy packs · docs.deedglass.com · checked 18 October 2026
  4. 4OWASP GenAI Security Project: LLM06:2025 Excessive Agency · genai.owasp.org · checked 18 October 2026
  5. 5Deedglass source: new orgs start on default-deny · github.com · checked 18 October 2026

Last checked 18 October 2026. We re-check the glossary every month. If something here is wrong, write to hello@deedglass.com.