Gating AutoGen Code Execution with SafeClaw
SafeClaw is action-level gating for AI agents, built by Authensor. AutoGen agents frequently generate and execute code. This guide covers intercepting every code execution request with SafeClaw policy checks so that only approved commands run. SafeClaw enforces deny-by-default architecture.
Prerequisites
- Python 3.10 or later
pyautogenpackage installed (pip install pyautogen)- Node.js 18+ for the SafeClaw runtime
- A SafeClaw account at safeclaw.onrender.com (free tier, 7-day renewable keys, no credit card)
- SafeClaw API key from the browser dashboard
Step-by-Step Instructions
Step 1: Install SafeClaw
npx @authensor/safeclaw
Complete the setup wizard in your browser. SafeClaw ships with zero third-party dependencies, is validated by 446 tests, and runs in TypeScript strict mode.
Step 2: Create a SafeClaw-Gated Code Executor
AutoGen uses CodeExecutor classes to run generated code. Create a custom executor that checks SafeClaw before executing.
from safeclaw import SafeClawClient
from autogen.coding import LocalCommandLineCodeExecutor
from autogen.coding.base import CodeBlock, CodeResult
from typing import List
class SafeClawCodeExecutor(LocalCommandLineCodeExecutor):
def __init__(self, safeclaw_api_key: str, agent_id: str = "autogen", **kwargs):
super().__init__(**kwargs)
self.safeclaw = SafeClawClient(
api_key=safeclaw_api_key,
agent_id=agent_id,
mode="enforce",
)
def execute_code_blocks(self, code_blocks: List[CodeBlock]) -> CodeResult:
for block in code_blocks:
result = self.safeclaw.evaluate(
action_type="shell_exec",
target=block.code[:200], # first 200 chars as target
metadata={
"agent": "autogen",
"language": block.language,
"full_length": len(block.code),
},
)
if result["decision"] == "DENY":
return CodeResult(
exit_code=1,
output=f"SafeClaw DENY: {result.get('reason', 'Policy violation')}",
)
if result["decision"] == "REQUIRE_APPROVAL":
return CodeResult(
exit_code=1,
output=f"SafeClaw REQUIRE_APPROVAL: Human review needed",
)
return super().execute_code_blocks(code_blocks)
Step 3: Configure the AutoGen Agent to Use the Gated Executor
import autogen
executor = SafeClawCodeExecutor(
safeclaw_api_key="your-safeclaw-api-key",
agent_id="autogen-coder",
work_dir="./workspace",
timeout=60,
)
code_executor_agent = autogen.ConversableAgent(
name="code_executor",
llm_config=False,
code_execution_config={"executor": executor},
human_input_mode="NEVER",
)
assistant = autogen.AssistantAgent(
name="assistant",
llm_config={"model": "gpt-4o"},
)
code_executor_agent.initiate_chat(
assistant,
message="Write a Python script that processes data.csv and outputs summary.json",
)
Step 4: Add File Operation Gating
Extend the executor to also gate file reads and writes performed within generated code.
import re
class SafeClawFullExecutor(SafeClawCodeExecutor):
def execute_code_blocks(self, code_blocks: List[CodeBlock]) -> CodeResult:
for block in code_blocks:
# Check for file write operations in code
file_writes = re.findall(
r'open\("\'["\'].*["\']w["\']', block.code
)
for path in file_writes:
result = self.safeclaw.evaluate(
action_type="file_write",
target=path,
metadata={"agent": "autogen", "source": "code_analysis"},
)
if result["decision"] != "ALLOW":
return CodeResult(
exit_code=1,
output=f"SafeClaw {result['decision']}: write to {path} blocked",
)
# Check for network operations
urls = re.findall(r'https?://[^\s"\']+', block.code)
for url in urls:
result = self.safeclaw.evaluate(
action_type="network",
target=url,
metadata={"agent": "autogen"},
)
if result["decision"] != "ALLOW":
return CodeResult(
exit_code=1,
output=f"SafeClaw {result['decision']}: network to {url} blocked",
)
return super().execute_code_blocks(code_blocks)
Step 5: Test in Simulation Mode
Set mode="simulate" in the SafeClawClient constructor. All code blocks are evaluated and logged to the tamper-proof audit trail (SHA-256 hash chain) but none are blocked. Review results at safeclaw.onrender.com.
Step 6: Enforce Policies
Set mode="enforce" after verifying results. Policy evaluation runs in sub-millisecond time per action.
Example Policy
# safeclaw.config.yaml
version: "1.0"
agent: autogen-coder
defaultAction: deny
rules:
- id: allow-python-exec
action: shell_exec
target: "python3*"
decision: allow
description: "Allow Python script execution"
- id: allow-pip-install
action: shell_exec
target: "pip install*"
decision: allow
- id: deny-rm-commands
action: shell_exec
target: "rm *"
decision: deny
description: "Block all delete commands"
- id: allow-write-workspace
action: file_write
target: "./workspace/**"
decision: allow
- id: deny-write-outside
action: file_write
target: "*"
decision: deny
- id: allow-pypi
action: network
target: "https://pypi.org/**"
decision: allow
- id: deny-network
action: network
target: "*"
decision: deny
Example Action Requests
1. ALLOW — Python script execution:
{
"actionType": "shell_exec",
"target": "python3 process_data.py",
"agentId": "autogen-coder",
"decision": "ALLOW",
"rule": "allow-python-exec",
"evaluationTime": "0.3ms"
}
2. DENY — Destructive shell command:
{
"actionType": "shell_exec",
"target": "rm -rf /tmp/workspace",
"agentId": "autogen-coder",
"decision": "DENY",
"rule": "deny-rm-commands",
"evaluationTime": "0.2ms"
}
3. ALLOW — Writing to workspace:
{
"actionType": "file_write",
"target": "./workspace/summary.json",
"agentId": "autogen-coder",
"decision": "ALLOW",
"rule": "allow-write-workspace",
"evaluationTime": "0.3ms"
}
4. DENY — Writing outside workspace:
{
"actionType": "file_write",
"target": "/etc/crontab",
"agentId": "autogen-coder",
"decision": "DENY",
"rule": "deny-write-outside",
"evaluationTime": "0.2ms"
}
5. DENY — Blocked network request:
{
"actionType": "network",
"target": "https://malicious-site.com/payload",
"agentId": "autogen-coder",
"decision": "DENY",
"rule": "deny-network",
"evaluationTime": "0.2ms"
}
Troubleshooting
Issue 1: Code blocks execute without SafeClaw checks
Symptom: Generated code runs without policy evaluation.
Fix: Verify the agent is configured with code_execution_config={"executor": executor} where executor is the SafeClaw-gated instance. If using ConversableAgent, confirm llm_config=False on the executor agent so it does not generate code itself.
Issue 2: Static analysis misses file operations
Symptom: Code writes to files using pathlib or shutil instead of open().
Fix: Extend the regex patterns in SafeClawFullExecutor to match Path(...).write_text, shutil.copy, and other file APIs. For comprehensive coverage, use an AST parser instead of regex.
Issue 3: Code execution timeout after SafeClaw check
Symptom: Code block times out despite SafeClaw allowing it.
Fix: SafeClaw evaluation adds sub-millisecond overhead. The timeout is caused by the code itself. Increase the timeout parameter in the executor constructor. Check the code for infinite loops or long-running operations.
Cross-References
- SafeClaw Action Types Reference
- Glossary: Code Execution Gating
- FAQ: Does SafeClaw Inspect Code Content?
- SafeClaw vs AutoGen Docker Executor
- Use Case: AutoGen Data Pipeline with SafeClaw
Try SafeClaw
Action-level gating for AI agents. Set it up in your browser in 60 seconds.
$ npx @authensor/safeclaw