GitHub - moon2022alakhali-commits/agentguard: Fail-closed approval gateway for AI agent tool calls · GitHub
/" data-turbo-transient="true" />
Skip to content
Type / to search
Sign in<br>Sign upAppearance settings
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
moon2022alakhali-commits
agentguard
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
main
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>1 Commit<br>1 Commit
README.md
README.md
agentguard_demo.py
agentguard_demo.py
demo.gif
demo.gif
View all files
Repository files navigation
AgentGuard
A fail-closed approval gateway for AI agent tool calls.
If your agent can call tools that do real things (delete data, send payments, revoke access, hit an API with side effects), you eventually want a layer that pauses risky calls until a human approves them -- and denies by default if nothing approves it. Not "log and hope." Actually blocked.
This repo is a minimal, dependency-free demo of that gateway. It's not a full SDK integration yet -- it's the core logic, extracted from a script I run internally, packaged so you can see exactly how it behaves.
How it works
SAFE_TOOLS -- whitelisted, auto-approved, no human needed.
DESTRUCTIVE_TOOLS -- always requires explicit human approval before running.
Anything else (unknown tool, no approval, approval times out) -- denied automatically . Fail-closed, not fail-open.
Run it
python3 agentguard_demo.py
No dependencies. Just the standard library.
The core logic
Decision:<br>if call.name in SAFE_TOOLS:<br>return Decision(allowed=True, reason="whitelisted_safe_tool")
if call.name in DESTRUCTIVE_TOOLS and not approved_by_human:<br>return Decision(allowed=False, reason="destructive_action_unapproved")
if approved_by_human:<br>return Decision(allowed=True, reason="explicit_human_approval")
# Default: unknown tool, no approval -> deny. This is the fail-closed part.<br>return Decision(allowed=False, reason="unknown_tool_no_approval")">def approval_gateway(call: ToolCall, *, approved_by_human: bool = False) -> Decision:<br>if call.name in SAFE_TOOLS:<br>return Decision(allowed=True, reason="whitelisted_safe_tool")
if call.name in DESTRUCTIVE_TOOLS and not approved_by_human:<br>return Decision(allowed=False, reason="destructive_action_unapproved")
if approved_by_human:<br>return Decision(allowed=True, reason="explicit_human_approval")
# Default: unknown tool, no approval -> deny. This is the fail-closed part.<br>return Decision(allowed=False, reason="unknown_tool_no_approval")
Why
Most agent frameworks let you add approval hooks, but the default when nothing responds is usually allow (fail-open) or just a log line. That's backwards for anything destructive. This flips the default.
Status
Early. This is the extracted core, not a packaged library yet -- no LangChain/OpenAI Agents SDK adapter, no persistence, no async approval flow (Slack/Telegram bot, etc.) included here. If that's useful to you, open an issue or a discussion -- trying to figure out if this is worth building out further and what the priority integration should be.
No dependency on LangChain or any specific agent framework. Drop the same pattern in front of whatever tool-calling loop you already have.
About<br>Fail-closed approval gateway for AI agent tool calls<br>Resources<br>Readme<br>Activity<br>Stars<br>0 stars<br>Watchers<br>0 watching<br>Forks<br>0 forks<br>Report repository
Releases
Packages
Contributors
Languages
You can’t perform that action at this time.