Skip to main content

Overview

CrewAI agents can call tools that take real actions. Untrusted text in the model context can change those actions. This page shows how to limit that risk. Related reference: OWASP Top 10 for LLM Applications (prompt injection and excessive agency). CrewAI gives you building blocks: hooks, guardrails, structured outputs, and Flow state. It does not turn these on as a secure default. You must set tools, allowlists, and approval checks in your application code. Human-in-the-loop (HITL) is approval, not a control. It pauses for a person to accept, reject, or comment. It does not authenticate the approver, check their role, or prove they were allowed to decide. This page covers threat model and execution-path behavior. For execution limits (max_rpm, max_iter, max_execution_time), verbosity, and agent settings, see Agents and Customize Agents.

Controls by execution path

CrewAI has two common execution paths. Some controls work on only one path.

agent.kickoff()

Agent.kickoff() runs an AgentExecutor. It does not create a Task or a Crew. It returns LiteAgentOutput. @on methods on a @CrewBase class are added to the global hook list when you create that crew. After that, those hooks can also run on later agent.kickoff() calls in the same process. They are not limited to one crew. See Direct agent interaction.

Crew and Flow

Crew and Flow kickoffs can use Task guardrails, Task human_input, and execution boundary hooks. Tool hooks and LLM hooks also apply.

1. Trusted vs untrusted inputs

Mark every input that reaches the model as trusted or untrusted. Rules:
  1. A label in the prompt does not stop the model from following untrusted text. Use code controls.
  2. Do not add untrusted text to system-level instructions. Keep it in a marked section.
  3. Give each agent only the fields it needs.
  4. Load credentials in tool code from the environment or a secrets manager. Do not put them in prompts, memory, or tool arguments that the model builds.
  5. Enforce policy in code (tool hooks, argument allowlists, guardrails).
The backstory text is a soft control. It does not stop the model from following untrusted text. Use tool hooks and allowlists below to enforce policy. For Crew and Flow inputs, use execution boundary hooks (INPUT). Those hooks do not run on standalone agent.kickoff(). For MCP, see MCP Security.

2. Prompt injection

Prompt injection is untrusted text that tries to override agent instructions. Examples include: ignore prior rules, call tools, leak data, or change the task. Examples:
  • “Ignore all previous instructions and…”
  • “You are now in developer mode…”
  • Encoded or multilingual instructions aimed at filters
  • Requests to reveal the system prompt or forward private context
Do not rely on prompt wording alone. Limit what the agent can do after the model is steered.

3. Indirect prompt injection

Indirect prompt injection places instructions in content the agent fetches later. The instructions are not in the user message. They can sit in a web page, email, PDF, ticket, or RAG chunk. Example:
  1. The user asks the agent to summarize a vendor page and draft an outreach email.
  2. Scrape or search returns page text that says to BCC an attacker and attach API keys.
  3. The agent follows that text when it drafts or sends the email.
What to do:
  • Give research agents read and fetch tools only. Give action agents tools that send, write, or change data only.
  • Pass validated structured state between them. Do not pass raw tool output.
  • Allowlist destinations in tool hooks (domains; block private and link-local ranges where needed).
  • For MCP tool metadata injection, see MCP Security.
Use separate Flow steps for research and send. Then the sender does not receive raw scraped content.

4. Tool abuse

Tool abuse is use of a valid tool in a harmful way. Examples: delete data, export data, spend money, send a message, or run code.
  • Give each agent only the tools its role needs.
  • Constrain arguments in code.
  • Prefer short-lived, per-tool credentials. Do not share one high-privilege account.
tools= on @on is matched after sanitize_tool_name (lowercase, underscored). Use the sanitized tool name (for example send_email, or file_writer_tool for FileWriterTool).
If a tool hook raises any exception other than HookAborted, CrewAI ignores the error and the tool still runs. Only HookAborted (or a legacy False return) blocks the call.
When a tool call is blocked, the tool does not run. The agent receives a message that the tool was blocked. The run continues. POST_TOOL_CALL still runs on blocked calls. Use POST_TOOL_CALL to clean results if you need to. That step is optional. See Tool Hooks.

5. Output validation

Check output before you hand it off, store it, take a side effect, or return it from an API. output_pydantic and output_json check schema shape only. They do not check policy. Add a guardrail callable when you need intent or business rules.

Task path (Crew)

See Task Guardrails.

agent.kickoff() path

Use Agent.guardrail / guardrail_max_retries. You can also pass response_format= on kickoff(). Agent.guardrail does not run during Crew Task execution. String or LLMGuardrail checks work on both the Task path and the kickoff path. Crew and Flow runs can also use execution boundary hooks.

6. Approval gates

HITL is approval, not a control. It asks a person to accept or reject. It does not authenticate that person, check their role, or record that they were authorized. Default console input() accepts whoever is at the keyboard. Require approval before irreversible, expensive, or public actions. Put the pause in code. Do not rely on the prompt alone. Task human_input=True pauses after the agent has run its tools and produced a result. It reviews the final answer before that output is accepted. It does not gate tool execution. An agent on that task can still call destructive tools before any human sees the run. Use it only when post-run output review is enough. See Human input on execution. For approval before a tool runs, use a tool hook and HookAborted:
request_human_input is still approval. It does not validate who typed yes. Add your own identity or policy check if you need that. Other options:
  • Task human_input=True — post-run output review on the Task / Crew path only.
  • ToolCallHookContext.request_human_input — works on agent.kickoff() and Crew runs. By default it uses a blocking console input().
  • @human_feedback / Enterprise HITL webhooks — Human-in-the-Loop, Human Feedback in Flows. Same limit: CrewAI does not verify the approver unless you add that outside these APIs.

7. Limiting delegation

  • allow_delegation defaults to False. Set it to True only when agents must collaborate.
  • You cannot allow delegation to some agents and block it for others. The limits are crew membership and each agent’s tools.
  • Hierarchical process sets manager_agent.allow_delegation = True. Keep high-risk tools on specialist agents. Put those tools behind hooks or approvals.
  • For A2A, prefer A2AClientConfig. Keep trust_remote_completion_status=False unless you want to trust remote completion status. See A2A Agent Delegation.

8. Isolation between agents

  1. Split read and write access across agents. Example: a researcher reads; an actor sends or writes.
  2. Use separate crews or Flow steps for untrusted intake and privileged action.
  3. Pass validated structured state between steps. Do not pass raw tool output.
  4. Limit knowledge with per-agent knowledge_sources. For memory, give the agent its own Memory or MemoryScope, or turn memory off on the crew. On the Task path, memory=False on an agent becomes None. The agent then uses crew memory if the crew has memory enabled.
  5. Run code in an external sandbox such as E2B tools or Modal. Treat sandbox output as untrusted. CodeInterpreterTool is removed. allow_code_execution is deprecated and no longer attaches a code tool.
  6. Connect only to MCP servers you trust. See MCP Security.
See Production Architecture.

Crafting Effective Agents

Roles, goals, and backstories for specialized agents.

Production Architecture

Flows, guardrails, and structured outputs.

Tool Hooks

Policy checks and approval around tool calls.

MCP Security

Trust, metadata injection, and transport for MCP.

Task Guardrails

Validate task outputs before they continue.

Human-in-the-Loop

Human review of task output and tool calls.

Customize Agents

Execution limits, verbosity, and agent settings.