Secure tool boundaries when one agent hands off to another
Tool policy limits which tools the target agent can use during a handoff — so a low-trust gatekeeper cannot escalate privileges by handing off to a powerful automation agent.
Handoffs are secure by default since PR #1848. The target agent only receives tools shared with the source agent. Use tool_policy_mode="passthrough" only when you intentionally need legacy behaviour.
from praisonaiagents import Agent, handoff, tool@tooldef search_tool(query: str) -> str: """Search the knowledge base.""" return f"Results for: {query}"gatekeeper = Agent(name="Gatekeeper", tools=[search_tool])automation = Agent(name="Automation", tools=[search_tool])triage = Agent( name="Triage", handoffs=[handoff(automation)],)triage.start("Find policy docs and hand off to automation")
The user asks the triage agent; tool policy limits what the target can run during handoff.
No extra configuration needed — handoff(target) already enforces intersect mode.
from praisonaiagents import Agent, handoff, tool@tooldef search_tool(query: str) -> str: """Search the knowledge base.""" return f"Results for: {query}"@tooldef execute_code(code: str) -> str: """Run code in a sandbox.""" return "executed"gatekeeper = Agent(name="Gatekeeper", tools=[search_tool])automation = Agent(name="Automation", tools=[search_tool, execute_code])triage = Agent( name="Triage", handoffs=[handoff(automation)], # automation only gets search_tool during handoff)
2
Block dangerous tools
Always strip specific tool names regardless of mode.
from praisonaiagents import Agent, handofftriage = Agent( name="Triage", handoffs=[handoff(automation, blocked_tools=["execute_code"])],)
3
Opt into legacy passthrough
Passthrough gives the target its full tool set (minus blocked_tools). Only use this when the source agent is intentionally delegating more capability than it holds.
Behaviour change (non-breaking API). Before PR #1848, handoffs passed the target agent’s full tool set. After PR #1848, the default is intersection. Existing code runs without changes, but the effective tool set during handoff is narrower. Restore legacy behaviour with one line: tool_policy_mode="passthrough".