Skip to main content
The OpenAI Agents SDK (@openai/agents, TypeScript) runs a function tool when the model asks for it. guardTool wraps the tool’s execute so theauth.policy.evaluate runs first. If the policy says no, or says a human must decide, the tool does not run. This page covers wrapping tools, handling an escalate decision with a single use approval, and reading the record afterwards. The general guard options are on Guard agent tools.

Wrap your tool

tool() returns an object that exposes invoke, not execute, so guard the plain definition first and pass the result to tool(). Put errorFunction in the same object so the model sees a refusal as text instead of the run failing.
The tool name is the policy resource, tool:refund, so the agent needs a permission on it. ToolGuardError is the parent of ToolDeniedError, ToolApprovalRequiredError and ToolGuardFailedError. Their messages are written for the model and say not to retry. errorFunction is an option on the tool itself (checked against @openai/agents 0.20.0). This page does not describe what the SDK does with a thrown error when it is missing, so set it on every guarded tool.

Escalate and approve once

The large tier above requires approval from 1000 USD. For a refund of 5000 the tool does not run. The guard opens an approval request, calls onEscalate with its id, and the model receives:
When a person decides, approve the request and set the id the guard should spend:
The next call with the same agent, action and resource runs and spends the approval. A third call gets this instead:
The approval is single use. Return the id from approvalId only for the call that was approved, then clear it. In a real app, look it up from the request that belongs to this run instead of a module variable. To drive the tool by hand, as the example does, call invoke with a run context and the arguments as a JSON string:

Read the decision record

Every decision lands in the agent’s audit log. With audit.tamperEvident on, each row joins a per agent hash chain. replayAgent returns the timeline and verifies the chain in the same call.
For the run above it prints:
The refund that ran (#5) records the approver and the reason APPROVAL_CONSUMED. The replay (#6) is a separate denied row, so the record shows both what was allowed and what was refused. Approval requests and answers also appear in the timeline as events that are not chained. Two things to know:
  • Audit rows are written in the background. A replay read in the same tick as the call can miss the last rows, so the example waits a moment.
  • Pass the same hmacKey you configured. It is needed to verify an HMAC chain.
See Audit trail for the chain format, break reasons and export.

Run the example

The repo has a runnable version at examples/openai-agents-guard. It needs no model and no API key. It is a plain folder, not a workspace package, so install the dependencies listed in its README in a scratch project.
Last modified on October 17, 2026