Skip to content

[Contrib] Agent-OS Governance: Kernel-Level Policy Enforcement for Crews#4384

Open
imran-siddique wants to merge 4 commits intocrewAIInc:mainfrom
imran-siddique:contrib/agent-os
Open

[Contrib] Agent-OS Governance: Kernel-Level Policy Enforcement for Crews#4384
imran-siddique wants to merge 4 commits intocrewAIInc:mainfrom
imran-siddique:contrib/agent-os

Conversation

@imran-siddique
Copy link

@imran-siddique imran-siddique commented Feb 5, 2026

Summary

Adds kernel-level governance for CrewAI workflows using Agent-OS.

Why This Matters

CrewAI enables powerful multi-agent crews, but lacks built-in policy enforcement. This module provides:

  • Content Filtering: Block dangerous patterns (SQL injection, shell commands)
  • Tool Control: Limit which tools agents can use
  • Rate Limiting: Cap iterations and tool calls
  • Audit Trail: Full logging for compliance and debugging

Changes

  • Added \src/crewai/governance/\
    • _kernel.py\ - GovernedAgent, GovernedCrew, GovernancePolicy classes
    • _init_.py\ - Public exports
    • \README.md\ - Documentation and examples

Example Usage

\\python
from crewai import Agent, Crew, Task
from crewai.governance import GovernedCrew, GovernancePolicy

Define policy

policy = GovernancePolicy(
max_tool_calls=20,
max_iterations=15,
blocked_patterns=["DROP TABLE", "rm -rf"],
blocked_tools=["shell_tool"],
)

Govern the crew

governed_crew = GovernedCrew(crew, policy)
result = governed_crew.kickoff()

Check audit

print(f"Violations: {len(governed_crew.violations)}")
\\

Value for CrewAI Users

Feature Without Module With Agent-OS
Content Filtering Manual Automatic
Tool Limits None Configurable
Audit Trail DIY Built-in
Violation Handling Runtime errors Controlled callbacks

Integration Path

This module works standalone, but can also integrate with the full Agent-OS kernel for:

  • GDPR/HIPAA compliance policies
  • Cost control limits
  • Human-in-the-loop approval flows
  • Cross-framework governance

Related Work

References


Note

Medium Risk
Introduces new runtime wrappers that monkey-patch Agent.execute_task and filter/sanitize tool usage and outputs, which could subtly change agent behavior and require validation across CrewAI versions.

Overview
Adds a new crewai.governance module that provides GovernancePolicy, GovernedAgent, and GovernedCrew wrappers to apply policy checks during crew execution.

GovernedAgent wraps Agent.execute_task to filter tools (allow/deny lists), track tool-call and iteration limits (recording violations), and sanitize outputs by truncating and replacing blocked regex patterns; all violations and actions can be recorded to an audit trail with an optional on_violation callback.

GovernedCrew wraps a Crew to automatically govern all agents, aggregate violations, log crew-level lifecycle events, and record an execution-time violation (post-run) when max_execution_time is exceeded; documentation and examples are added in governance/README.md.

Written by Cursor Bugbot for commit 4279378. This will update automatically on new commits. Configure here.

Adds kernel-level governance for CrewAI workflows.

Features:
- GovernancePolicy: Define rules for crew behavior
- GovernedAgent: Wrap individual agents with policy enforcement
- GovernedCrew: Govern entire crews with shared policy
- Content filtering with blocked patterns
- Tool filtering (blocked/allowed lists)
- Full audit trail

Integration with Agent-OS kernel for enterprise governance.

See: https://github.com/imran-siddique/agent-os
- Fix content filtering bypass for non-string outputs
- Fix double-counting of agent violations in crew totals
- Remove unimplemented human approval features from docs
- Add warning when agent lacks execute_task method
- Use getattr consistently for agent.role access
- Clarify rate limiting requires CrewAI callback integration
1. Rate limiting now enforced:
   - _tool_calls incremented when tools pass filter
   - _iterations incremented after each execution
   - TOOL_LIMIT_EXCEEDED and ITERATION_LIMIT_EXCEEDED violations raised

2. Content filter return type: Already fixed (returns sanitized string)

3. Timeout enforcement: Clarified in docstring that it's audit-only
   post-execution check. Real-time enforcement needs asyncio.timeout.

4. Audit event task_name: Fixed key mismatch - now extracts from
   both 'task_name' and 'task' object (via .description or .name)

5. Crew violations in audit log: _record_violation now calls
   _log_event to ensure all violations appear in audit trail
@imran-siddique
Copy link
Author

Cursor Bugbot has reviewed your changes and found 4 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Please review again

The _check_output method was returning a string for non-string outputs
when violations were detected, which broke downstream consumers expecting
specific types (e.g., TaskOutput). Now returns the original object while
logging a warning. Violations are still recorded and can be retrieved
via get_violations().

Fixes review comment about return type breaking downstream consumers.
@imran-siddique
Copy link
Author

All Review Comments Addressed ✅

Fixed the Bugbot-identified issue:

  • Content filter return type fix: _check_output now preserves original object type for non-string outputs instead of converting to string (which broke downstream consumers expecting TaskOutput, etc.)

The violation is still recorded and can be retrieved via get_violations() - we just don't break the type contract anymore.

Could you please provide a final review so we can move forward? Thank you! 🙏

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

"Returning original object to preserve type. Violations: %d",
type(output).__name__,
len(self._violations)
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logger undefined in _check_output causes NameError

High Severity

logger is defined as a local variable inside _wrap_execution (line 145) but referenced in _check_output (line 279), which is a separate method with no access to that local scope. When a non-string output triggers a content violation, this raises a NameError, crashing the governed execution instead of gracefully returning the original object.

Additional Locations (1)

Fix in Cursor Fix in Web

self._record_violation(
ViolationType.TOOL_LIMIT_EXCEEDED,
f"Tool calls ({self._tool_calls}) exceeded limit ({self.policy.max_tool_calls})",
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tool filtering incorrectly counted as tool invocations

Medium Severity

_filter_tools increments self._tool_calls for each tool that passes the allow/block filter (line 226), treating the count of available tools as actual tool invocations. If an agent has 10 allowed tools and max_tool_calls is 5, a TOOL_LIMIT_EXCEEDED violation fires before any tool is actually called, making rate limiting ineffective and producing false violations.

Additional Locations (1)

Fix in Cursor Fix in Web

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.

1 participant