On this tutorial, we construct an enterprise-grade AI governance system utilizing OpenClaw and Python. We begin by establishing the OpenClaw runtime and launching the OpenClaw Gateway in order that our Python setting can work together with an actual agent by the OpenClaw API. We then design a governance layer that classifies requests based mostly on threat, enforces approval insurance policies, and routes protected duties to the OpenClaw agent for execution. By combining OpenClaw’s agent capabilities with coverage controls, we reveal how organizations can safely deploy autonomous AI programs whereas sustaining visibility, traceability, and operational oversight.
!apt-get replace -y
!apt-get set up -y curl
!curl -fsSL | bash -
!apt-get set up -y nodejs
!node -v
!npm -v
!npm set up -g openclaw@newest
!pip -q set up requests pandas pydantic
import os
import json
import time
import uuid
import secrets and techniques
import subprocess
import getpass
from pathlib import Path
from typing import Dict, Any
from dataclasses import dataclass, asdict
from datetime import datetime, timezone
import requests
import pandas as pd
from pydantic import BaseModel, Area
attempt:
from google.colab import userdata
OPENAI_API_KEY = userdata.get("OPENAI_API_KEY")
besides Exception:
OPENAI_API_KEY = None
if not OPENAI_API_KEY:
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
if not OPENAI_API_KEY:
OPENAI_API_KEY = getpass.getpass("Enter your OpenAI API key (hidden input): ").strip()
assert OPENAI_API_KEY != "", "API key cannot be empty."
OPENCLAW_HOME = Path("/root/.openclaw")
OPENCLAW_HOME.mkdir(mother and father=True, exist_ok=True)
WORKSPACE = OPENCLAW_HOME / "workspace"
WORKSPACE.mkdir(mother and father=True, exist_ok=True)
GATEWAY_TOKEN = secrets and techniques.token_urlsafe(48)
GATEWAY_PORT = 18789
GATEWAY_URL = f"We put together the setting required to run the OpenClaw-based governance system. We set up Node.js, the OpenClaw CLI, and the required Python libraries so our pocket book can work together with the OpenClaw Gateway and supporting instruments. We additionally securely accumulate the OpenAI API key through a hidden terminal immediate and initialize the directories and variables required for runtime configuration.
config = {
"env": {
"OPENAI_API_KEY": OPENAI_API_KEY
},
"agents": {
"defaults": {
"workspace": str(WORKSPACE),
"model": {
"primary": "openai/gpt-4.1-mini"
}
}
},
"gateway": {
"mode": "local",
"port": GATEWAY_PORT,
"bind": "loopback",
"auth": {
"mode": "token",
"token": GATEWAY_TOKEN
},
"http": {
"endpoints": {
"chatCompletions": {
"enabled": True
}
}
}
}
}
config_path = OPENCLAW_HOME / "openclaw.json"
config_path.write_text(json.dumps(config, indent=2))
physician = subprocess.run(
["bash", "-lc", "openclaw doctor --fix --yes"],
capture_output=True,
textual content=True
)
print(physician.stdout[-2000:])
print(physician.stderr[-2000:])
gateway_log = "/tmp/openclaw_gateway.log"
gateway_cmd = f"OPENAI_API_KEY='{OPENAI_API_KEY}' OPENCLAW_GATEWAY_TOKEN='{GATEWAY_TOKEN}' openclaw gateway --port {GATEWAY_PORT} --bind loopback --token '{GATEWAY_TOKEN}' --verbose > {gateway_log} 2>&1 & echo $!"
gateway_pid = subprocess.check_output(["bash", "-lc", gateway_cmd]).decode().strip()
print("Gateway PID:", gateway_pid)We assemble the OpenClaw configuration file that defines the agent defaults and Gateway settings. We configure the workspace, mannequin choice, authentication token, and HTTP endpoints in order that the OpenClaw Gateway can expose an API suitable with OpenAI-style requests. We then run the OpenClaw physician utility to resolve compatibility points and begin the Gateway course of that powers our agent interactions.
def wait_for_gateway(timeout=120):
begin = time.time()
whereas time.time() - begin < timeout:
attempt:
r = requests.get(f"{GATEWAY_URL}/", timeout=5)
if r.status_code in (200, 401, 403, 404):
return True
besides Exception:
go
time.sleep(2)
return False
assert wait_for_gateway(), Path(gateway_log).read_text()[-6000:]
headers = {
"Authorization": f"Bearer {GATEWAY_TOKEN}",
"Content-Type": "application/json"
}
def openclaw_chat(messages, consumer="demo-user", agent_id="main", temperature=0.2):
payload = {
"model": f"openclaw:{agent_id}",
"messages": messages,
"user": consumer,
"temperature": temperature,
"stream": False
}
r = requests.publish(
f"{GATEWAY_URL}/v1/chat/completions",
headers=headers,
json=payload,
timeout=180
)
r.raise_for_status()
return r.json()
class ActionProposal(BaseModel):
user_request: str
class: str
threat: str
confidence: float = Area(ge=0.0, le=1.0)
requires_approval: bool
enable: bool
motive: strWe watch for the OpenClaw Gateway to completely initialize earlier than sending any requests. We create the HTTP headers and implement a helper operate that sends chat requests to the OpenClaw Gateway by the /v1/chat/completions endpoint. We additionally outline the ActionProposal schema that can later characterize the governance classification for every consumer request.
def classify_request(user_request: str) -> ActionProposal:
textual content = user_request.decrease()
red_terms = [
"delete", "remove permanently", "wire money", "transfer funds",
"payroll", "bank", "hr record", "employee record", "run shell",
"execute command", "api key", "secret", "credential", "token",
"ssh", "sudo", "wipe", "exfiltrate", "upload private", "database dump"
]
amber_terms = [
"email", "send", "notify", "customer", "vendor", "contract",
"invoice", "budget", "approve", "security policy", "confidential",
"write file", "modify", "change"
]
if any(t in textual content for t in red_terms):
return ActionProposal(
user_request=user_request,
class="high_impact",
threat="red",
confidence=0.92,
requires_approval=True,
enable=False,
motive="High-impact or sensitive action detected"
)
if any(t in textual content for t in amber_terms):
return ActionProposal(
user_request=user_request,
class="moderate_impact",
threat="amber",
confidence=0.76,
requires_approval=True,
enable=True,
motive="Moderate-risk action requires human approval before execution"
)
return ActionProposal(
user_request=user_request,
class="low_impact",
threat="green",
confidence=0.88,
requires_approval=False,
enable=True,
motive="Low-risk request"
)
def simulated_human_approval(proposal: ActionProposal) -> Dict[str, Any]:
if proposal.threat == "red":
permitted = False
observe = "Rejected automatically in demo for red-risk request"
elif proposal.threat == "amber":
permitted = True
observe = "Approved automatically in demo for amber-risk request"
else:
permitted = True
observe = "No approval required"
return {
"approved": permitted,
"reviewer": "simulated_manager",
"note": observe
}
@dataclass
class TraceEvent:
trace_id: str
ts: str
stage: str
payload: Dict[str, Any]We construct the governance logic that analyzes incoming consumer requests and assigns a threat stage to every. We implement a classification operate that labels requests as inexperienced, amber, or crimson relying on their potential operational impression. We additionally add a simulated human approval mechanism and outline the hint occasion construction to file governance choices and actions.
class TraceStore:
def __init__(self, path="openclaw_traces.jsonl"):
self.path = path
Path(self.path).write_text("")
def append(self, occasion: TraceEvent):
with open(self.path, "a") as f:
f.write(json.dumps(asdict(occasion)) + "n")
def read_all(self):
rows = []
with open(self.path, "r") as f:
for line in f:
line = line.strip()
if line:
rows.append(json.hundreds(line))
return rows
trace_store = TraceStore()
def now():
return datetime.now(timezone.utc).isoformat()
SYSTEM_PROMPT = """
You might be an enterprise OpenClaw assistant working beneath governance controls.
Guidelines:
- By no means declare an motion has been executed until the governance layer explicitly permits it.
- For low-risk requests, reply usually and helpfully.
- For moderate-risk requests, suggest a protected plan and point out any approvals or checks that may be wanted.
- For top-risk requests, refuse to execute and as a substitute present a safer non-operational various equivalent to a draft, guidelines, abstract, or evaluate plan.
- Be concise however helpful.
"""
def governed_openclaw_run(user_request: str, session_user: str = "employee-001") -> Dict[str, Any]:
trace_id = str(uuid.uuid4())
proposal = classify_request(user_request)
trace_store.append(TraceEvent(trace_id, now(), "classification", proposal.model_dump()))
approval = None
if proposal.requires_approval:
approval = simulated_human_approval(proposal)
trace_store.append(TraceEvent(trace_id, now(), "approval", approval))
if proposal.threat == "red":
end result = {
"trace_id": trace_id,
"status": "blocked",
"proposal": proposal.model_dump(),
"approval": approval,
"response": "This request is blocked by governance policy. I can help by drafting a safe plan, a checklist, or an approval packet instead."
}
trace_store.append(TraceEvent(trace_id, now(), "blocked", end result))
return end result
if proposal.threat == "amber" and never approval["approved"]:
end result = {
"trace_id": trace_id,
"status": "awaiting_or_rejected",
"proposal": proposal.model_dump(),
"approval": approval,
"response": "This request requires approval and was not cleared."
}
trace_store.append(TraceEvent(trace_id, now(), "halted", end result))
return end result
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"Governance classification: {proposal.model_dump_json()}nnUser request: {user_request}"}
]
uncooked = openclaw_chat(messages=messages, consumer=session_user, agent_id="main", temperature=0.2)
assistant_text = uncooked["choices"][0]["message"]["content"]
end result = {
"trace_id": trace_id,
"status": "executed_via_openclaw",
"proposal": proposal.model_dump(),
"approval": approval,
"response": assistant_text,
"openclaw_raw": uncooked
}
trace_store.append(TraceEvent(trace_id, now(), "executed", {
"status": end result["status"],
"response_preview": assistant_text[:500]
}))
return end result
demo_requests = [
"Summarize our AI governance policy for internal use.",
"Draft an email to finance asking for confirmation of the Q1 cloud budget.",
"Send an email to all employees that payroll will be delayed by 2 days.",
"Transfer funds from treasury to vendor account immediately.",
"Run a shell command to archive the home directory and upload it."
]
outcomes = [governed_openclaw_run(x) for x in demo_requests]
for r in outcomes:
print("=" * 120)
print("TRACE:", r["trace_id"])
print("STATUS:", r["status"])
print("RISK:", r["proposal"]["risk"])
print("APPROVAL:", r["approval"])
print("RESPONSE:n", r["response"][:1500])
trace_df = pd.DataFrame(trace_store.read_all())
trace_df.to_csv("openclaw_governance_traces.csv", index=False)
print("nSaved: openclaw_governance_traces.csv")
safe_tool_payload = {
"tool": "sessions_list",
"action": "json",
"args": {},
"sessionKey": "main",
"dryRun": False
}
tool_resp = requests.publish(
f"{GATEWAY_URL}/tools/invoke",
headers=headers,
json=safe_tool_payload,
timeout=60
)
print("n/tools/invoke status:", tool_resp.status_code)
print(tool_resp.textual content[:1500])We implement the total ruled execution workflow across the OpenClaw agent. We log each step of the request lifecycle, together with classification, approval choices, agent execution, and hint recording. Lastly, we run a number of instance requests by the system, save the governance traces for auditing, and reveal how you can invoke OpenClaw instruments by the Gateway.
In conclusion, we efficiently applied a sensible governance framework round an OpenClaw-powered AI assistant. We configured the OpenClaw Gateway, linked it to Python by the OpenAI-compatible API, and constructed a structured workflow that features request classification, simulated human approvals, managed agent execution, and full audit tracing. This method exhibits how OpenClaw may be built-in into enterprise environments the place AI programs should function beneath strict governance guidelines. By combining coverage enforcement, approval workflows, and hint logging with OpenClaw’s agent runtime, we created a sturdy basis for constructing safe and accountable AI-driven automation programs.
Take a look at Full Pocket book right here. Additionally, be happy to comply with us on Twitter and don’t neglect to affix our 120k+ ML SubReddit and Subscribe to our Publication. Wait! are you on telegram? now you’ll be able to be a part of us on telegram as properly.



