A CrewAI crew is a group of agents that call tools, MCP servers and each other with the credentials of the process that runs it, so one over-permissioned tool or one untrusted MCP server can turn a research crew into an unattended actor with production access. CrewAI has changed quickly: its built-in code interpreter has been removed, the agent code execution settings are deprecated, MCP servers can now be attached directly to agents, and tool call hooks give a real enforcement point. This guide covers the four controls that matter most in a CrewAI deployment: the identity and credentials the crew runs with, tool permissions and approval, secrets handling, and telemetry and tracing. It is written for engineers and security reviewers putting CrewAI crews and flows into production. Cross-framework topics, including sandboxing generated code, are in the Securing Agent Frameworks Guide. Facts are from the CrewAI documentation for version 1.15.32 in the project's GitHub repository, checked on 28 October 2026.
Key takeaways
- A crew has no identity of its own. Every tool authenticates with keys from the environment or its own configuration, so give each crew its own scoped credentials rather than a developer's keys.
- Use
PRE_TOOL_CALLhooks as the policy point. A hook can rewrite tool input or raiseHookAbortedto block a call, and post-call hooks see every attempt, including blocked ones. - Trust decides MCP risk. CrewAI warns that a malicious MCP server can inject instructions through tool metadata simply by being connected and listed, even if no tool is called.
- Do not put keys in MCP URLs. String references such as a server URL with an
api_keyquery parameter put the secret in logs and traces; use structured configurations with headers. - Decide telemetry and tracing deliberately. Anonymous telemetry is on by default,
share_crewsends task descriptions and backstories, and AMP tracing is controlled separately byCREWAI_TRACING_ENABLED.
Where CrewAI's security boundaries are
CrewAI organises work as agents (a role, goal, backstory, LLM and tools), tasks (work with an expected output, optional guardrails and optional human input), crews (agents and tasks run sequentially or hierarchically) and flows (event-driven orchestration with state). All of them run inside your Python process. The boundaries you control are:
| Boundary | CrewAI mechanism | What can go wrong | Control |
|---|---|---|---|
| Model access | llm on each agent, keys from environment variables | Shared or personal provider keys, cost abuse | One scoped key per crew and environment, spend limits at the provider |
| Tools | tools on agents or tasks, custom BaseTool classes | Tool reaches more than the task needs | Per-task tool lists, least-privilege credentials, hooks |
| MCP servers | mcps field, MCPServerStdio, MCPServerHTTP, MCPServerSSE, or MCPServerAdapter | Malicious server, metadata injection, local command execution | Trusted servers only, tool_filter, pinned packages |
| Delegation | allow_delegation (default False) | An agent hands work to one with stronger tools | Leave off unless the crew design needs it |
| Code execution | allow_code_execution, code_execution_mode (deprecated); CodeInterpreterTool removed | Generated code runs on the host | External sandbox service; see the sandboxing guide |
| Memory and knowledge | Unified Memory with hierarchical scopes, knowledge_sources | One agent reads another's private context | Scoped views per agent (for example memory.scope("/agent/researcher")) |
| Telemetry and tracing | CREWAI_DISABLE_TELEMETRY, share_crew, CREWAI_TRACING_ENABLED | Task content leaves the organisation | Explicit settings per environment |
Identity and credentials
CrewAI's examples set provider and tool keys as environment variables (for instance OPENAI_API_KEY and SERPER_API_KEY), which is fine for a laptop and a problem in production if every crew shares the same keys. Treat each deployed crew as a non-human identity with its own credentials. See the Non-Human Identity (NHI) Guide.
- Per-crew keys: issue separate model and tool keys for each crew and environment, so usage, cost and revocation map to one crew. A shared key makes a leak a whole-estate incident.
- Workload identity where the tool supports it: custom tools that call cloud APIs should use the platform's workload identity (managed identity, IAM role, service account federation) instead of a stored key. See the Workload Identity Federation Guide.
- Scope tool credentials to the task: a research crew's search tool needs a search API key, not a GitHub token. Where one tool needs write access, give it to a dedicated agent with that tool alone.
- Least privilege for MCP credentials: CrewAI's MCP guidance says credentials used by
MCPServerAdaptershould have only the permissions the required tools need. - Keep humans' keys out: a crew running on an engineer's personal token outlives the engineer's role and blurs audit trails.
The cost of one over-privileged token is clear from the CrewAI "Uncrew" Flaw 2025: a failed provisioning status check on CrewAI's own platform returned an error payload containing a GitHub token that the researchers said had administrative privileges across CrewAI's GitHub organisation. CrewAI fixed it within hours; the lessons are to redact secrets from errors and to scope tokens narrowly.
Tool permissions, hooks and human approval
CrewAI's tool call hooks run at two interception points: PRE_TOOL_CALL before every tool execution and POST_TOOL_CALL after it. Register them with the @on decorator (the older @before_tool_call and @after_tool_call decorators still work and share the same chain).
| Need | Mechanism | Notes |
|---|---|---|
| Block a call | Raise HookAborted in a PRE_TOOL_CALL hook | The tool does not run; the agent receives "Tool execution blocked by hook" and the run continues |
| Validate or sanitise input | Mutate ctx.tool_input in place | Replacing the dictionary instead of editing it means the tool never sees the change |
| Human approval for a tool | ctx.request_human_input(prompt, default_message) in a pre-call hook | Console-based; for services, route approvals to your own queue |
| Redact output | Return a replacement string from a POST_TOOL_CALL hook | raw_tool_result keeps the original object |
| Audit every attempt | POST_TOOL_CALL hook logging tool_name, agent, task | Fires on blocked calls too |
| Review a task's final answer | human_input=True on the task | Reviews output, not individual tool calls |
| Validate output before the next task | guardrail or guardrails, guardrail_max_retries (default 3) | Use for format and policy checks on what flows between agents |
- Allowlist, do not denylist: a pre-call hook that permits named tools with argument checks for each is far stronger than one that searches for bad strings.
- Bound autonomy:
max_iter(default 20),max_execution_time,max_rpmandmax_retry_limit(default 2) cap runaway loops and cost. Set them explicitly for production agents. - Keep delegation off by default: with
allow_delegation=Truean agent can hand work to another agent, which may hold stronger tools. Enable it only where the crew design needs it and check the delegate's tools. - Tool caching: tool results are cached by default (
cache=True). Usecache_functionor turn caching off for tools whose results are user-specific or sensitive.
See the OWASP LLM Top 10 LLM06 Excessive Agency Guide and the AI Agent Tool and Plugin Security Guide.
MCP servers in CrewAI
CrewAI's MCP security page opens with one rule: only connect agents to MCP servers you fully trust. It lists the risks as arbitrary code execution (especially over stdio), data exposure, unintended API calls and prompt injection, and calls out injection through tool metadata as the subtle one: names and descriptions enter the model's context as soon as tools are listed.
- Filter tools: use
create_static_tool_filter(allowed_tool_names=[...])or theserver#toolstring syntax so the agent sees only the tools it needs. Fewer listed tools also means less untrusted metadata in context. - Pin stdio servers:
MCPServerStdio(command="npx", args=["-y", ...])fetches and runs a package with the agent's operating system rights. Pin versions and run the process with minimal file system access. - Remote servers over HTTPS with headers: use
MCPServerHTTPwith credentials inheaders. Avoid string references that carry?api_key=in the URL. - Local development servers: CrewAI advises binding them to
127.0.0.1, validatingOriginandHostheaders and requiring authentication, as defences against DNS rebinding. - Watch OAuth behaviour: CrewAI describes confused deputy and token passthrough risks in MCP proxies; be cautious when a server triggers unexpected or broad OAuth consent.
- Connected integrations by slug: references such as
"github"or"stripe#list_invoices"use integrations connected in your CrewAI account; review which account connections exist and what scopes they hold.
See the MCP Security Guide.
Secrets handling
- Load from a secret store at start-up: inject provider and tool keys from your platform's secret manager into the process environment; do not commit
.envfiles or bake them into images. - Do not put secrets in roles, goals, backstories or task text: these flow into prompts, traces and, with
share_crew, to CrewAI. - Return minimal tool output: a tool that returns a raw API response can hand the model a token. A
POST_TOOL_CALLhook can redact before the agent sees the result. - Return generic errors: the Uncrew flaw was a detailed error carrying a credential. Catch exceptions in custom tools and log detail internally only.
- Stdio
envmaps: theenv={"API_KEY": ...}parameter onMCPServerStdioshould read from your secret store, never a literal.
See the API Key Management Guide.
Telemetry, tracing and logging
| Setting | Default | Effect | Production choice |
|---|---|---|---|
| Anonymous telemetry | On | Versions, crew and agent metadata, role names, tool names, LLM attributes, exception class names (not messages) | Disable with CREWAI_DISABLE_TELEMETRY=true if policy forbids any outbound telemetry |
share_crew | Off | Adds goals, backstories, task descriptions, expected outputs and inputs; CrewAI warns this may include personal data | Keep off |
OTEL_SDK_DISABLED=true | Unset | Disables CrewAI's exporter and all OpenTelemetry in the process | Use only if you do not need your own tracing |
| AMP tracing | Opt-in; a first run may prompt "Share this execution trace with CrewAI? [y/N]" | tracing=True or CREWAI_TRACING_ENABLED=true sends agent decisions, tool usage and LLM calls to the CrewAI AMP platform | Enable only if AMP is an approved processor; OTEL_SDK_DISABLED does not turn it off |
CrewAI's own telemetry runs on a private TracerProvider, so it neither receives your application spans nor appears in your back end. For your own audit trail, use an observability integration or a POST_TOOL_CALL hook that logs tool name, agent role, task, outcome and whether it was blocked, and send those events to your SIEM. Do not put personal data in agent roles or tool names, since CrewAI collects them by default.
Metrics: crews running on shared or personal keys (target zero); tools covered by pre-call allowlist hooks; blocked tool calls per week; MCP servers with unpinned versions; environments with share_crew or AMP tracing on without approval; agents with delegation enabled.
Rollout approach
- Inventory: list crews and flows, their LLM keys, tools, MCP servers, delegation and code execution settings, and telemetry and tracing choices.
- Remove deprecated execution: replace
allow_code_executionand any remainingCodeInterpreterTooluse with an external sandbox. - Add hooks in log-only mode: register a
POST_TOOL_CALLlogging hook and aPRE_TOOL_CALLhook that records would-be blocks without raising. Run for a week in staging. - Enforce: switch the pre-call hook to raise
HookAbortedfor calls outside the allowlist. Roll back by returning the hook to log-only. - Split credentials: move each crew to its own keys and tool identities, then revoke the shared ones.
- Fix telemetry settings: set telemetry,
share_crewand tracing explicitly per environment in deployment configuration, not in code defaults.
Common failure patterns
- Connecting MCP servers from a directory listing: metadata injection works on connection alone.
- One "god" agent: every tool on one agent with delegation on, so any prompt injection reaches everything.
- Keys in MCP URLs and literal
envvalues: they leak through logs, traces and repositories. - Verbose errors from custom tools: stack traces and request objects carrying credentials, the Uncrew pattern.
- Tracing turned on by an environment variable nobody owns:
CREWAI_TRACING_ENABLED=truein a shared.envenables it for every crew.
Framework mapping
| Risk | CrewAI control | Reference |
|---|---|---|
| Excessive agency | Per-task tools, pre-call hooks, delegation off, iteration limits | OWASP LLM06:2025 Excessive Agency; NIST SP 800-53 AC-6 |
| Prompt injection via MCP metadata or tool output | Trusted servers, tool filters, guardrails | OWASP LLM01:2025 Prompt Injection |
| Secrets in errors, traces and telemetry | Generic errors, redaction hooks, share_crew off | OWASP LLM02:2025 Sensitive Information Disclosure |
| Unpinned tools and servers | Pinned packages and MCP servers | OWASP LLM03:2025 Supply Chain |
| Shared credentials | Per-crew keys, workload identity | NIST CSF 2.0 PR.AA-01; SP 800-53 IA-5 |
| Audit trail | Post-call logging hook to SIEM | SP 800-53 AU-2; CSF DE.CM-03 |
Practitioner checklist
- Give every production crew its own model and tool credentials, sourced from a secret store.
- Attach tools per task and agent; keep
allow_delegationoff unless designed in. - Enforce a
PRE_TOOL_CALLallowlist hook and log every attempt withPOST_TOOL_CALL. - Connect only trusted MCP servers, filter their tools and pin stdio packages.
- Move all credentials out of MCP URLs and literal
envvalues. - Replace deprecated code execution settings with an external sandbox.
- Set telemetry,
share_crewand AMP tracing explicitly per environment. - Set
max_iter,max_execution_timeandmax_rpmfor every production agent.
Standards and references
- CrewAI: MCP Security Considerations
- CrewAI: Tool Call Hooks
- CrewAI: Telemetry
- CrewAI: Tracing
- CrewAI: Agents
- CrewAI: MCP overview
- OWASP: Top 10 for LLM Applications 2025
Related NHI Mgmt Group resources: Securing Agent Frameworks Guide, LangChain and LangGraph Security Guide, MCP Security Guide, AI Agent Sandboxing and Code Execution Guide, CrewAI "Uncrew" Flaw 2025.