Skip to main content
Web search and other external tools wrap results in safety markers — the model treats them as data, not instructions.
The user searches the web; external tool output is wrapped so the model treats it as data.
The hook-layer scanner protects agent prompts and tool outputs. The agent↔agent boundary is protected separately by the Inter-Agent Provenance envelope — enabled by default on every create_subagent_tool call.

Quick Start

1

Simple Usage

Built-in search tools are protected automatically:
2

With Configuration

Mark custom tools as external:

How It Works

Auto-protected built-ins include duckduckgo, web_search, tavily_search, scrape_page, fetch_url, and others in the external tools set. MCP tools can be marked at registration time. Outbound tool results are wrapped in <external_tool_result>; inbound webhook and hook payloads are wrapped in <external_request_payload> — same idea, opposite direction. See Untrusted Request Fencing for the ingress boundary.
The hook-level scanner does not read a trust label off the payload. Prompt strings passed through before_llm_call are scanned unconditionally so a forged _source field cannot bypass the checks. Tool-level trust (external vs internal tool) is still governed by how the tool is registered — that hasn’t changed.

Configuration Options


Programmatic Injection Defense

The auto-wrap above protects tool outputs. To also scan all agent prompts at the hook layer, enable the injection-defense pipeline:
This registers hooks on BEFORE_TOOL and BEFORE_AGENT that scan inputs through a 6-check pipeline and block critical threats.
enable_injection_defense() registers on the process-global praisonaiagents.hooks registry — the policy applies to every Agent in the process. In a multi-tenant host (e.g. praisonai serve) do not rely on it for per-tenant isolation. To scope or tear down later, keep the returned hook_ids and remove them via praisonaiagents.hooks.remove_hook:

One-liner (both defenses)

enable_security() is the same story: it registers process-global hooks. One tenant’s extra_patterns would apply to every tenant sharing the process. Use per-request add_hook in multi-tenant hosts, or hold the returned hook IDs and remove them at teardown.

Best Practices

Web APIs, scraping, MCP servers you do not control, and third-party feeds should use trust_level="external".
Removing <external_tool_result> tags breaks the model’s boundary between data and instructions.
Wrapping cost is minimal; under-marking exposes you to injection.
Combine with Tool Circuit Breaker and input validation for defence in depth.
The hook registry is process-global. In multi-tenant servers, hold the returned hook IDs and remove them via praisonaiagents.hooks.remove_hook on teardown, or add per-request hooks manually instead of using the enable_* one-liner.

Related defence. Tool outputs get wrapped in <external_tool_result> markers (this page). Inbound webhook and hook payloads get the ingress counterpart — wrapped in <external_request_payload>, described in Untrusted Request Fencing. Platform display names and group titles interpolated into the [{sender}] attribution prefix get a different treatment — collapse-and-strip — described in Sender Attribution Sanitisation.

Inter-Agent Provenance

The agent↔agent counterpart — sub-agent output labelled as data

Untrusted Request Fencing

The ingress counterpart — webhook and hook payloads fenced as data

Attribution Sanitisation

Neutralise untrusted platform display names in the prompt prefix

Tool Circuit Breaker

Automatic tool failure detection and recovery

Security Overview

Complete security features and best practices