Securing CrewAI
Scan, fix, and verify a CrewAI crew in 10 minutes.
1. Install
go install github.com/inkog-io/inkog/cmd/inkog@latest2. Scan
inkog scan ./my-crewai-appExample output:
crew.py:12:1: CRITICAL [recursive_delegation]
Agents can delegate to each other indefinitely
│
11 │ researcher = Agent(
12 │ allow_delegation=True,
│ ^^^^^^^^^^^^^^^^^^^^^
13 │ ...
│
OWASP LLM08 | EU AI Act Article 14
crew.py:28:5: HIGH [missing_oversight]
Crew executes without human approval gates
│
27 │ crew = Crew(
28 │ agents=[researcher, writer],
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
29 │ tasks=tasks,
│
EU AI Act Article 14
─────────────────────────────────────────
2 findings (1 critical, 1 high)3. Fix
Fix 1: Limit delegation depth
# Before
researcher = Agent(
role="Researcher",
allow_delegation=True,
)
# After
researcher = Agent(
role="Researcher",
allow_delegation=True,
max_delegation_depth=2, # Max 2 hops
)Fix 2: Add human oversight
# Before
crew = Crew(agents=[researcher, writer], tasks=tasks)
# After
crew = Crew(
agents=[researcher, writer],
tasks=tasks,
step_callback=human_approval_callback,
max_rpm=10, # Rate limit
)
def human_approval_callback(step_output):
if step_output.requires_approval:
return get_human_approval(step_output)
return True4. Verify
inkog scan ./my-crewai-appExpected:
─────────────────────────────────────────
0 findings
Security Gate: PASSED5. Add to CI
# .github/workflows/security.yml
name: Security
on: [push, pull_request]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: inkog-io/inkog-action@v1
with:
path: .
fail-on: critical,highCommon Fixes
| Finding | Fix |
|---|---|
recursive_delegation | Set max_delegation_depth=2 |
missing_oversight | Add step_callback for approval |
no_rate_limit | Set max_rpm=10 |
dangerous_tool | Use tools_handler with allowlist |
Multi-Agent Security
CrewAI crews can spiral into infinite delegation:
Researcher → Writer → Researcher → Writer → ...Fix with explicit termination:
# Terminal agent (no outgoing delegation)
final_reviewer = Agent(
role="Final Reviewer",
allow_delegation=False, # Stops the chain
)Next
Last updated on