决策端点¶
ClawSentry Gateway 提供多种传输通道接收 AI Agent 运行时事件,并返回统一的 CanonicalDecision 安全决策。本页覆盖所有决策相关端点。
决策模型概览¶
所有端点最终返回统一的 CanonicalDecision:
{
"decision": "allow | block | defer | modify",
"reason": "human-readable explanation",
"policy_id": "L1-D1-destructive-tool",
"risk_level": "low | medium | high | critical",
"decision_source": "policy | manual | system",
"policy_version": "1.0",
"decision_latency_ms": 12.5,
"modified_payload": null,
"retry_after_ms": null,
"failure_class": "none",
"final": true
}
| 判决 | 含义 | final |
|---|---|---|
allow |
允许执行 | 必须为 true |
block |
拒绝执行 | 必须为 true |
defer |
需人工审批 | 可选 |
modify |
允许执行但修改参数 | 可选,需附带 modified_payload |
POST /ahp — OpenClaw Webhook 决策¶
接收 OpenClaw Webhook 事件(JSON-RPC 2.0 封装),归一化为 AHP 协议并返回安全决策。
认证¶
- Bearer Token:
Authorization: Bearer <CS_AUTH_TOKEN> - 详见 认证文档
请求格式¶
请求体为 JSON-RPC 2.0 封装的 SyncDecisionRequest:
{
"jsonrpc": "2.0",
"id": 1,
"method": "ahp/sync_decision",
"params": {
"rpc_version": "sync_decision.1.0",
"request_id": "req-abc-123",
"deadline_ms": 100,
"decision_tier": "L1",
"event": {
"schema_version": "ahp.1.0",
"event_id": "evt-001",
"trace_id": "trace-001",
"event_type": "pre_action",
"session_id": "session-001",
"agent_id": "agent-001",
"source_framework": "openclaw",
"occurred_at": "2026-03-23T10:30:00+00:00",
"event_subtype": "exec.approval.requested",
"tool_name": "bash",
"risk_hints": ["shell_execution", "destructive_pattern"],
"payload": {
"command": "rm -rf /important-data",
"approval_id": "apr-001"
},
"source_protocol_version": "1.0",
"mapping_profile": "openclaw@abc1234/protocol.v1/profile.v1"
},
"context": {
"caller_adapter": "openclaw-adapter.v1"
}
}
}
关键字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
rpc_version |
string | 必须为 sync_decision.1.0 |
|
request_id |
string | 请求唯一标识,用于幂等性缓存 | |
deadline_ms |
int | 决策超时(1-5000 ms) | |
decision_tier |
enum | 决策层级:L1(规则引擎)或 L2(含 LLM 分析) |
|
event |
object | AHP CanonicalEvent | |
context |
object | 可选决策上下文 |
成功响应¶
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"rpc_version": "sync_decision.1.0",
"request_id": "req-abc-123",
"rpc_status": "ok",
"decision": {
"decision": "block",
"reason": "D1: destructive tool pattern detected (rm -rf)",
"policy_id": "L1-D1-destructive-tool",
"risk_level": "high",
"decision_source": "policy",
"policy_version": "1.0",
"decision_latency_ms": 2.3,
"failure_class": "none",
"final": true
},
"actual_tier": "L1",
"served_at": "2026-03-23T10:30:00.002+00:00"
}
}
错误响应¶
当请求校验失败、超时、版本不支持或引擎不可用时,返回 JSON-RPC 2.0 错误:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "Unsupported rpc_version: 'sync_decision.2.0'",
"data": {
"rpc_version": "sync_decision.1.0",
"request_id": "req-abc-123",
"rpc_status": "error",
"rpc_error_code": "VERSION_NOT_SUPPORTED",
"rpc_error_message": "Unsupported rpc_version: 'sync_decision.2.0'",
"retry_eligible": false,
"retry_after_ms": null,
"fallback_decision": null
}
}
}
错误码一览:
rpc_error_code |
含义 | retry_eligible |
|---|---|---|
INVALID_REQUEST |
请求格式错误 | false |
EVENT_SCHEMA_MISMATCH |
事件 Schema 不匹配 | false |
VERSION_NOT_SUPPORTED |
RPC 版本不支持 | false |
DEADLINE_EXCEEDED |
决策超时(附 fallback_decision) |
true |
ENGINE_UNAVAILABLE |
引擎启动中 | true |
ENGINE_INTERNAL_ERROR |
引擎内部错误 | true |
RATE_LIMITED |
速率限制 | true |
幂等性¶
同一 request_id 在 TTL 窗口内(与 deadline_ms 关联)重复请求,直接返回缓存的决策结果。缓存自动定期清理(间隔 10 秒)。
curl 示例¶
curl -X POST http://127.0.0.1:8080/ahp \
-H "Authorization: Bearer $CS_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "ahp/sync_decision",
"params": {
"rpc_version": "sync_decision.1.0",
"request_id": "test-001",
"deadline_ms": 500,
"decision_tier": "L1",
"event": {
"schema_version": "ahp.1.0",
"event_id": "evt-test-001",
"trace_id": "trace-test-001",
"event_type": "pre_action",
"session_id": "sess-test",
"agent_id": "agent-test",
"source_framework": "a3s-code",
"occurred_at": "2026-03-23T10:00:00+00:00",
"event_subtype": "PreToolUse",
"tool_name": "bash",
"payload": {"command": "echo hello"}
}
}
}'
POST /ahp/a3s — a3s-code HTTP Transport¶
为 a3s-code 提供直接 HTTP 接入的 AHP 事件提交端点。支持 handshake(握手)和 event(事件)两种消息类型。
认证¶
- Bearer Token:
Authorization: Bearer <CS_AUTH_TOKEN>
协议流程¶
Client Gateway
| |
|--- handshake ------------------> |
|<-- handshake result ----------- |
| |
|--- event (pre_action) ---------> |
|<-- decision ------------------- |
| |
|--- event (post_action) --------> |
|<-- decision ------------------- |
Handshake 请求¶
Handshake 响应¶
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocol_version": "2.0",
"harness_info": {
"name": "a3s-gateway-harness",
"version": "1.0.0",
"capabilities": [
"pre_action",
"post_action",
"pre_prompt",
"session",
"error"
]
}
}
}
事件请求¶
发送 AHP 事件以获取安全决策:
{
"jsonrpc": "2.0",
"id": 2,
"method": "ahp/event",
"params": {
"event_type": "pre_action",
"session_id": "session-001",
"agent_id": "agent-001",
"payload": {
"tool": "bash",
"command": "rm -rf /tmp/data",
"arguments": {
"command": "rm -rf /tmp/data"
}
}
}
}
事件响应¶
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"action": "block",
"decision": "block",
"reason": "D1: destructive tool pattern detected",
"metadata": {
"source": "clawsentry-gateway-harness",
"policy_id": "L1-D1-destructive-tool",
"risk_level": "high",
"decision_source": "policy",
"final": true
}
}
}
action 字段映射:
| AHP Decision | a3s-code Action |
|---|---|
allow |
continue |
block |
block |
defer |
defer |
modify |
modify(附带 modified_payload) |
支持的 event_type 值¶
pre_action, pre_tool_use, post_action, post_tool_use,
pre_prompt, generate_start, session_start, session_end, error
curl 示例¶
# 握手
curl -X POST http://127.0.0.1:8080/ahp/a3s \
-H "Authorization: Bearer $CS_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"ahp/handshake","params":{}}'
# 提交事件
curl -X POST http://127.0.0.1:8080/ahp/a3s \
-H "Authorization: Bearer $CS_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"params": {
"event_type": "pre_action",
"session_id": "test-session",
"agent_id": "test-agent",
"payload": {
"tool": "bash",
"command": "ls -la /home"
}
}
}'
POST /ahp/resolve — DEFER 决策代理¶
代理 DEFER 决策的操作员确认——将允许/拒绝指令转发到 OpenClaw WebSocket 客户端。
认证¶
- Bearer Token:
Authorization: Bearer <CS_AUTH_TOKEN>
请求¶
{
"approval_id": "apr-abc-123",
"decision": "allow-once",
"reason": "Operator approved after manual review"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
approval_id |
string | 审批请求 ID(来自 OpenClaw 事件) | |
decision |
string | allow-once 或 deny |
|
reason |
string | 可选的决策原因说明 |
成功响应¶
错误响应¶
无 OpenClaw 连接(503):
请求参数错误(400):
无效 decision 值(400):
上游解析失败(502):
优雅降级¶
当 OpenClaw 不支持 reason 字段(由于 additionalProperties: false 限制)时,resolve 端点会自动重试——先带 reason 发送,失败后去掉 reason 再次发送。
curl 示例¶
# 允许执行
curl -X POST http://127.0.0.1:8080/ahp/resolve \
-H "Authorization: Bearer $CS_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"approval_id": "apr-001", "decision": "allow-once"}'
# 拒绝执行
curl -X POST http://127.0.0.1:8080/ahp/resolve \
-H "Authorization: Bearer $CS_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"approval_id": "apr-001", "decision": "deny", "reason": "suspicious operation"}'
UDS Transport — Unix Domain Socket¶
UDS 是 ClawSentry 的主传输通道,提供最低延迟的进程间通信。a3s-code Harness 默认通过 UDS 连接 Gateway。
连接信息¶
| 项目 | 值 |
|---|---|
| Socket 路径 | /tmp/clawsentry.sock(或 CS_UDS_PATH) |
| 协议 | JSON-RPC 2.0 |
| 方法 | ahp/sync_decision |
| 帧格式 | 4 字节大端序长度前缀 + JSON Payload |
| 权限 | chmod 0600(仅所有者可读写) |
帧格式¶
+------------------+--------------------+
| 4 bytes (uint32) | N bytes (JSON) |
| big-endian | UTF-8 encoded |
| = N | JSON-RPC 2.0 body |
+------------------+--------------------+
请求示例¶
{
"jsonrpc": "2.0",
"id": 1,
"method": "ahp/sync_decision",
"params": {
"rpc_version": "sync_decision.1.0",
"request_id": "uds-req-001",
"deadline_ms": 100,
"decision_tier": "L1",
"event": {
"schema_version": "ahp.1.0",
"event_id": "evt-uds-001",
"trace_id": "trace-uds-001",
"event_type": "pre_action",
"session_id": "session-001",
"agent_id": "agent-001",
"source_framework": "a3s-code",
"occurred_at": "2026-03-23T10:00:00+00:00",
"event_subtype": "PreToolUse",
"tool_name": "bash",
"payload": {
"command": "cat /etc/passwd"
}
},
"context": {
"caller_adapter": "a3s-adapter.v1"
}
}
}
响应示例¶
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"rpc_version": "sync_decision.1.0",
"request_id": "uds-req-001",
"rpc_status": "ok",
"decision": {
"decision": "defer",
"reason": "D2: sensitive path (/etc/passwd) access detected",
"policy_id": "L1-D2-sensitive-path",
"risk_level": "medium",
"decision_source": "policy",
"policy_version": "1.0",
"decision_latency_ms": 0.8,
"failure_class": "none",
"final": false
},
"actual_tier": "L1",
"served_at": "2026-03-23T10:00:00.001+00:00"
}
}
安全限制¶
| 限制 | 值 |
|---|---|
| 最大帧大小 | 10 MB |
| Socket 文件权限 | 0600 |
| 超时 | 由请求方 deadline_ms 控制 |
Python 客户端示例¶
import asyncio
import json
import struct
async def send_uds_request(uds_path: str, request: dict) -> dict:
"""发送 JSON-RPC 2.0 请求到 ClawSentry UDS。"""
reader, writer = await asyncio.open_unix_connection(uds_path)
try:
body = json.dumps(request).encode("utf-8")
# 写入 4 字节长度前缀 + JSON payload
writer.write(struct.pack("!I", len(body)))
writer.write(body)
await writer.drain()
# 读取响应
length_bytes = await reader.readexactly(4)
resp_length = struct.unpack("!I", length_bytes)[0]
resp_data = await reader.readexactly(resp_length)
return json.loads(resp_data)
finally:
writer.close()
await writer.wait_closed()
三层决策模型¶
所有决策端点共享同一个三层决策引擎:
| 层级 | 名称 | 典型延迟 | 说明 |
|---|---|---|---|
| L1 | 规则引擎 | < 1 ms | D1-D5 五维风险评分 + 短路规则 |
| L2 | LLM 语义分析 | < 3 s | 调用 LLM 进行上下文感知的语义分析 |
| L3 | 审查 Agent | < 30 s | 多轮工具调用的深度安全审查 |
D1-D5 风险维度¶
| 维度 | 范围 | 说明 |
|---|---|---|
| D1 | 0-3 | 工具类型危险度 |
| D2 | 0-3 | 目标路径敏感度 |
| D3 | 0-3 | 命令模式危险度 |
| D4 | 0-2 | 上下文风险累积 |
| D5 | 0-2 | Agent 信任等级 |
综合风险分 = max(D1, D2, D3) + D4 + D5,范围 0-7。
风险等级映射¶
| 综合分 | 风险等级 |
|---|---|
| 0-1 | low |
| 2-3 | medium |
| 4-5 | high |
| 6-7 | critical |