diff --git a/integrations/CrewAI-SidClaw/.env.example b/integrations/CrewAI-SidClaw/.env.example new file mode 100644 index 00000000..b5582124 --- /dev/null +++ b/integrations/CrewAI-SidClaw/.env.example @@ -0,0 +1,5 @@ +OPENAI_API_KEY=sk-... +SIDCLAW_API_KEY=ai_... +SIDCLAW_AGENT_ID=devops-crew +# Optional: self-hosted SidClaw API URL (defaults to https://api.sidclaw.com) +# SIDCLAW_API_URL=http://localhost:4000 diff --git a/integrations/CrewAI-SidClaw/README.md b/integrations/CrewAI-SidClaw/README.md new file mode 100644 index 00000000..e4a1c6c2 --- /dev/null +++ b/integrations/CrewAI-SidClaw/README.md @@ -0,0 +1,107 @@ +# CrewAI + SidClaw + +Adds a human approval and audit layer to CrewAI agents using [SidClaw](https://github.com/sidclawhq/platform) — an open-source governance SDK for AI agents. + +This example shows a DevOps crew with two tools: + +| Tool | Data classification | SidClaw decision | +|---|---|---| +| `deploy_to_production` | `confidential` | **Approval required** — waits for human sign-off before deploying | +| `run_db_migration` | `restricted` | **Denied** — blocked by policy, never executes | +| `check_service_health` | `internal` | **Allow** — runs immediately, full audit trace recorded | + +## Why governance matters here + +CrewAI agents are great at orchestrating complex DevOps workflows. But `deploy_to_production` and `run_db_migration` are irreversible. Without a governance layer, the crew decides and acts — no human checkpoint, no audit trail. + +SidClaw adds: +- Policy evaluation before each tool call (< 50ms overhead) +- Human approval workflow for high-risk actions (approval card in dashboard) +- Tamper-proof hash-chain audit trace for every action +- One-line integration: `govern_crewai_tool(tool, client=client)` + +## Prerequisites + +1. Python 3.10+ +2. A SidClaw account (free tier at [app.sidclaw.com](https://app.sidclaw.com) — 5 agents free) +3. An OpenAI API key + +## Setup + +```bash +# Clone and navigate +cd integrations/CrewAI-SidClaw + +# Install dependencies +pip install -r requirements.txt + +# Configure environment +cp .env.example .env +# Edit .env with your API keys +``` + +## Create agent and policies + +Run the SidClaw CLI to set up your agent and policies: + +```bash +npx create-sidclaw-app@latest --name devops-crew --template devops +``` + +Or create them in the dashboard at [app.sidclaw.com](https://app.sidclaw.com). + +## Run the example + +```bash +python main.py +``` + +Expected output: + +``` +[SidClaw] check_service_health → ALLOW (trace: trc_...) + All services healthy. + +[SidClaw] deploy_to_production → APPROVAL REQUIRED + Waiting for approval in dashboard: https://app.sidclaw.com/dashboard/approvals + (Approve or deny at app.sidclaw.com to continue) + +[SidClaw] run_db_migration → DENY + Blocked: database migrations require DBA review. Action was not executed. +``` + +## How it works + +```python +from sidclaw import SidClaw +from sidclaw.middleware.crewai import govern_crewai_tool + +client = SidClaw(api_key=os.environ["SIDCLAW_API_KEY"], agent_id="devops-crew") + +governed_deploy = govern_crewai_tool( + deploy_tool, + client=client, + data_classification="confidential", +) +``` + +`govern_crewai_tool` wraps the tool's `_run` method. Before execution, it calls the SidClaw policy engine. On `allow`, the tool runs and the outcome is recorded to the audit trace. On `approval_required`, execution pauses until a human approves or denies in the dashboard. On `deny`, `ActionDeniedError` is raised and the tool never executes. + +## Self-hosting + +SidClaw can be self-hosted with Docker: + +```bash +git clone https://github.com/sidclawhq/platform +cd platform +docker compose up +``` + +The SDK license is Apache 2.0. The platform uses FSL 1.1 (free for organizations under CHF 1M annual revenue). + +## Links + +- [SidClaw GitHub](https://github.com/sidclawhq/platform) +- [Documentation](https://docs.sidclaw.com) +- [Live demo](https://demo-devops.sidclaw.com) (no signup needed) +- [PyPI](https://pypi.org/project/sidclaw/) diff --git a/integrations/CrewAI-SidClaw/crew.py b/integrations/CrewAI-SidClaw/crew.py new file mode 100644 index 00000000..26832d60 --- /dev/null +++ b/integrations/CrewAI-SidClaw/crew.py @@ -0,0 +1,119 @@ +"""DevOps governance crew. + +A CrewAI crew that demonstrates SidClaw governance across three tools +with different risk profiles: + - check_service_health → allow + - deploy_to_production → approval_required + - run_db_migration → deny +""" + +import os +from typing import Any + +from crewai import Agent, Crew, Task +from crewai.tools import BaseTool +from dotenv import load_dotenv + +from sidclaw import ActionDeniedError, SidClaw +from sidclaw.middleware.crewai import govern_crewai_tool + +load_dotenv() + + +# --------------------------------------------------------------------------- +# SidClaw client +# --------------------------------------------------------------------------- + +sidclaw = SidClaw( + api_key=os.environ["SIDCLAW_API_KEY"], + agent_id=os.environ.get("SIDCLAW_AGENT_ID", "devops-crew"), + api_url=os.environ.get("SIDCLAW_API_URL", "https://api.sidclaw.com"), +) + + +# --------------------------------------------------------------------------- +# Tools (undecorated — governance is added via govern_crewai_tool) +# --------------------------------------------------------------------------- + +class CheckServiceHealthTool(BaseTool): + name: str = "check_service_health" + description: str = "Check the health of all production services." + + def _run(self, **kwargs: Any) -> str: + # In production: call your health-check endpoint + return "All services healthy. API: OK, DB: OK, Cache: OK" + + +class DeployToProductionTool(BaseTool): + name: str = "deploy_to_production" + description: str = "Deploy the latest build to the production environment." + + def _run(self, version: str = "latest", **kwargs: Any) -> str: + # In production: trigger your CI/CD pipeline + return f"Deployed version {version} to production successfully." + + +class RunDbMigrationTool(BaseTool): + name: str = "run_db_migration" + description: str = "Run pending database migrations against the production database." + + def _run(self, migration_id: str = "all", **kwargs: Any) -> str: + # In production: execute migrations + return f"Migration {migration_id} completed." + + +# --------------------------------------------------------------------------- +# Apply governance +# +# govern_crewai_tool wraps the tool's _run method. Before execution, SidClaw +# evaluates the action against your policies. The data_classification hint +# influences which policy rules apply. +# --------------------------------------------------------------------------- + +health_tool = govern_crewai_tool( + CheckServiceHealthTool(), + client=sidclaw, + data_classification="internal", +) + +deploy_tool = govern_crewai_tool( + DeployToProductionTool(), + client=sidclaw, + data_classification="confidential", +) + +migration_tool = govern_crewai_tool( + RunDbMigrationTool(), + client=sidclaw, + data_classification="restricted", +) + + +# --------------------------------------------------------------------------- +# Agent and crew +# --------------------------------------------------------------------------- + +devops_agent = Agent( + role="DevOps Engineer", + goal="Ensure services are healthy, deploy the latest build, and run any pending migrations.", + backstory=( + "You are a senior DevOps engineer responsible for maintaining production reliability. " + "All deployment and database actions require governance approval." + ), + tools=[health_tool, deploy_tool, migration_tool], + verbose=True, +) + +devops_task = Task( + description=( + "1. Check all service health.\n" + "2. Deploy the latest build to production.\n" + "3. Run any pending database migrations." + ), + expected_output="A summary of each action taken and its outcome.", + agent=devops_agent, +) + + +def build_crew() -> Crew: + return Crew(agents=[devops_agent], tasks=[devops_task], verbose=True) diff --git a/integrations/CrewAI-SidClaw/main.py b/integrations/CrewAI-SidClaw/main.py new file mode 100644 index 00000000..63d471c4 --- /dev/null +++ b/integrations/CrewAI-SidClaw/main.py @@ -0,0 +1,20 @@ +"""Entry point for the CrewAI + SidClaw governance example. + +Run: + python main.py +""" + +from sidclaw import ActionDeniedError +from crew import build_crew + + +if __name__ == "__main__": + crew = build_crew() + + try: + result = crew.kickoff() + print("\n--- Crew result ---") + print(result) + except ActionDeniedError as e: + print(f"\n[SidClaw] Action blocked by policy: {e}") + print("Check the audit trace at https://app.sidclaw.com/dashboard/audit") diff --git a/integrations/CrewAI-SidClaw/requirements.txt b/integrations/CrewAI-SidClaw/requirements.txt new file mode 100644 index 00000000..c40cbc4f --- /dev/null +++ b/integrations/CrewAI-SidClaw/requirements.txt @@ -0,0 +1,3 @@ +crewai>=0.130.0 +sidclaw>=0.1.2 +python-dotenv>=1.0.0