OpenAI Agents authorization gate
Human approval gates for OpenAI Agents SDK tool calls.
OpenAI Agents SDK agents execute handoffs and tool calls autonomously. Permission Protocol adds an authorization layer — a signed receipt that must exist before any consequential tool call runs. The agent pauses at the gate, a human approves, and the receipt travels with the action as cryptographic proof of authorization.
The problem
OpenAI Agents SDK's guardrail system lets you validate inputs and outputs, but it doesn't produce authorization receipts or require human approval before execution. Permission Protocol wraps tool calls in an external gate that issues a signed receipt — proof that a human explicitly authorized the action before it ran.
Code example.
Before — no gate
from agents import function_tool
@function_tool
def execute_database_migration(migration_id: str) -> str:
"""Run a database migration."""
# No authorization — agent can run migrations freely
return run_migration(migration_id)After — authorization gate
from agents import function_tool
from permission_protocol import require_approval
@function_tool
@require_approval(
action="database_migration",
resource_fn=lambda args: f"db:production:{args['migration_id']}",
policy="database-mutation-gate",
)
def execute_database_migration(migration_id: str) -> str:
"""Run a database migration."""
# Agent waits here until a receipt is issued
return run_migration(migration_id)
# SDK output when gate fires:
# → Authorization required for: database_migration
# → db:production:migration_0047
# → Approval link: https://app.permissionprotocol.com/approve/9bc14
# → ✓ Receipt pp_r_a2f91c issuedHow it works.
Decorate the tool
Add @require_approval to any @function_tool. The decorator intercepts calls before the tool function body executes and routes them through Permission Protocol.
Reviewer sees action details
The configured reviewer receives an approval link showing the tool name, arguments, agent ID, and policy. They approve or reject before execution continues.
Receipt issued, tool executes
Approval triggers a signed receipt. The decorator verifies it and allows the tool body to run. The receipt is logged with the run for audit. Rejection raises an exception the agent can handle.
The receipt it produces.
{
"receipt_id": "pp_r_a2f91c88",
"action": "database_migration",
"resource": "db:production:migration_0047",
"actor": "openai-agent-orchestrator",
"approved_by": "[email protected]",
"policy": "database-mutation-gate",
"timestamp": "2026-05-16T09:41:03Z",
"signature": "pp_sig_ZxT2a..."
}FAQ.
Does this work with multi-agent handoffs?
Yes. Receipts travel with the action context. When an orchestrator agent hands off to a subagent that calls a gated tool, the authorization requirement fires at the subagent's tool call, not the handoff itself.
Can I gate handoffs between agents?
Yes. You can wrap an agent's handoff action in a require_approval decorator to require a receipt before the orchestrator transfers control to a subagent with elevated permissions.
How does this work with OpenAI's guardrails?
They're complementary. OpenAI guardrails validate inputs and outputs. Permission Protocol gates whether a specific action was explicitly authorized. You can run both — guardrails as a sanity check, PP as the authorization layer.
Does the receipt persist across runs?
Yes. Receipts are stored and retrievable by ID. If you resume an agent run, the receipt from the prior authorization is still valid (unless it has expired) and does not require a new approval.
Get the gate running today.
Free for individual developers. The quickstart takes under five minutes. Enterprise plans for teams that need audit trails, policy management, and self-hosted authority nodes.