Skip to main content
Last updated on

Approvals and Guardrails

Verdicts

VerdictEffect
ALLOWcontinue
REQUIRE_APPROVALpoll for approval if hitl_enabled, otherwise follow fallback behavior
BLOCKraise GovernanceHaltError at task boundary or GovernanceBlockedError at Layer 3
HALTraise GovernanceHaltError and short-circuit future tasks on that agent

Error Surfaces

ClassWhen
GovernanceHaltErrorBLOCK or HALT at governed task boundaries
GovernanceBlockedErrorBLOCK or HALT at Layer 3 hooks
GovernanceAPIErrorAPI failure with governance_policy=fail_closed
GovernanceApprovalExpiredErrorapproval window expired

Approvals

When OpenBox returns REQUIRE_APPROVAL:

  • hitl_enabled=True — the SDK polls until the approval resolves
  • hitl_enabled=False — approval handling falls back to configured fallback behavior
  • exclude_crews_hitl — lets you disable approval polling for selected crews

Guardrail Redaction

OpenBox responses can include guardrail output that:

  • redacts activity_input before task execution
  • redacts activity_output before returning results
  • raises validation errors when the payload is rejected and no redacted fallback is provided

Policy Before Guardrails

Policy runs before guardrails. If policy already returns a non-ALLOW verdict, guardrails for that same event may not run.

If a guardrail you expect does not fire:

  • inspect the earlier policy verdict first
  • verify you are matching the correct governed boundary

Layer 3 Caveat

CrewAI may swallow GovernanceBlockedError raised from inside a tool path and surface a later ValueError from the before-LLM-call hook instead.

If you want a cleaner task-boundary failure:

  • write the policy to trigger at ActivityStarted
  • keep Layer 3 policy as a defense-in-depth fallback

OPA Matching Shortlist

BoundaryMatch against
ActivityStartedinput.activity_input[*].description
ActivityCompletedinput.activity_output.result
DB hookinput.spans[*].attributes["db.operation"]
File hookinput.spans[*].name == "file.write" plus file path