Skip to main content

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 BlockedToolCall with 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:

  1. Argument checking — are all required arguments present and correctly typed?
  2. Block rules — does any block rule condition return True? If so, raise BlockedToolCall.
  3. Escalation rules — does any escalation rule condition return True? If so, call the approval handler. If denied, raise BlockedToolCall.
  4. Execute — all checks passed, run the real tool function.
  5. Record — log the call to AgentManager.history.

Documentation


Examples

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

toolfence-0.1.0.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

toolfence-0.1.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

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

Hashes for toolfence-0.1.0.tar.gz
Algorithm Hash digest
SHA256 239dc898c8146fc5e15bd44da6a55338d1b0d2381617d3bc3be3bb242ec67f02
MD5 ff622eefd0cbb6e332399b70592ca415
BLAKE2b-256 66da4074cb9e3083494aa44a4fe1ed18693b167375c04c969fefe2d6cb874a30

See more details on using hashes here.

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

Hashes for toolfence-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 16511681c6fea395a1d4761c0de2d94d3906280b2c3baed289daf3442e458f52
MD5 eee2fe2490feaee06efdef2add419e2a
BLAKE2b-256 7c3ae5292174d775f69325c63016745917956929ab541fedfad01e7018edd845

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page