pydantic-ai-toolguard
Deny-first tool authorization for pydantic-ai agents — by AgentsID.
Implements the AgentsID Permission Specification: glob-based tool patterns, parameter conditions, schedule windows, rate limiting, approval workflows, and an append-only audit log.
Install
pip install pydantic-ai-toolguard
Quick Start
from pydantic_ai import Agent
from pydantic_ai_toolguard import ToolGuard, PermissionRule
guard = ToolGuard(rules=[
PermissionRule(tool_pattern="delete_*", action="deny"),
PermissionRule(tool_pattern="*", action="allow"),
])
agent = Agent("openai:gpt-5.2", capabilities=[guard])
The guard hides denied tools from the model and blocks execution if a denied tool is somehow called. Every decision is recorded in the audit log.
How It Works
Rules are evaluated deny-first:
- DENY rules checked first — first matching deny = blocked
- ALLOW rules checked second — first matching allow = permitted (subject to rate limits, schedule, approval)
- Default DENY — no matching rule = blocked
This integrates via three pydantic-ai capability hooks:
prepare_tools— filters denied tools out of the model's viewbefore_tool_execute— evaluates permissions before executionafter_tool_execute— records the result
Features
Glob Pattern Matching
PermissionRule(tool_pattern="*", action="allow") # all tools
PermissionRule(tool_pattern="db_*", action="deny") # prefix match
PermissionRule(tool_pattern="*_readonly", action="allow") # suffix match
Parameter Conditions
PermissionRule(
tool_pattern="query_db",
action="deny",
conditions={"env": "production"}, # only deny production queries
)
Schedule Windows
from pydantic_ai_toolguard import ScheduleConfig
PermissionRule(
tool_pattern="deploy_*",
action="allow",
schedule=ScheduleConfig(
hours_start=9, hours_end=17,
timezone="US/Pacific",
days=("mon", "tue", "wed", "thu", "fri"),
),
)
Rate Limiting
from pydantic_ai_toolguard import RateLimitConfig
PermissionRule(
tool_pattern="search_*",
action="allow",
rate_limit=RateLimitConfig(max=10, per="minute"),
)
Approval Workflows
async def ask_user(tool: str, rule: PermissionRule) -> bool:
return input(f"Allow {tool}? (y/n) ") == "y"
guard = ToolGuard(
rules=[PermissionRule(tool_pattern="transfer_*", action="allow", requires_approval=True)],
on_approval=ask_user,
)
Audit Log
guard = ToolGuard(rules=[...])
# After agent runs...
for entry in guard.audit_log.query(decision="denied"):
print(f"{entry.timestamp} — {entry.tool}: {entry.reason}")
# Export as JSON
print(guard.audit_log.export_json())
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
rules |
Sequence[PermissionRule] |
required | Permission rules |
on_approval |
async (str, PermissionRule) -> bool |
None |
Approval callback |
hide_denied |
bool |
True |
Remove denied tools from model view |
log_decisions |
bool |
True |
Record to audit log |
deny_message |
str |
"Permission denied: {reason}" |
Message returned to model on deny |
Links
- AgentsID — Identity and auth for AI agents
- Permission Specification
- AgentsID Scanner — Security scanner for MCP servers
- pydantic-ai Capabilities
License
MIT
Release files for pydantic-ai-toolguard 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pydantic_ai_toolguard-0.1.0.tar.gz | 12.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydantic_ai_toolguard-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.4 kB
Release files / pydantic_ai_toolguard-0.1.0.tar.gz
| Download URL | pydantic_ai_toolguard-0.1.0.tar.gz |
|---|---|
| Size | 12.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9a91f7fcb68f56221f4e894370e37d21ba09f13dfa6915fc5874ea726b4715c4
|
|
BLAKE2b-256 checksum How to use checksums |
d06c89243d04a578ae6fe90726050fb9033a7354042a7e6d3c773217758e0ae8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.12
|
Release files / pydantic_ai_toolguard-0.1.0-py3-none-any.whl
| Download URL | pydantic_ai_toolguard-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
977ba648512c74859090053bb8aaf515df4e5f2b7785b0a7b2a254ec9bb08708
|
|
BLAKE2b-256 checksum How to use checksums |
5dbb0d62289311418c1d6b876ba1981115d39ada812b566c818c1888606ce136
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.12
|