Deterministic runtime security for AI agent tools
Project description
ToolFence
Deterministic runtime security for AI agent tools.
LLMs can hallucinate and be prompt-engineered, allowing faulty agent actions to slip through. ToolFence helps solve this by enforcing strict and deterministic rules.
ToolFence is a lightweight Python framework that sits between your LLM and your tool functions. When an agent calls a tool, ToolFence intercepts the call, evaluates your rules, and either passes it through, blocks it, or escalates it for user approval — all before your tool function runs. Rules are Python code, not LLM instructions, so they cannot be overridden by a clever prompt.
Why ToolFence
LLMs are good at deciding what to do. They are not reliable enforcers of what is allowed. A well-crafted prompt can convince an LLM to ignore its own safety instructions. ToolFence allows a quick and simple way to enforce policy at the code layer — outside the prompt, outside the model, and outside the reach of any user input.
User prompt → LLM → tool call → [ToolFence] → tool execution
↑
deterministic rules run here
Installation
pip install toolfence
Quick example
from toolfence import secure, AgentManager, Rule, BlockedToolCall
manager = AgentManager()
manager.set_default_approval_handler(lambda ctx: input(f'Do you approve {ctx.tool_call.tool} to execute? ') == 'yes')
manager.set_rules(
tool = "transfer_funds",
rules=[
# Hard block — never transfer over $10,000
Rule(
id="transfer-hard-limit",
description="Transfers over $10,000 are never permitted.",
condition=lambda ctx: ctx.tool_call.arguments.amount > 10000,
action="block"
),
# Escalate — transfers over $1,000 need user approval
Rule(
id="transfer-large-escalate",
description="Transfers over $1,000 require approval.",
condition=lambda ctx: ctx.tool_call.arguments.amount > 1000,
action="escalate"
),
],
)
@secure(manager)
def transfer_funds(from_account: str, to_account: str, amount: float) -> dict:
return {"status": "transferred", "amount": amount}
manager.validate()
try:
transfer_funds("ACC-001", "ACC-002", 15000.0)
except BlockedToolCall as e:
print(e.message) # "Transfers over $10,000 are never permitted."
Features
- Hard block rules — write Python conditions that unconditionally prevent a tool call from executing
- Escalation rules — pause execution and require user approval before proceeding
- Evidence verification — load trusted data (e.g., database, API) and verify LLM-supplied arguments against it, catching hallucinations and prompt injection
- Argument checking — validate argument presence and types before rules even run
- Async support — works with async tools and async approval handlers
- Config validation — catch misconfigured rules, missing handlers, and configuration mistakes before your agent runs
- Structured errors — every blocked tool call raises
BlockedToolCallwith a message for your agent's LLM - Full history — every tool call (passed or blocked) is recorded in
AgentManager.history - Easy Integration — easily integrates with other frameworks and workflows such as LangChain
How it works
@secure(manager)
def my_tool(arg: str) -> dict: ...
Decorating a function with @secure registers it with the AgentManager and wraps it with the ToolFence interceptor. Every call to my_tool now runs through:
- Argument checking — are all required arguments present and correctly typed?
- Block rules — does any block rule condition return
True? If so, raiseBlockedToolCall. - Escalation rules — does any escalation rule condition return
True? If so, call the approval handler. If denied, raiseBlockedToolCall. - Execute — all checks passed, run the real tool function.
- Record — log the call to
AgentManager.history.
Documentation
Examples
examples/example_basic.py— minimal setup with block and escalation rulesexamples/example_evidence.py— evidence verification and prompt injection prevention
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file toolfence-0.1.0.tar.gz.
File metadata
- Download URL: toolfence-0.1.0.tar.gz
- Upload date:
- Size: 9.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.13.1 Darwin/23.2.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
239dc898c8146fc5e15bd44da6a55338d1b0d2381617d3bc3be3bb242ec67f02
|
|
| MD5 |
ff622eefd0cbb6e332399b70592ca415
|
|
| BLAKE2b-256 |
66da4074cb9e3083494aa44a4fe1ed18693b167375c04c969fefe2d6cb874a30
|
File details
Details for the file toolfence-0.1.0-py3-none-any.whl.
File metadata
- Download URL: toolfence-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.13.1 Darwin/23.2.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16511681c6fea395a1d4761c0de2d94d3906280b2c3baed289daf3442e458f52
|
|
| MD5 |
eee2fe2490feaee06efdef2add419e2a
|
|
| BLAKE2b-256 |
7c3ae5292174d775f69325c63016745917956929ab541fedfad01e7018edd845
|