CrewAI + Veto
Role-based authorization for CrewAI multi-agent systems. Each crew member operates within defined boundaries. Prevent privilege escalation through delegation, enforce per-role tool access, and audit every action across your agent teams.
The problem with CrewAI agents today
CrewAI orchestrates teams of specialized agents with distinct roles. But "role" is a prompt concept, not an enforcement mechanism. Any agent can call any tool it's given access to, and delegation lets a manager hand tasks to workers without scoping which tools the delegated agent can use. There is no runtime check that the Researcher stays read-only or the Writer doesn't access payment tools.
The security track record is concerning. In March 2026, CERT/CC disclosed four critical CrewAI vulnerabilities (CVE-2026-2275, -2286, -2287, -2285). The code interpreter tool silently falls back to an insecure sandbox when Docker is unavailable, enabling arbitrary code execution via ctypes. SSRF in the RAG search tools allows content acquisition from internal services. File path validation is missing from the JSON loader. These flaws can be triggered through prompt injection, meaning a malicious user input can manipulate agents into exploiting them. No complete patch exists for all four as of April 2026.
Agent "roles" are prompt strings, not access control. A Researcher agent with access to a delete tool will use it if the LLM decides to. Roles don't constrain tools.
When a manager delegates to a worker, the worker inherits tool access without scoping. Delegation becomes a privilege escalation vector.
Sandbox escape, SSRF, RCE, and local file read. All triggerable via prompt injection. CERT/CC advisory VU#221883. No full patch yet.
Before and after Veto
The left tab shows a standard CrewAI setup. Agents have tools but no authorization. The right tab adds Veto with role-based policies inside each tool function.
from crewai import Agent, Task, Crew, Process
from crewai.tools import tool
@tool
def read_documents(query: str) -> str:
"""Search and read documents from the knowledge base."""
return document_store.search(query)
@tool
def send_email(to: str, subject: str, body: str) -> str:
"""Send an email to a recipient."""
return email_service.send(to, subject, body)
@tool
def delete_records(table: str, condition: str) -> str:
"""Delete records from a database table."""
return db.execute(f"DELETE FROM {table} WHERE {condition}")
@tool
def process_payment(amount: float, recipient: str) -> str:
"""Process a payment transaction."""
return payment_service.charge(amount, recipient)
researcher = Agent(
role="Researcher",
goal="Find and analyze relevant information",
tools=[read_documents],
)
writer = Agent(
role="Writer",
goal="Create content based on research",
tools=[send_email],
)
manager = Agent(
role="Manager",
goal="Oversee operations and approve decisions",
tools=[delete_records, process_payment],
allow_delegation=True,
)
# Every agent can call its tools without authorization.
# The Manager can delegate to Writer or Researcher.
# Nothing prevents privilege escalation through delegation.
# CrewAI's code interpreter silently falls back to an
# insecure sandbox when Docker is unavailable (CVE-2026-2275).
crew = Crew(
agents=[researcher, writer, manager],
tasks=[...],
process=Process.hierarchical,
manager_agent=manager,
)
result = crew.kickoff()Role-based policy configuration
Define what each agent role can do. Researcher gets read-only. Writer can send internal emails with approval for external. Manager gets write access with payment limits. Roles are enforced at the tool call boundary, not in prompts.
rules:
# Researcher: read-only access
- name: researcher_read_only
description: Researcher can only read documents
tool: read_documents
when: context.agent_role == "researcher"
action: allow
- name: researcher_no_write
description: Block researcher from write operations
tool: [send_email, delete_records, process_payment]
when: context.agent_role == "researcher"
action: deny
message: "Researcher role has read-only access"
# Writer: can send email, but not to external domains
- name: writer_internal_email_only
description: Writer can only email internal addresses
tool: send_email
when: context.agent_role == "writer" && !args.to.endswith("@yourcompany.com")
action: require_approval
approvers: [content-lead]
message: "External emails from writer require content lead approval"
# Manager: full access with limits
- name: manager_block_production_deletes
description: Block destructive writes in production
tool: delete_records
when: context.environment == "production"
action: deny
message: "Destructive operations blocked in production"
- name: manager_approve_large_payments
description: Payments over $1,000 need CFO approval
tool: process_payment
when: args.amount > 1000
action: require_approval
approvers: [cfo]
timeout: 1h
- name: manager_block_huge_payments
description: Hard block on payments over $50,000
tool: process_payment
when: args.amount > 50000
action: deny
message: "Payments over $50,000 require manual processing"Quickstart
Install
pip install veto crewaiDefine role-based policies
Create veto/policies.yaml with rules per agent role. Use context.agent_role to scope access.
Add veto.guard() to each tool
Call veto.guard() with the agent's role as context. The crew structure, tasks, and process type stay unchanged.
What Veto covers for CrewAI agents
Role-based tool access
Enforce that each agent role can only use specific tools. Researcher: read-only. Writer: email with approval. Manager: payments with limits. Enforced in code, not prompts.
Delegation protection
When a manager delegates, the worker's tool calls still go through Veto with the worker's role context. No privilege escalation through delegation chains.
Human-in-the-loop
Route sensitive tool calls to human approval queues per role. Writers need content lead approval for external emails. Managers need CFO approval for large payments.
Full audit trail
Every tool call logged with agent role, tool name, arguments, decision, and timestamp. See which agent in which crew attempted what, and what was authorized.
Frequently asked questions
How does Veto handle agent delegation in CrewAI?
Can different agents have different policies for the same tool?
Does it work with hierarchical and sequential processes?
What happens when a tool call is denied?
Related integrations
Your crew, your rules. Authorization built for multi-agent systems.