AgentGuard – fail-closed approval gateway for AI agent tool calls

yhouseff_dev1 pts0 comments

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.

approval decision fail tool return allowed

Related Articles