CrewAI + ExecLayer Governance Guide
Secure multi-agent systems with per-agent policies, cross-agent authorization, and privilege escalation prevention. Add execution authority to CrewAI's collaborative agent architecture.
The CrewAI Governance Challenge
CrewAI changes the multi-agent game. Instead of agents working in isolation, CrewAI agents form crews that collaborate on complex tasks. Each agent has different roles, capabilities, and tools. The system is more powerful than single agents but introduces new security problems.
In a CrewAI crew, one agent can delegate to another. If agent A has read-only access to the customer database and agent B has write access, and if A can convince B to make a change, then A has effectively escalated its privileges through B. The original design intent is circumvented by social proof within the multi-agent system.
CrewAI has no mechanism to prevent this. Each agent is authorized for its own tools, but there is no understanding of delegation, trust boundaries, or capability inheritance through agent communication. This is what ExecLayer adds: governance that understands the multi-agent context.
Three Core Governance Problems in Multi-Agent Systems
Problem 1: Per-Agent Policy Enforcement
CrewAI agents have different roles and therefore different capabilities. A research agent should be able to query data and call search APIs. A data processor should be able to write to specific database tables. A coordinator should only be able to invoke other agents, not execute tools directly.
ExecLayer applies per-agent policy bundles. Each agent in the crew gets a policy document that specifies which actions it can perform:
agent "research_agent" {
can "data_read" on "documents"
can "external_api_call" to "search_api"
cannot "data_mutation"
}
agent "processor_agent" {
can "data_mutation" on "processed_results"
can "data_read" on "documents"
cannot "external_api_call"
}
agent "coordinator_agent" {
can "invoke_agent" to "research_agent"
can "invoke_agent" to "processor_agent"
cannot use_tools
}
When the research agent tries to execute a tool call, ExecLayer checks the policy. When the processor agent tries the same tool call, ExecLayer checks a different policy. When the coordinator agent tries to invoke another agent, ExecLayer knows that this agent can only invoke other agents, not execute tools.
Problem 2: Cross-Agent Authorization for Shared Resources
In CrewAI, multiple agents may need access to the same resource. Both research_agent and processor_agent need to read from the documents table, but only processor_agent should write to it. Both agents communicate about data through task delegation.
ExecLayer tracks which agents have touched which resources and in what order. When processor_agent tries to write to a document that research_agent just read, ExecLayer verifies that the write is authorized and consistent with the delegation context:
// In the crew's execution log:
1. research_agent reads document_123
2. research_agent returns findings to coordinator
3. coordinator asks processor_agent to refine findings
4. processor_agent tries to write to document_123
ExecLayer checks:
- Does processor_agent have write access to document_123? Yes.
- Is this write consistent with the task delegation?
Yes, coordinator delegated this task.
- Has research_agent's read permission been revoked? No.
- Approve write.
This prevents agents from writing to resources they were not supposed to modify, even if another agent somehow suggested it.
Problem 3: Preventing Privilege Escalation Through Delegation
The most subtle problem: agent A has limited permissions but asks agent B (which has higher permissions) to perform an action. If B is not careful, it executes A's request with B's own authority, effectively giving A elevated privileges.
ExecLayer prevents this through delegation receipts. When agent A delegates a task to agent B:
- ExecLayer records that A requested the action.
- B executes the action under its own authority.
- ExecLayer verifies that the action B executed matches what A requested.
- If B tries to execute actions beyond what A asked for, ExecLayer tags those as agent-initiated, not delegated.
The cryptographic receipt shows exactly who initiated the action and who executed it, preventing ambiguity about authority delegation:
{
"receipt_id": "auth_recv_9x8y7z",
"action": {
"canonical_intent": "data_mutation on payments table",
"requested_by": "research_agent",
"executed_by": "processor_agent"
},
"authorization": {
"research_agent_has_access": false,
"processor_agent_has_access": true,
"delegation_valid": true
},
"signature": "0x..."
}
Conceptual Architecture for CrewAI Integration
The key difference from single-agent systems: ExecLayer must understand both the requester and the executor, and verify that the delegation is authorized.
Implementing Per-Agent Policy Bundles
CrewAI agents are typically defined with roles and tools:
crew = Crew(
agents=[
Agent(
role="Research Analyst",
goal="Find relevant information",
tools=[search_tool, read_database_tool]
),
Agent(
role="Data Processor",
goal="Transform data into insights",
tools=[transform_tool, write_database_tool]
)
],
tasks=[...]
)
ExecLayer maps each agent to a policy bundle at initialization time. The crew passes in an agent-to-policy mapping:
execLayer_policies = {
"Research Analyst": {
"can_invoke_agents": ["Data Processor"],
"can_use_tools": ["search_tool", "read_database_tool"],
"tool_constraints": {
"search_tool": {"max_queries_per_minute": 10},
"read_database_tool": {
"allowed_tables": ["documents"],
"disallowed_patterns": ["*user_passwords*"]
}
}
},
"Data Processor": {
"can_invoke_agents": [],
"can_use_tools": ["transform_tool", "write_database_tool"],
"tool_constraints": {
"write_database_tool": {
"allowed_tables": ["processed_results"],
"disallowed_tables": ["documents", "users"]
}
}
}
}
crew = Crew(
agents=[...],
tasks=[...],
governance=ExecLayerGovernance(
policies=execLayer_policies,
ledger_backend="merkle"
)
)
Each time an agent executes a tool or invokes another agent, ExecLayer checks the agent's policy bundle before allowing the action. The agent name, role, or ID is extracted from CrewAI's agent context and matched to the policy.
Handling Agent-to-Agent Invocations
CrewAI's task delegation system allows agents to invoke other agents. ExecLayer gates these invocations with special handling:
class ExecLayerAgentCallback(BaseCallbackHandler):
def on_agent_invoke(self, agent_name, task_description, **kwargs):
# Requesting agent
requester = self.current_agent()
# Requested agent
target = agent_name
# Create delegation request
request = DelegationRequest(
requester_agent=requester,
target_agent=target,
task_description=task_description
)
# Check requester's delegation policy
can_request = self.execLayer.check_delegation_policy(
agent=requester,
target=target
)
if not can_request:
raise AgentAuthorizationError(
f"{requester} cannot invoke {target}"
)
# Record delegation initiation
delegation_receipt = self.execLayer.record_delegation_request(
request
)
# Allow agent to proceed
return delegation_receipt
The delegation receipt stays attached to the task as it moves from agent to agent. When the target agent completes the task, ExecLayer verifies that the actual actions taken were within the scope of the delegation:
// Delegation receipt shows:
{
"delegation_id": "deleg_abc123",
"requester": "research_agent",
"target": "processor_agent",
"requested_scope": "data_mutation on processed_results table",
"executed_scope": "data_mutation on processed_results table",
"scopes_match": true,
"authorized": true
}
Preventing Privilege Escalation
The strongest protection against privilege escalation is scope verification. When agent A delegates a task to agent B, ExecLayer records the exact scope of the delegation. B can execute actions in that scope, but not outside it.
Example: research_agent asks processor_agent to "calculate statistics on the revenue column". This scope is narrowed to:
{
"delegation_scope": {
"canonical_action": "data_read",
"resource_type": "database_column",
"resource": "revenue",
"allowed_aggregations": ["sum", "average", "count"]
}
}
When processor_agent executes its tools, any action outside this scope is tagged as agent-initiated (not delegated) and subject to processor_agent's own policy. If processor_agent tries to read a different column, that read is only authorized if processor_agent's own policy allows it. If not, ExecLayer denies it.
This prevents scenarios like: "research_agent asked me to calculate stats, so I'll just read the salary column too." The salary column read is not authorized by the delegation, and processor_agent's policy probably doesn't allow it either.
Multi-Crew and Shared Resource Governance
CrewAI systems often have multiple crews working with shared databases, APIs, or external services. ExecLayer extends per-agent policies to cross-crew authorization.
Imagine crew A (sales analysis) and crew B (data pipeline) both need to write to a shared data warehouse. ExecLayer prevents crew A from writing to tables that crew B owns:
// Crew A's policy
crew_a = {
"agents": ["sales_researcher", "sales_analyst"],
"allowed_writes": ["sales_fact_table", "temp_*"],
"disallowed_writes": ["customer_dimension", "product_dimension"]
}
// Crew B's policy
crew_b = {
"agents": ["etl_agent", "validator_agent"],
"allowed_writes": ["customer_dimension", "product_dimension", "fact_tables"],
"disallowed_writes": ["sales_fact_table"]
}
If an agent from crew A somehow gets invoked by crew B (through an API or webhook), ExecLayer still applies crew A's policy. The agent cannot write to customer_dimension just because crew B invoked it.
Cryptographic Receipts for Multi-Agent Auditing
In single-agent systems, an Authority Receipt records one agent's action. In multi-agent systems, receipts create an audit trail across agent boundaries:
{
"receipt_id": "auth_recv_14k15l",
"timestamp": "2026-04-03T14:35:22Z",
"agents_involved": [
{
"agent": "research_agent",
"role": "requester",
"action": "requested data analysis"
},
{
"agent": "processor_agent",
"role": "executor",
"action": "performed data_mutation on processed_results"
}
],
"delegation_chain": [
{
"from": "research_agent",
"to": "processor_agent",
"scope": "data_mutation on processed_results",
"verified": true
}
],
"authorization": {
"research_agent_authorized_to_request": true,
"processor_agent_authorized_to_execute": true,
"delegation_valid": true
},
"merkle_index": 5234,
"hash": "0x52a1d9..."
}
This receipt clearly shows who asked for what, who executed it, and whether the delegation was authorized. When auditing, you can reconstruct the entire multi-agent workflow and verify that each agent acted within its authorized scope.
Not Yet Shipped
Like the LangChain integration, the CrewAI governance system is our detailed design for the future. We are building this system and expect to release it in Q2 2026. The multi-agent delegation architecture is proven, the policy checking logic is developed, but the CrewAI-specific adapter is in active development.
We are sharing this in detail because multi-agent governance is a frontier problem. Most organizations that deploy CrewAI today have no way to ensure that agents don't escalate privileges through delegation. ExecLayer changes that.
Broader Multi-Agent Governance Principles
The CrewAI integration illustrates principles that apply to any multi-agent system:
- Each agent must have independent policy evaluation based on its own capability set.
- Delegation must be explicit and scoped, not implicit or unlimited.
- Cross-agent actions must be verified against both the requester's and executor's policies.
- Authority receipts must record delegation chains, not just final actions.
- Privilege escalation is prevented by restricting actions outside the delegation scope to the agent's own policy.
For more context on multi-agent governance, see our deep dive on Authority Receipts and governance research.
Ready to govern your CrewAI multi-agent systems?
Request Early Access