OpenAI Function Calling Integration
Integrate cryptographic human approval into OpenAI function calling loops and the OpenAI Agents SDK.
The signedapproval-openai package provides a ready-to-use OpenAI tool definition (signed_approval_tool) and a handler function (handle_approval) that blocks until a real human authenticates on their phone and approves the action.
The tool works with both the classic function calling API (client.chat.completions.create) and the OpenAI Agents SDK (openai-agents). Every approval is backed by an Ed25519 signature — unforgeable, offline-verifiable proof.
Install the package
pip install signedapproval-openai
# with OpenAI SDK:
pip install "signedapproval-openai[openai]"Get your API key
Create an API key in the Dashboard → API Keys and store it as an environment variable.
export SIGNEDAPPROVAL_API_KEY="sa_live_..."Function calling loop
Add signed_approval_tool to your tools list and call handle_approval in your tool-call loop:
import os
import json
from openai import OpenAI
from signedapproval_openai import signed_approval_tool, create_approval_handler
client = OpenAI()
handler = create_approval_handler(api_key=os.environ["SIGNEDAPPROVAL_API_KEY"])
messages = [{"role": "user", "content": "Deploy the API to production."}]
while True:
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=[signed_approval_tool],
tool_choice="auto",
)
choice = response.choices[0]
if choice.finish_reason == "tool_calls":
messages.append(choice.message)
for tool_call in choice.message.tool_calls:
if tool_call.function.name == "request_human_approval":
args = json.loads(tool_call.function.arguments)
# Blocks until human approves on phone
result = handler(args)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result,
})
else:
print(choice.message.content)
breakOpenAI Agents SDK
Use a @function_tool decorator to wrap the handler for the Agents SDK:
import os
from agents import Agent, Runner, function_tool
from signedapproval_openai import handle_approval
@function_tool
def request_human_approval(action: str) -> str:
"""
Request cryptographic human approval before performing a high-stakes action.
Call this before any irreversible, financial, or destructive operation.
"""
return handle_approval(
{"action": action},
api_key=os.environ["SIGNEDAPPROVAL_API_KEY"],
)
agent = Agent(
name="Deployment Agent",
instructions=(
"You manage production deployments. Always call request_human_approval "
"before deploying, deleting data, or sending external communications."
),
tools=[request_human_approval],
)
result = Runner.run_sync(agent, "Deploy payment-service v2.1.0 to production.")
print(result.final_output)Tool definition reference
The exported signed_approval_tool (also aliased as OPENAI_TOOL_DEFINITION) is a plain Python dict in OpenAI's JSON Schema tool format:
{
"type": "function",
"function": {
"name": "request_human_approval",
"description": "Request cryptographic human approval ...",
"parameters": {
"type": "object",
"properties": {
"action": {
"type": "string",
"description": "Human-readable description of the action requiring approval",
},
"context": {
"type": "object",
"description": "Optional metadata shown to the approver",
"additionalProperties": True,
},
},
"required": ["action"],
},
},
}Handler return value
handle_approval() and create_approval_handler() both return a JSON string suitable for passing directly back to the model as the tool result:
{
"request_id": "req_01jq...",
"decision": "approved",
"approved": true,
"signature": "base64...",
"public_key_id": "key_abc123",
"verified": true
}When the decision is rejected or expired, approved and verified will be false and signature will be null. The model can read this and abort the planned action.
contextparameter to pass structured metadata to the approver — for example, the target environment, amount, or affected records. This appears in the approval request on the approver's phone.create_approval_handler() over calling handle_approval()directly — it pre-binds your API key and TTL so you don't repeat them on every call.