OpenClaw 集成¶
将 OpenClaw 代理框架接入 ClawSentry,实现命令执行审批的实时安全监督。
概述¶
OpenClaw 是一个 AI 代理框架,提供 Gateway 模式下的命令执行审批系统。ClawSentry 通过 WebSocket 实时连接 OpenClaw Gateway,作为 operator 客户端监听 exec.approval.requested 事件,经三层决策引擎评估后调用 exec.approval.resolve 返回 allow / deny 判决。
sequenceDiagram
participant Agent as OpenClaw Agent
participant OG as OpenClaw Gateway
participant CS as ClawSentry (WS 客户端)
participant Engine as L1/L2/L3 引擎
Agent->>OG: 执行命令 (exec)
OG->>OG: exec-approvals 检查
OG-->>CS: WS event: exec.approval.requested
CS->>Engine: normalize + evaluate
Engine-->>CS: CanonicalDecision
CS->>OG: WS req: exec.approval.resolve (allow/deny)
OG-->>Agent: 命令允许/拒绝
关键架构特征¶
- 增量级集成 — ClawSentry 不修改 OpenClaw 也能独立工作;OpenClaw 侧的配置是可选增强层
- 双向 WS 通信 — 既接收 approval 事件,也主动发送 resolve RPC
- 优雅降级 — 当 OpenClaw 不支持
reason字段时,自动去除 reason 重试
前置条件¶
环境要求
- Python 3.10+
- ClawSentry 已安装
- OpenClaw Gateway 已运行(Docker 或本地部署)
- OpenClaw Gateway Token(位于
~/.openclaw/openclaw.json)
快速开始¶
一键初始化 + 自动配置¶
ClawSentry 提供 --setup 选项,可自动检测并配置 OpenClaw:
# 预览将要执行的配置变更(不修改任何文件)
clawsentry init openclaw --auto-detect --setup --dry-run
# 确认无误后,执行自动配置
clawsentry init openclaw --auto-detect --setup
--setup 执行以下操作:
| 操作 | 文件 | 变更内容 |
|---|---|---|
| 设置执行模式 | ~/.openclaw/openclaw.json |
tools.exec.host → "gateway" |
| 设置审批策略 | ~/.openclaw/exec-approvals.json |
security → "allowlist", ask → "always" |
| 自动备份 | *.bak |
修改前自动创建 .bak 备份文件 |
同时生成 .env.clawsentry,内容包括:
# ClawSentry — OpenClaw integration config
OPENCLAW_WEBHOOK_TOKEN=<自动生成>
CS_AUTH_TOKEN=<自动生成>
CS_HTTP_PORT=8080
OPENCLAW_WEBHOOK_PORT=8081
OPENCLAW_ENFORCEMENT_ENABLED=true
OPENCLAW_WS_URL=ws://127.0.0.1:18789
OPENCLAW_OPERATOR_TOKEN=<从 openclaw.json 自动读取>
自定义 OpenClaw 配置目录
如果 OpenClaw 配置不在默认的 ~/.openclaw/,可以指定路径:
启动 Gateway¶
当检测到 OpenClaw 配置时,日志输出:
INFO [ahp-stack] Full stack starting: gateway=http://127.0.0.1:8080/ahp uds=/tmp/clawsentry.sock webhook=http://127.0.0.1:8081/webhook/openclaw
INFO [openclaw-approval-client] Connected to OpenClaw Gateway at ws://127.0.0.1:18789
INFO [openclaw-approval-client] WS event listener started
如果没有检测到 OpenClaw 配置:
INFO [ahp-stack] Gateway-only starting: gateway=http://127.0.0.1:8080/ahp uds=/tmp/clawsentry.sock (no OpenClaw config detected)
手动配置详解¶
如果不使用 --setup 自动配置,需要手动完成以下步骤。
步骤 1: 配置 OpenClaw Gateway¶
openclaw.json¶
关键配置
tools.exec.host 必须设为 "gateway"。默认值 "sandbox" 会跳过所有审批检查,命令直接执行。
编辑 ~/.openclaw/openclaw.json:
{
"tools": {
"exec": {
"host": "gateway"
}
},
"gateway": {
"auth": {
"token": "<your-gateway-token>"
},
"controlUi": {
"allowedOrigins": ["http://127.0.0.1:18789"]
}
}
}
各字段说明:
| 字段 | 必须 | 说明 |
|---|---|---|
tools.exec.host |
必须为 "gateway" — 启用审批事件广播 |
|
gateway.auth.token |
Gateway 认证 Token,ClawSentry 用此连接 WS | |
gateway.controlUi.allowedOrigins |
WS Origin 白名单,需包含 Gateway 地址 |
sandbox 模式陷阱
tools.exec.host 默认为 "sandbox"。在 sandbox 模式下,OpenClaw 会直接在沙箱中执行命令,完全跳过 processGatewayAllowlist() 和审批流程。这意味着 ClawSentry 永远收不到任何事件。
exec-approvals.json¶
编辑 ~/.openclaw/exec-approvals.json:
| 字段 | 推荐值 | 说明 |
|---|---|---|
security |
"allowlist" |
所有命令进入审批流程 |
ask |
"always" |
每次执行都需要审批 |
security: deny 的坑
如果设为 "deny",OpenClaw 会在审批前直接拒绝命令,不会触发 WS 广播。ClawSentry 将无法拦截任何事件。
步骤 2: 配置 ClawSentry 环境变量¶
export OPENCLAW_WS_URL=ws://127.0.0.1:18789
export OPENCLAW_OPERATOR_TOKEN=<your-gateway-token>
export OPENCLAW_ENFORCEMENT_ENABLED=true
export CS_HTTP_PORT=8080
步骤 3: 启动服务¶
环境变量参考¶
OpenClaw 连接¶
| 变量 | 默认值 | 说明 |
|---|---|---|
OPENCLAW_WS_URL |
ws://127.0.0.1:18789 |
OpenClaw Gateway WebSocket 地址 |
OPENCLAW_OPERATOR_TOKEN |
(空) | 认证 Token(来自 openclaw.json 的 gateway.auth.token) |
OPENCLAW_ENFORCEMENT_ENABLED |
false |
启用 WS 连接和审批拦截 |
Webhook 接收器¶
| 变量 | 默认值 | 说明 |
|---|---|---|
OPENCLAW_WEBHOOK_TOKEN |
(空) | Webhook 回调认证 Token |
OPENCLAW_WEBHOOK_PORT |
8081 |
Webhook HTTP 接收端口 |
AHP_WEBHOOK_IP_WHITELIST |
(空) | 允许的 Webhook 来源 IP(逗号分隔) |
AHP_WEBHOOK_TOKEN_TTL_SECONDS |
(空) | Token 有效期(秒) |
Gateway 服务¶
| 变量 | 默认值 | 说明 |
|---|---|---|
CS_HTTP_HOST |
127.0.0.1 |
HTTP 监听地址 |
CS_HTTP_PORT |
8080 |
HTTP 监听端口 |
CS_AUTH_TOKEN |
(空) | Bearer Token 认证 |
CS_TRAJECTORY_DB_PATH |
/tmp/clawsentry-trajectory.db |
SQLite 轨迹数据库 |
会话级强制策略¶
| 变量 | 默认值 | 说明 |
|---|---|---|
AHP_SESSION_ENFORCEMENT_ENABLED |
false |
启用会话级强制策略 |
AHP_SESSION_ENFORCEMENT_THRESHOLD |
3 |
高风险事件触发阈值 |
AHP_SESSION_ENFORCEMENT_ACTION |
defer |
触发动作:defer / block / l3_require |
AHP_SESSION_ENFORCEMENT_COOLDOWN_SECONDS |
600 |
冷却时间(秒) |
LLM 语义分析(可选)¶
| 变量 | 默认值 | 说明 |
|---|---|---|
AHP_LLM_PROVIDER |
(空) | LLM 提供商:anthropic / openai |
AHP_LLM_BASE_URL |
(提供商默认) | 自定义 API 地址 |
AHP_LLM_MODEL |
(提供商默认) | 模型标识符 |
事件流详解¶
WebSocket 连接参数¶
ClawSentry 使用以下参数连接 OpenClaw Gateway:
# WebSocket 连接
ws_url = "ws://127.0.0.1:18789"
headers = {
"Authorization": "Bearer <operator_token>",
"Origin": "http://127.0.0.1:18789"
}
# 认证握手
connect_request = {
"type": "req",
"method": "connect",
"params": {
"minProtocol": 3,
"maxProtocol": 3,
"client": {
"id": "openclaw-control-ui", # 必须!保留 operator scope
"version": "1.0.0",
"platform": "linux",
"mode": "backend"
},
"role": "operator",
"scopes": ["operator.read", "operator.write", "operator.approvals"],
"auth": {"token": "<operator_token>"}
}
}
client.id 必须为 openclaw-control-ui
OpenClaw Gateway 的 message-handler.ts 通过 client.id === "openclaw-control-ui" 判定是否为 controlUi 客户端。非 controlUi 客户端在没有绑定设备时会被清空 scope,导致无法接收 approval 事件。
事件格式:exec.approval.requested¶
当 OpenClaw Agent 执行命令时,Gateway 通过 WS 广播:
{
"type": "event",
"event": "exec.approval.requested",
"payload": {
"id": "approval-uuid-123",
"request": {
"command": "npm install express",
"sessionKey": "session-abc",
"agentId": "agent-001"
}
}
}
Payload 结构注意
命令字段在 payload.request.command 而不是 payload.command。会话标识在 payload.request.sessionKey,Agent ID 在 payload.request.agentId。
决策映射¶
ClawSentry 内部判决映射到 OpenClaw 审批决策:
| ClawSentry 判决 | OpenClaw 审批 | 行为 |
|---|---|---|
ALLOW |
allow-once |
允许本次命令执行 |
BLOCK |
deny |
拒绝命令执行 |
DEFER |
(不发送 resolve) | 等待人工审批或自然超时 |
Resolve 请求格式¶
{
"type": "req",
"id": "<unique-request-id>",
"method": "exec.approval.resolve",
"params": {
"id": "approval-uuid-123",
"decision": "deny",
"reason": "L1: destructive_pattern detected"
}
}
DEFER 处理¶
当 L1/L2 引擎将事件判定为 DEFER(中等风险,需人工确认)时,ClawSentry 不会自动 resolve。运维人员可以通过以下方式处理:
CLI 交互模式¶
收到 DEFER 事件时,终端提示:
操作说明:
- A — 发送
allow-once到 OpenClaw - D — 发送
deny到 OpenClaw - S — 跳过,让 OpenClaw 超时自动处理
Web 仪表板¶
打开 http://127.0.0.1:8080/ui,进入 DEFER Panel:
- 实时展示待审批的 DEFER 决策
- 每个条目显示倒计时
- 点击 Allow 或 Deny 按钮操作
- 当 OpenClaw 不可达时,显示 503 降级提示
REST API¶
# 通过 API 代理 resolve(Gateway 转发到 OpenClaw WS)
curl -X POST http://127.0.0.1:8080/ahp/resolve \
-H 'Content-Type: application/json' \
-d '{
"approval_id": "approval-uuid-123",
"decision": "allow-once"
}'
503 降级
如果 OpenClaw WS 连接不可用,/ahp/resolve 返回 503 并提示无法代理。
Resolve 优雅降级¶
OpenClaw 的 ExecApprovalResolveParamsSchema 使用 additionalProperties: false 配合 AJV 的 removeAdditional: false,这意味着额外的 reason 字段会导致请求被拒绝。
ClawSentry 的 resolve 实现了自动降级重试:
1. 发送 resolve(包含 reason 字段)
2. 如果 OpenClaw 返回 "additional properties" 错误
3. 自动去除 reason 字段,重新发送
4. 记录日志: "OpenClaw rejected reason field, retrying without it"
这确保了无论 OpenClaw 版本是否支持 reason 字段,resolve 都能正常工作。
真实 E2E 验证结果¶
以下是 ClawSentry 连接真实 OpenClaw Gateway 的端到端拦截验证结果:
| 命令 | 风险等级 | 决策 | 响应时间 |
|---|---|---|---|
rm -rf /important-data |
high | BLOCK (deny) | 57ms |
sudo chmod 777 /etc/passwd |
high | BLOCK (deny) | 54ms |
echo hello world |
medium | DEFER | 54ms |
验证要点
- OpenClaw Agent(
openclaw agent --session-id)生成的真实工具调用被 Monitor 成功拦截 - 高危命令在 60ms 内被自动阻止(deny resolve 发回 OpenClaw)
- Gateway 日志确认
exec.approval.resolved事件被正确广播 - L1 规则引擎的
destructive_pattern检测在 sub-millisecond 内完成判决
实时监控¶
SSE 事件类型¶
ClawSentry 通过 SSE 推送以下事件,均可在 clawsentry watch 或 Web 仪表板中查看:
| 事件类型 | 说明 |
|---|---|
decision |
每次决策结果(含 command、reason、risk_level) |
session_start |
新会话开始 |
session_risk_change |
会话风险等级变化 |
session_enforcement_change |
会话强制策略触发/释放 |
alert |
高危告警 |
监控命令¶
# 实时彩色输出
clawsentry watch
# 仅看 decision 和 alert
clawsentry watch --filter decision,alert
# JSON 格式(适合管道处理)
clawsentry watch --json | jq '.decision'
# SSE 原始流
curl -N http://127.0.0.1:8080/report/stream
# 带认证的 SSE(用于 EventSource)
curl -N "http://127.0.0.1:8080/report/stream?token=<your-token>"
REST 查询¶
# 聚合统计
curl http://127.0.0.1:8080/report/summary
# 活跃会话(按风险排序)
curl http://127.0.0.1:8080/report/sessions
# 会话详情 + D1-D5 风险维度
curl http://127.0.0.1:8080/report/session/{session_id}/risk
# 告警列表
curl http://127.0.0.1:8080/report/alerts
# 确认告警
curl -X POST http://127.0.0.1:8080/report/alerts/{alert_id}/acknowledge
# 会话强制执行状态
curl http://127.0.0.1:8080/report/session/{session_id}/enforcement
# 手动释放强制执行
curl -X POST http://127.0.0.1:8080/report/session/{session_id}/enforcement \
-H 'Content-Type: application/json' \
-d '{"action": "release"}'
OpenClaw Docker 部署参考¶
如果使用 Docker 运行 OpenClaw Gateway:
# 构建镜像(需要网络代理时加 --network=host)
DOCKER_BUILDKIT=1 docker build --network=host \
--progress=plain -t openclaw:local -f Dockerfile .
# 启动容器
docker run -d \
--name openclaw-gateway \
--network host \
--init \
-e HOME=/home/node \
-e OPENCLAW_GATEWAY_TOKEN=<your-token> \
-v ~/.openclaw:/home/node/.openclaw \
openclaw:local \
node dist/index.js gateway \
--bind loopback \
--port 18789 \
--allow-unconfigured
网络模式
使用 --network host 使容器直接绑定宿主机的 127.0.0.1:18789,ClawSentry 可以直接通过 ws://127.0.0.1:18789 连接。
故障排查¶
WS 连接失败:scope 被清空
症状:连接成功但收不到任何 approval 事件。
原因:client.id 不是 openclaw-control-ui,OpenClaw 在 message-handler.ts:537 清空了非 controlUi 客户端的 scope。
解决:
- 确认环境变量配置正确 — ClawSentry 默认使用
client.id = "openclaw-control-ui" - 确认
gateway.controlUi.allowedOrigins包含了正确的 Origin 地址 - 检查日志中是否有
Connected to OpenClaw Gateway输出
连接成功但没有 approval 事件
可能原因:
-
tools.exec.host不是"gateway"— 这是最常见的原因。sandbox 模式完全跳过审批。 -
确保设置为exec-approvals.json配置为security: "deny"— 命令在审批前就被拒绝了。"security": "allowlist"+"ask": "always"。 -
Agent 没有触发工具调用 — 确认 Agent 确实在执行命令。
Token 认证失败
症状:日志输出 OpenClaw Gateway auth failed: ...
解决:
- 确认
OPENCLAW_OPERATOR_TOKEN与~/.openclaw/openclaw.json中的gateway.auth.token一致 - 注意是
gateway.auth.token,不是旧版的gateway.token - 可以使用
--setup自动读取:
resolve 失败:additional properties 错误
症状:日志出现 OpenClaw rejected reason field, retrying without it
说明:这是正常的降级行为。OpenClaw 的 ExecApprovalResolveParamsSchema 不接受 reason 字段,ClawSentry 自动去除后重试。resolve 仍然会成功。
如果 resolve 完全失败,检查:
- Approval ID 是否仍然有效(可能已超时)
- WS 连接是否仍然存活
- 检查 OpenClaw Gateway 日志
DEFER 决策超时无人处理
说明:当 DEFER 事件没有被人工处理时,OpenClaw 会按其自身的超时策略自动处理(通常是拒绝)。
建议:
- 使用
clawsentry watch --interactive保持交互模式 - 或打开 Web 仪表板
http://127.0.0.1:8080/ui监控 DEFER 面板 - 配置会话强制策略,在频繁 DEFER 后自动升级为 BLOCK:
Gateway 检测不到 OpenClaw 配置
症状:日志输出 Gateway-only starting ... (no OpenClaw config detected)
解决:
- 确认
OPENCLAW_ENFORCEMENT_ENABLED=true已设置 - 确认
OPENCLAW_OPERATOR_TOKEN不为空 - 确认
OPENCLAW_WS_URL格式正确(如ws://127.0.0.1:18789) - 加载环境变量:
source .env.clawsentry
Webhook 接收器收不到事件
说明:Webhook 是补充通道。主要事件流通过 WS 实现。
- 确认 OpenClaw 侧配置了正确的 Webhook URL:
http://127.0.0.1:8081/webhook/openclaw - 检查 IP 白名单:
AHP_WEBHOOK_IP_WHITELIST - 检查 Token:
OPENCLAW_WEBHOOK_TOKEN