Skip to content

feat(hooks): add provider-based pre-tool-call guardrails#5422

Open
uchibeke wants to merge 1 commit intocrewAIInc:mainfrom
aporthq:feat/guardrail-provider
Open

feat(hooks): add provider-based pre-tool-call guardrails#5422
uchibeke wants to merge 1 commit intocrewAIInc:mainfrom
aporthq:feat/guardrail-provider

Conversation

@uchibeke
Copy link
Copy Markdown

Summary

This PR adds an optional provider-based guardrail seam on top of CrewAI's existing before_tool_call hook flow.

It keeps the core design intentionally small:

  • CrewAI defines a neutral GuardrailProvider contract
  • CrewAI ships a minimal built-in AllowlistGuardrailProvider
  • external providers can plug into the same interface
  • tool execution is unchanged unless a guardrail is explicitly enabled

This closes #4877 and follows the same architectural direction as the provider-based approach proposed in bytedance/deer-flow#1240, while staying consistent with CrewAI's current hook model and runtime behavior.

What Changed

  • add GuardrailRequest, GuardrailDecision, and GuardrailProvider
  • add enable_guardrail(...) and disable_guardrail(...)
  • add built-in AllowlistGuardrailProvider
  • normalize tool-call input into a reusable request object for external providers
  • support fail_closed=True|False behavior when provider evaluation errors
  • document the new hook seam in English, Arabic, Korean, and Brazilian Portuguese
  • include runnable examples for:
    • built-in allowlist guardrails
    • custom providers
    • external Open Agent Passport (OAP) providers such as APort

Why This Shape

The issue thread correctly identified a missing production seam: CrewAI can run before_tool_call hooks, but it does not currently expose a reusable provider contract for pre-tool-call authorization.

This PR addresses that gap without overreaching:

  • it does not bundle any vendor-specific policy engine
  • it does not add async suspend/resume semantics to core
  • it does not change normal CrewAI tool execution unless enabled
  • it keeps the current core decision model at allow / deny

That makes the feature usable today while leaving room for richer future decisions such as escalate or signed receipts if CrewAI later adds first-class runtime support for them.

External Provider Story

CrewAI stays vendor-neutral here.

The built-in allowlist provider covers the simplest production need, but external providers can enforce richer policy models through the same seam. The docs include an external OAP example with APort to show that the interface can support:

  • repository and branch restrictions for code actions
  • per-transaction and daily limits for payment actions
  • export and PII limits for data actions

CrewAI core still only receives an allow or deny verdict. Capability logic, limits, assurance rules, and policy-pack evaluation remain outside the framework in the provider.

Non-Goals

This PR does not add:

  • async suspend / resolve(decision_id, outcome) flows
  • native allow | deny | escalate tri-state decisions
  • signed decision receipts in CrewAI core
  • post-task or post-output verification
  • bundled vendor integrations

Those are valid future extensions, but they do not fit cleanly into CrewAI's current boolean before_tool_call contract without broader runtime changes.

Docs

Updated:

  • docs/en/learn/tool-hooks.mdx
  • docs/ar/learn/tool-hooks.mdx
  • docs/ko/learn/tool-hooks.mdx
  • docs/pt-BR/learn/tool-hooks.mdx

The docs keep the core examples minimal and runnable, while also showing that an external provider can enforce more than simple tool-name allowlists.

Testing

Ran locally:

CREWAI_STORAGE_DIR=/tmp/crewai-test-storage \
PYTHONPATH=lib/crewai/src \
python3 -m pytest -o addopts= lib/crewai/tests/hooks/test_guardrails.py -q

Result:

  • 12 passed

Syntax check:

PYTHONPYCACHEPREFIX=/tmp/crewai-pyc \
python3 -m py_compile \
  lib/crewai/src/crewai/hooks/guardrails.py \
  lib/crewai/tests/hooks/test_guardrails.py

Docs flow validated with the published APort bootstrap/runtime path:

  • native bootstrap works with APORT_NONINTERACTIVE=1 uvx --from aport-agent-guardrails aport setup --framework=crewai --integration-mode=native
  • OAPGuardrailProvider(framework="crewai") registers through enable_guardrail(...)

Note:

  • I did not run the full uv run repo lint/type suite on this machine because the existing workspace dependency resolution for lancedb==0.30.0 is still failing on macOS x86_64 outside this diff.

Linked Issue / Context

Issue Thread Coverage

Comment Theme Status Notes
#1 Pre-tool-call auth is a real gap; mentions anomaly scoring/approvals Addressed The missing pre-tool authorization seam is added; anomaly scoring and approval workflows remain provider concerns.
#2 Keep discussion provider-agnostic, not vendor-specific Addressed Core stays neutral; APort is documented as an external provider example only.
#3 Async authorization / wait for external approval Deferred CrewAI core stays synchronous because before_tool_call is currently boolean.
#4 suspend + resolve(decision_id) model Deferred Valid future direction, but not added in this PR.
#5 Downstream dependency handling during suspension Deferred Depends on suspend/resume semantics that CrewAI core does not expose today.
#6 Concern that pause/human approval may not fit CrewAI cleanly Addressed This PR intentionally keeps the core model to optional synchronous allow / deny.
#7 Include agent identity/boundaries, not just tool name Partial GuardrailRequest carries agent_role, task_description, and crew_id, but no explicit charter field yet.
#8 AuthGuardian vendor pitch Marketing Mostly product promotion; the core permission-gate idea is already covered by the seam.
#9 Healthcare, multilingual tool resolution, audit logging Partial Supported by custom providers, but not implemented in CrewAI core.
#10 Post-task output verification Out of scope This PR is pre-tool-call authorization only.
#11 VetoAPI human approval pitch Marketing Mostly vendor promotion; human approval remains outside current core scope.
#12 Layered pre-exec + post-exec verification Out of scope Good architecture, but broader than this seam.
#13 Stateless per-call provider, tri-state, structured denial Partial The seam is per-call and normalized; tri-state and structured denial are not in core yet.
#14 Compose policy + approval + verification Out of scope Broader systems layering, not the focus of this PR.
#15 Identity drift / behavioral inconsistency / escalate Deferred Needs richer request semantics and likely tri-state escalation support.
#16 Output correctness after tool success Out of scope Post-execution verification is separate from this feature.
#17 Signed decision receipts/evidence Deferred Not carried in GuardrailDecision yet.
#18 Default-deny, typed decisions, async callback, signed evidence Partial fail_closed behavior is present; typed tri-state/callback/evidence are deferred.
#19 SINT adapter shipped Marketing Useful ecosystem signal, but not a CrewAI core requirement.
#20 Conformance fixtures for providers Deferred Good follow-up, but not required for first seam landing.
#21 Fixtures for tri-state outputs Deferred Depends on tri-state support first.
#22 Delegation scope, budget, signed receipt Partial Possible through custom providers; not first-class in CrewAI core.
#23 VeroQ release update Marketing Product update, not a new framework requirement.
#24 Wallet-state provider before token transfers Partial A custom provider can do this today through the new seam.
#25 Multi-issuer wallet demo Marketing Demo/update rather than core feedback.
#26 SINT suspend/resolve adapter update Deferred Relevant if CrewAI later adds async suspension semantics.
#27 Compose delegation, policy, wallet, compliance into one verdict Partial The seam allows composed providers, but CrewAI does not ship one.
#28 Add escalation field to decisions Partial Conceptually aligned, but intentionally omitted from current core API.

@uchibeke uchibeke force-pushed the feat/guardrail-provider branch from 64282b8 to 47dda4b Compare April 12, 2026 19:55
@uchibeke
Copy link
Copy Markdown
Author

Hey @lorenzejay, lmk if this aligns with what you'd like to see.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] GuardrailProvider interface for pre-tool-call authorization

1 participant