Gate tool execution
A model can ask your program to run a tool, such as searching documents or sending an email. That request is only a proposal. The text the model read may contain instructions planted by someone else, which is called prompt injection. So the model's wish is never a reason to act. Your code decides. A simple gate asks two questions: is this tool allowed at all, and if it changes something, has the user confirmed it?
Learn it
Words to know
- tool call
- A model's request that your program run a function for it, with a name and arguments.
- allowlist
- The list of things that are permitted. Anything not on it is refused.
- prompt injection
- Text in a document, a web page or a message that tries to give the model new instructions.
How it works
- If the tool's name is not on the allowlist, the answer is
deny. Nothing else is checked. - If the tool is a write tool, one that changes something, and the user has not confirmed, the answer is
confirm. A tool that only looks something up is a read tool. - Otherwise the answer is
allow.
Worked example
Input name = "send" allowed = ["search", "send"] writes = ["send"] confirmed = false Output "confirm"
| Question | Check | Result |
|---|---|---|
| Is send allowed? | allowed holds search and send | yes: go on |
| Is send a write tool? | writes holds send | yes |
| Has the user confirmed? | confirmed is false | no: answer confirm |
| allowed | write | confirmed | answer | |
|---|---|---|---|---|
| not allowed | no | any | any | deny |
| read tool | yes | no | any | allow |
| write, waiting | yes | yes | no | confirm |
| write, confirmed | yes | yes | yes | allow |
- runs
- refused
- waits for the user
The tool is allowed, but it changes something and nobody has approved it yet. So the gate asks for confirmation instead of running it.
Why it matters
The second portfolio project is a support workflow whose send action must pass this gate. Asking the model to behave is not a safety measure; a check in your own code is.
Your turn
Decide what happens to a tool call that the model has proposed.
name- the tool the model wants to run; names are compared exactly, so
Searchis notsearch allowed- the names of the tools this user may use
writes- the names of the tools that change something, such as sending or deleting
confirmed- true if the user has approved this call
- Returns
- One of three strings:
denyif the tool is not allowed,confirmif it is an allowed write tool that has not been confirmed, andallowotherwise.
What JavaScript gives you
list.includes(x)- whether x is one of the items
!flag- true when
flagis false
What Python gives you
x in list- whether x is one of the items
not flag- true when
flagis false
Example 1
Input name = "search" allowed = ["search"] writes = [] confirmed = false Output "allow"
search is allowed and is not a write tool, so no confirmation is needed.
Example 2
Input name = "send" allowed = ["search", "send"] writes = ["send"] confirmed = false Output "confirm"
As in the worked example: allowed, but a write without approval.
Example 3
Input name = "send" allowed = ["search", "send"] writes = ["send"] confirmed = true Output "allow"
The same call after the user approved it.
Example 4
Input name = "delete" allowed = [] writes = ["delete"] confirmed = true Output "deny"
delete is not on the allowlist. A confirmation cannot make a forbidden tool run.
The checks also try
- a forbidden write tool, not confirmed
- a read tool with confirmed set
- a name that differs only by a capital letter
- a write tool that is missing from the allowlist
- a read tool, not confirmed, beside a write tool
- the second of two write tools
- a name that is only part of an allowed name
Hints
Each hint gives away a little more. Open one only when you need it.
Hint 1: Where to start
There are three possible answers. Ask first whether the tool is allowed, and only then whether it is a write that nobody confirmed. The order matters.
Hint 2: The key step
Ask about the allowlist first. Only a tool that passed that question can get
confirmorallow.Hint 3: The outline
If
nameis not inallowed, returndeny. Otherwise, ifnameis inwritesandconfirmedis false, returnconfirm. Otherwise returnallow.
Solution
From here on the page gives the method away. If you are still solving, go back to the hints.
Step by step
- A tool that is not on the allowlist is denied. This check comes first, so that nothing later can turn a forbidden tool into a permitted one, not even a confirmation.
- A write that the user has not confirmed must wait. A wrong search wastes a moment. A wrong send or delete cannot be taken back, so a person approves it first.
- Everything else may run. What is left is either a read tool, or a write tool that the user has confirmed.
The same numbered steps are the comments in the solution.
JavaScript
function solve(name, allowed, writes, confirmed) {
// 1. A tool that is not on the allowlist is denied
if (!allowed.includes(name)) return "deny";
// 2. A write that the user has not confirmed must wait
if (writes.includes(name) && !confirmed) return "confirm";
// 3. Everything else may run
return "allow";
}Python
def solve(name, allowed, writes, confirmed):
# 1. A tool that is not on the allowlist is denied
if name not in allowed:
return "deny"
# 2. A write that the user has not confirmed must wait
if name in writes and not confirmed:
return "confirm"
# 3. Everything else may run
return "allow"
Watch out
- Do not ask for confirmation before checking the allowlist. A forbidden tool would then show the user a confirm button for something that must never run.
- This gate checks the tool's name only. A real system also checks the arguments, and that this user may touch this particular record.
- A confirmation belongs to one exact call. If the arguments change after the user approved, the approval no longer counts.
- In JavaScript:
name in alloweddoes not search a JavaScript array: it asks whethernameis one of its positions. Useallowed.includes(name). - In Python:
falseis not a name in Python. Writenot confirmed, or compare withFalse, which has a capital letter.
Check yourself
Why is a model's tool call treated as a proposal and not a command?
The model may be following instructions hidden in text it read. Only your code knows what this user is allowed to do.
Which check comes first, and why?
The allowlist. A tool that is not allowed must be denied whatever else is true, including a confirmation.