BlogTechnical

Reviewing OpenAI Agents SDK deployments — the handoff guardrail gap

Handoffs run through a different pipeline than tool calls, and the SDK's own documentation says tool guardrails don't apply to them. What that means for reviewing a multi-agent handoff chain.

Drel Research9 min read

The OpenAI Agents SDK (the production successor to the earlier Swarm framework) is built around four primitives: Agents (LLM-powered entities with instructions and tools), Tools (functions an agent can call), Handoffs (transfers of control from one agent to another), and Guardrails (safety checks on inputs and outputs). A Runner drives the execution loop; Sessions carry state across turns.

Of the four primitives, Handoffs is the one worth a review's close attention — not because it's poorly designed, but because its relationship to Guardrails is easy to misread.

OpenAI Agents SDK, briefly

A handoff is not a function call that returns a value to the caller — once an agent hands off, the receiving agent owns the conversation for the rest of that run. This is what makes multi-agent specialization practical: a triage agent can hand a request to a billing agent, which hands it to a refunds agent, each with narrower instructions and tools than a single do-everything agent would need.

The execution loop automatically handles the call-tool-respond cycle, including chains where one tool result triggers another tool call. Functions decorated with @function_tool get their JSON schema generated from type hints, and their description from the docstring the model reads when deciding whether to call them.

The guardrail pipeline doesn't cover everything

Guardrails run on custom function-tool invocations: input guardrails before execution, output guardrails after, in parallel with the agent so they can short-circuit on a violation. That coverage is solid for the case it's built for. It is not universal coverage across every way an agent can act:

Which execution paths the tool-guardrail pipeline actually covers

Execution pathGuardrail coverage
A custom function tool, called directly by the current agentCovered — input guardrails run before execution, output guardrails run after.
A handoff to another agentNot covered by tool guardrails — handoffs run through a separate handoff pipeline. Input guardrails apply only to the first agent in the chain; output guardrails apply only to the agent producing the final output.
A hosted tool or other built-in execution toolNot covered — these don't use the tool-guardrail pipeline at all, by the SDK's own documentation.
An agent exposed to another agent via Agent.as_tool()Not covered — this pattern doesn't currently expose tool-guardrail options directly.
By the SDK's own documentation: if a workflow includes managers, handoffs, or delegated specialists, tool guardrails — not agent-level input/output guardrails alone — are what's needed to check before and after each custom function-tool call. Relying on a single top-level guardrail to cover a multi-agent handoff chain is a documented gap, not an edge case.

Why this matters for multi-agent systems specifically

A single-agent, single-tool deployment mostly avoids this issue — there's one agent, its guardrails apply to its own tool calls, and that's the whole system. The gap opens specifically as systems grow into the pattern the SDK is designed to make easy: a chain of specialized agents handing a task to each other. An input guardrail configured on the first (triage) agent does not automatically protect every agent downstream of a handoff — by design, it only applies to that first agent. A malicious or malformed input that passes the triage agent's check can still reach a downstream agent's tools without a second check, unless that downstream agent has its own guardrails configured explicitly.

This is the same shape of gap as the collective-escalation problem documented in the recent OpenAI/Hugging Face agent incident: a control that works correctly at one point in a system doesn't automatically extend to every agent instance or every handoff downstream of it. A review has to check the whole chain, not the first link.

A related incident — but not this SDK

No CVE or security advisory has been published against the open-source openai-agents-python or JS package itself. A real, disclosed incident exists nearby and is worth naming precisely so it doesn't get misattributed: “AgentForger,” disclosed by Zenity Labs in July 2026, was a cross-site request forgery flaw in ChatGPT's Agent Builder product — a separate, consumer/workspace-facing tool for building agents, not the open-source SDK developers build on. Two URL parameters in Agent Builder (template_name and an auto-executing initial_assistant_prompt) let a single crafted link silently create, publish, and schedule a rogue Workspace Agent inheriting a logged-in employee's connected-app permissions — Outlook, Gmail, Slack, Google Drive, SharePoint, Teams. OpenAI fixed it within four days of disclosure.

Optimistic execution vs. default-deny

The Agents SDK's guardrail model is worth contrasting directly against Claude Agent SDK's permission model, because the two make close to opposite default choices. The Agents SDK runs optimistically: the main agent proceeds and generates output while guardrails check it in parallel, raising an exception to halt only after a violation is detected. Claude Agent SDK is default-deny: a PreToolUse hook can block a tool call before it ever executes, which is the property an auditor looks for when a tool's side effect can't be undone.

Neither model is wrong in the abstract — they're suited to different jobs. Optimistic, parallel guardrails fit a system oriented around validating what crosses a boundary between conversational agents. Pre-execution blocking fits a system pointed at a live filesystem or codebase, where the cost of an action executing before it's checked is a file already written or a command already run. A review has to know which model a given deployment is actually getting, since “a guardrail is configured” means something different in each.

Review checklist

For any system built on the OpenAI Agents SDK, a design-time review should be able to answer:

  • Does every agent in a handoff chain have its own tool guardrails configured, or only the first (triage) agent?
  • For hosted tools and built-in execution tools, what validates their inputs and outputs, given they don't use the tool-guardrail pipeline?
  • Where Agent.as_tool() is used, what compensating control exists in place of tool guardrails, which aren't currently exposed for that pattern?
  • Is there an explicit list of which agent in the chain is the final output producer — since output guardrails apply only there, not to intermediate agents?
  • Are tracing and Sessions enabled and reviewed, so a handoff chain's actual path can be reconstructed after the fact?

See human-in-the-loop agentic controls for where a human-review step belongs relative to a handoff chain like this one, and multi-agent system security review for the framework-agnostic version of this checklist.

Sources

Blog

Get new posts in your inbox

AI security review, OWASP Agentic Top 10, ISO 42001 evidence, and what AI Committees actually need. No cadence promises — we publish when there's something worth reading.

Review a multi-agent handoff chain before it ships

Guardrail coverage across every agent in the chain, not just the first — mapped to a disposition your AI Committee can act on before deployment.

A note on scope: Drel reviews assessed systems against documented architecture, configuration and intent. It does not ingest live telemetry from production environments. Dispositions reflect the assessed system at the time of review and the re-assessment triggers that govern when the disposition must be revisited.