0%

Claude Code 实战 (24):权限系统水晶包开发

Claude Code 实战 (24):权限系统水晶包开发

导读: 这是 Claude Code 源码解析系列的第 24 篇,实战篇第 4 篇。基于 Claude Code 多层权限决策引擎 (第 9 篇),实战开发权限系统水晶包。


📋 目录

  1. 权限系统水晶包概述
  2. 基于 Claude Code 权限系统设计
  3. 实战:开发权限系统水晶包
  4. 权限管理最佳实践
  5. 总结

权限系统水晶包概述

核心功能

权限系统水晶包 = Claude Code Permission Decision Engine OpenClaw 化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
权限系统水晶包提供:
├── 规则管理
│ ├── 全局规则 (Global Rules)
│ ├── 工作区规则 (Workspace Rules)
│ └── 会话规则 (Session Rules)
├── 权限决策
│ ├── 规则匹配 (Rule Matching)
│ ├── AI 分类器 (AI Classifier)
│ └── 用户确认 (User Confirmation)
├── 审批流程
│ ├── 审批请求
│ ├── 审批历史
│ └── 记住选择
└── 审计日志
├── 决策记录
├── 统计报告
└── 合规报告

使用场景

场景 风险级别 权限决策
删除文件 中风险 需要确认
修改配置 中风险 需要确认
安装软件 低风险 允许 (devops Agent)
删除系统文件 严重风险 直接拒绝
查看文件 低风险 直接允许

基于 Claude Code 权限系统设计

Claude Code 权限系统回顾 (第 9 篇)

多层权限决策架构:

1
2
3
请求 → 全局规则 → 工作区规则 → 会话规则 → AI 分类器 → 用户确认
↓ ↓ ↓ ↓ ↓
Allow Allow/Deny Allow/Deny Allow/Deny Allow/Deny

权限规则定义 (第 9 篇):

1
2
3
4
5
6
7
8
9
10
11
interface PermissionRule {
id: string;
scope: 'global' | 'workspace' | 'session';
match: {
tool: string;
pattern: string;
conditions?: { agent?: string; cwd?: string };
};
action: 'allow' | 'deny' | 'ask';
priority: number;
}

AI 分类器 (第 9 篇):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
async function runClassifier(command: string): Promise<ClassificationResult> {
const prompt = `
分析以下命令的安全性:
命令:${command}

考虑:
1. 是否有破坏性风险?
2. 是否访问敏感位置?
3. 是否执行远程代码?
4. 是否可逆?

返回 JSON: {"safe": boolean, "reason": string, "confidence": number}
`;

const response = await llm.generate(prompt);
return JSON.parse(response.content);
}

水晶包设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
权限系统水晶包架构:

┌─────────────────────────────────────────────────────────────┐
│ 权限请求 │
│ "执行命令:rm -rf node_modules" │
└─────────────────────┬───────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 规则引擎层 │
│ ├── 全局规则引擎 │
│ ├── 工作区规则引擎 │
│ └── 会话规则引擎 │
└─────────────┬───────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ AI 分类器层 │
│ ├── 风险评估 │
│ ├── 置信度计算 │
│ └── 决策建议 │
└─────────────┬───────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 审批引擎层 │
│ ├── 审批请求 │
│ ├── 审批历史 │
│ └── 记住选择 │
└─────────────┬───────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 审计层 │
│ ├── 决策日志 │
│ ├── 统计报告 │
│ └── 合规报告 │
└─────────────────────────────────────────────────────────────┘

实战:开发权限系统水晶包

步骤 1:创建水晶包目录

1
2
3
# 创建水晶包目录
mkdir -p ~/.openclaw/crystals/permission-manager/{scripts,config,tests,docs}
cd ~/.openclaw/crystals/permission-manager

步骤 2:编写 CRYSTAL.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
---
name: permission-manager
version: 1.0.0
description: 权限系统水晶包 (基于 Claude Code Permission Decision Engine)
author: John
license: MIT

# 能力声明
capabilities:
- name: permission_check
description: 权限检查
based_on: Claude Code Permission Decision Engine
features:
- 多层规则匹配
- AI 风险评估
- 审批流程

- name: rule_management
description: 规则管理
based_on: Claude Code Rule Engine
features:
- 规则添加/删除
- 规则导入/导出
- 规则验证

- name: permission_audit
description: 权限审计
based_on: Claude Code Audit Logger
features:
- 决策记录
- 统计报告
- 合规报告

# 配置
config:
# 规则文件
rules:
global: ~/.openclaw/config/permissions/global-rules.yaml
workspace: ./.openclaw/permissions.yaml

# AI 分类器
classifier:
enabled: true
model: claude-sonnet-4-6
confidence_threshold: 0.85

# 审批设置
approval:
remember_choices: true
default_scope: workspace

# 权限
permissions:
- file_read
- file_write
- bash (limited)
---

# 权限系统水晶包

基于 Claude Code Permission Decision Engine 实现的 OpenClaw 水晶包。

## 使用方式

### 检查权限

```bash
openclaw run permission-manager check \
--tool bash \
--command "rm -rf node_modules"

管理规则

1
2
3
4
5
6
7
8
9
10
11
# 添加规则
openclaw run permission-manager rule add \
--pattern "npm install.*" \
--action allow \
--scope workspace

# 列出规则
openclaw run permission-manager rule list

# 删除规则
openclaw run permission-manager rule delete --id rule-001

查看审计

1
2
openclaw run permission-manager audit --limit 20
openclaw run permission-manager report

安全特性

  1. 多层规则 - 全局/工作区/会话三级规则
  2. AI 风险评估 - 智能判断风险级别
  3. 审批流程 - 支持记住选择
  4. 审计日志 - 完整决策记录

测试

1
bash tests/test.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

### 步骤 3:实现核心脚本

**文件:** `scripts/permission-check.sh`

```bash
#!/bin/bash
# 权限检查脚本 (基于 Claude Code Permission Decision Engine)

set -e

TOOL=""
COMMAND=""
AGENT=""
CWD=""
SKIP_AI=false

# 配置
CONFIG_DIR="$HOME/.openclaw/crystals/permission-manager/config"
GLOBAL_RULES="$HOME/.openclaw/config/permissions/global-rules.yaml"
WORKSPACE_RULES="./.openclaw/permissions.yaml"
AUDIT_LOG="$HOME/.openclaw/logs/permission-audit.log"

while [[ $# -gt 0 ]]; do
case $1 in
--tool)
TOOL="$2"
shift 2
;;
--command)
COMMAND="$2"
shift 2
;;
--agent)
AGENT="$2"
shift 2
;;
--cwd)
CWD="$2"
shift 2
;;
--skip-ai)
SKIP_AI=true
shift
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done

# 日志记录
log_decision() {
local tool="$1"
local command="$2"
local decision="$3"
local reason="$4"
local source="$5"
local timestamp=$(date -Iseconds)

mkdir -p "$(dirname "$AUDIT_LOG")"
echo "$timestamp | $tool | $command | $decision | $reason | $source" >> "$AUDIT_LOG"
}

# 加载规则
load_rules() {
local scope="$1"
local rules_file=""

case "$scope" in
global)
rules_file="$GLOBAL_RULES"
;;
workspace)
rules_file="$WORKSPACE_RULES"
;;
esac

if [[ ! -f "$rules_file" ]]; then
return 1
fi

cat "$rules_file"
}

# 规则匹配
match_rule() {
local command="$1"
local tool="$2"
local agent="$3"
local scope="$4"

local rules=$(load_rules "$scope")

if [[ -z "$rules" ]]; then
return 1
fi

# 解析 YAML 规则 (简化处理)
echo "$rules" | grep -A5 "pattern:" | while read -r line; do
if [[ "$line" == *"pattern:"* ]]; then
local pattern=$(echo "$line" | sed 's/.*pattern: *//' | tr -d '"')

if echo "$command" | grep -qiE "$pattern"; then
# 找到匹配规则,获取 action
local action=$(echo "$rules" | grep -A10 "$pattern" | grep "action:" | head -1 | sed 's/.*action: *//')
local conditions=$(echo "$rules" | grep -A10 "$pattern" | grep "conditions:" | sed 's/.*conditions: *//')

# 检查条件
if [[ -n "$conditions" ]]; then
if [[ "$conditions" == *"agent: $agent"* ]] && [[ -n "$agent" ]]; then
echo "$action|rule|$scope"
return 0
fi
else
echo "$action|rule|$scope"
return 0
fi
fi
fi
done

return 1
}

# AI 风险评估
ai_risk_assessment() {
local command="$1"
local tool="$2"

if [[ "$SKIP_AI" == true ]]; then
echo "ask|ai|disabled"
return 0
fi

# 调用 AI 分类器 (简化实现)
# 实际应该调用 LLM API

# 危险命令模式
local dangerous_patterns=(
"rm\s+(-[rf]+\s+)*/"
"dd\s+.*"
"mkfs\."
"curl\s+.*\|\s*(ba)?sh"
"eval\s+.*\$\(.*\)"
)

for pattern in "${dangerous_patterns[@]}"; do
if echo "$command" | grep -qiE "$pattern"; then
echo "deny|ai|危险命令模式匹配"
return 0
fi
done

# 中等风险命令
local medium_patterns=(
"chmod\s+.*"
"git\s+push"
"docker\s+rm"
)

for pattern in "${medium_patterns[@]}"; do
if echo "$command" | grep -qiE "$pattern"; then
echo "ask|ai|中等风险命令"
return 0
fi
done

# 低风险命令
echo "allow|ai|低风险命令"
return 0
}

# 用户确认
request_approval() {
local tool="$1"
local command="$2"
local reason="$3"
local source="$4"

echo ""
echo "⚠️ 权限审批"
echo "─────────────────────────────────────"
echo "工具:$tool"
echo "命令:$command"
echo "原因:$reason"
echo "来源:$source"
echo ""
echo "[y] 允许 [n] 拒绝 [a] 允许并记住 (工作区) [A] 允许并记住 (全局)"
read -p "请选择: " -n 1 -r
echo ""

case $REPLY in
y|Y)
echo "allow|user|用户确认"
;;
n|N)
echo "deny|user|用户拒绝"
;;
a|A)
# 添加到工作区规则
echo "$command|allow|workspace" >> "$WORKSPACE_RULES.added"
echo "allow|user|用户确认并记住 (工作区)"
;;
A)
# 添加到全局规则
echo "$command|allow|global" >> "$GLOBAL_RULES.added"
echo "allow|user|用户确认并记住 (全局)"
;;
*)
echo "deny|user|用户未选择"
;;
esac
}

# 权限决策
make_decision() {
local tool="$1"
local command="$2"
local agent="$3"

echo "进行权限检查..."

# 1. 全局规则匹配
local global_result=$(match_rule "$command" "$tool" "$agent" "global" || echo "")
if [[ -n "$global_result" ]]; then
local action=$(echo "$global_result" | cut -d'|' -f1)
if [[ "$action" != "ask" ]]; then
log_decision "$tool" "$command" "$action" "全局规则匹配" "global_rule"
echo "$global_result"
return 0
fi
fi

# 2. 工作区规则匹配
local workspace_result=$(match_rule "$command" "$tool" "$agent" "workspace" || echo "")
if [[ -n "$workspace_result" ]]; then
local action=$(echo "$workspace_result" | cut -d'|' -f1)
if [[ "$action" != "ask" ]]; then
log_decision "$tool" "$command" "$action" "工作区规则匹配" "workspace_rule"
echo "$workspace_result"
return 0
fi
fi

# 3. AI 风险评估
local ai_result=$(ai_risk_assessment "$command" "$tool")
local ai_action=$(echo "$ai_result" | cut -d'|' -f1)

if [[ "$ai_action" != "ask" ]]; then
log_decision "$tool" "$command" "$ai_action" "AI 风险评估" "ai_classifier"
echo "$ai_result"
return 0
fi

# 4. 用户确认
local user_result=$(request_approval "$tool" "$command" "需要用户确认" "user_confirmation")
log_decision "$tool" "$command" "$(echo $user_result | cut -d'|' -f1)" "用户确认" "user"
echo "$user_result"
}

# 主函数
main() {
if [[ -z "$TOOL" ]] || [[ -z "$COMMAND" ]]; then
echo "Error: --tool and --command are required"
exit 1
fi

# 设置默认值
CWD="${CWD:-$PWD}"
AGENT="${AGENT:-default}"

# 进行权限决策
local decision=$(make_decision "$TOOL" "$COMMAND" "$AGENT")
local action=$(echo "$decision" | cut -d'|' -f1)
local source=$(echo "$decision" | cut -d'|' -f3)

echo ""
echo "权限决策结果:"
echo " 决策:$action"
echo " 来源:$source"

case "$action" in
allow)
echo ""
echo "✅ 操作已允许"
exit 0
;;
deny)
echo ""
echo "❌ 操作被拒绝"
exit 1
;;
ask)
echo ""
echo "⚠️ 需要用户确认"
exit 2
;;
esac
}

main "$@"

文件: scripts/rule-management.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/bin/bash
# 规则管理脚本

set -e

ACTION=""
PATTERN=""
SCOPE="workspace"
RULE_ID=""

while [[ $# -gt 0 ]]; do
case $1 in
add)
ACTION="add"
shift
;;
list)
ACTION="list"
shift
;;
delete)
ACTION="delete"
shift
;;
--pattern)
PATTERN="$2"
shift 2
;;
--action)
RULE_ACTION="$2"
shift 2
;;
--scope)
SCOPE="$2"
shift 2
;;
--id)
RULE_ID="$2"
shift 2
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done

GLOBAL_RULES="$HOME/.openclaw/config/permissions/global-rules.yaml"
WORKSPACE_RULES="./.openclaw/permissions.yaml"

# 添加规则
add_rule() {
local pattern="$1"
local action="$2"
local scope="$3"

local rules_file=""
case "$scope" in
global)
rules_file="$GLOBAL_RULES"
;;
workspace)
rules_file="$WORKSPACE_RULES"
;;
esac

# 生成规则 ID
local rule_id="rule_$(date +%Y%m%d_%H%M%S)_$$"

# 添加规则
cat >> "$rules_file" << EOF

- id: $rule_id
pattern: "$pattern"
action: $action
created_at: $(date -Iseconds)
EOF

echo "规则已添加:"
echo " ID: $rule_id"
echo " 模式:$pattern"
echo " 动作:$action"
echo " 范围:$scope"
}

# 列出规则
list_rules() {
local scope="$1"

local rules_file=""
case "$scope" in
global)
rules_file="$GLOBAL_RULES"
;;
workspace)
rules_file="$WORKSPACE_RULES"
;;
esac

if [[ ! -f "$rules_file" ]]; then
echo "没有规则"
return 0
fi

echo "权限规则 ($scope):"
echo "─────────────────────────────────────"
cat "$rules_file"
}

# 删除规则
delete_rule() {
local rule_id="$1"
local scope="$2"

local rules_file=""
case "$scope" in
global)
rules_file="$GLOBAL_RULES"
;;
workspace)
rules_file="$WORKSPACE_RULES"
;;
esac

if [[ ! -f "$rules_file" ]]; then
echo "没有规则文件"
return 1
fi

# 删除规则 (简化处理)
local temp_file="$rules_file.tmp"
grep -v "id: $rule_id" "$rules_file" > "$temp_file"
mv "$temp_file" "$rules_file"

echo "规则已删除:$rule_id"
}

# 主函数
main() {
case "$ACTION" in
add)
if [[ -z "$PATTERN" ]] || [[ -z "$RULE_ACTION" ]]; then
echo "Error: --pattern and --action are required"
exit 1
fi
add_rule "$PATTERN" "$RULE_ACTION" "$SCOPE"
;;
list)
list_rules "$SCOPE"
;;
delete)
if [[ -z "$RULE_ID" ]]; then
echo "Error: --id is required"
exit 1
fi
delete_rule "$RULE_ID" "$SCOPE"
;;
*)
echo "Usage: rule-management <add|list|delete> [options]"
exit 1
;;
esac
}

main "$@"

文件: scripts/permission-audit.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/bin/bash
# 权限审计脚本

set -e

LIMIT=50
FORMAT="table"
FILTER=""

AUDIT_LOG="$HOME/.openclaw/logs/permission-audit.log"

# 显示审计日志
show_audit() {
if [[ ! -f "$AUDIT_LOG" ]]; then
echo "没有审计日志"
return 0
fi

local logs=$(cat "$AUDIT_LOG")

# 过滤
if [[ -n "$FILTER" ]]; then
logs=$(echo "$logs" | grep -i "$FILTER")
fi

# 显示
case "$FORMAT" in
"table")
printf "%-25s %-8s %-10s %-15s %s\n" "时间" "工具" "决策" "来源" "命令"
echo "────────────────────────────────────────────────────────────────────────"

echo "$logs" | tail -n "$LIMIT" | while IFS='|' read -r timestamp tool command decision reason source; do
printf "%-25s %-8s %-10s %-15s %s\n" \
"$(echo $timestamp | cut -d+ -f1)" \
"$tool" \
"$decision" \
"$source" \
"$(echo $command | cut -c1-40)"
done
;;
"json")
echo "$logs" | tail -n "$LIMIT" | while IFS='|' read -r timestamp tool command decision reason source; do
echo "{\"timestamp\":\"$timestamp\",\"tool\":\"$tool\",\"command\":\"$command\",\"decision\":\"$decision\",\"reason\":\"$reason\",\"source\":\"$source\"}"
done | jq -s '.'
;;
esac
}

# 显示统计
show_stats() {
if [[ ! -f "$AUDIT_LOG" ]]; then
return 0
fi

local total=$(wc -l < "$AUDIT_LOG")
local allow=$(grep -c "|allow|" "$AUDIT_LOG" || echo 0)
local deny=$(grep -c "|deny|" "$AUDIT_LOG" || echo 0)

# 按来源统计
local rule_count=$(grep -c "|rule|" "$AUDIT_LOG" || echo 0)
local ai_count=$(grep -c "|ai|" "$AUDIT_LOG" || echo 0)
local user_count=$(grep -c "|user|" "$AUDIT_LOG" || echo 0)

echo ""
echo "统计:"
echo " 总决策数:$total"
echo " 允许:$allow"
echo " 拒绝:$deny"

if [[ $total -gt 0 ]]; then
local allow_rate=$((allow * 100 / total))
echo " 允许率:$allow_rate%"
fi

echo ""
echo "决策来源:"
echo " 规则匹配:$rule_count"
echo " AI 分类器:$ai_count"
echo " 用户确认:$user_count"
}

# 主函数
main() {
while [[ $# -gt 0 ]]; do
case $1 in
--limit)
LIMIT="$2"
shift 2
;;
--format)
FORMAT="$2"
shift 2
;;
--filter)
FILTER="$2"
shift 2
;;
*)
shift
;;
esac
done

show_audit
show_stats
}

main "$@"

步骤 4:配置文件

文件: config/global-rules.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 全局权限规则

rules:
# 绝对禁止的规则
- id: deny-rm-root
pattern: "rm\\s+(-[rf]+\\s+)*/"
action: deny
reason: "禁止删除根目录文件"

- id: deny-dd
pattern: "dd\\s+.*"
action: deny
reason: "禁止 dd 命令"

- id: deny-curl-pipe
pattern: "(curl|wget)\\s+[^|]*\\|\\s*(ba)?sh"
action: deny
reason: "禁止下载执行远程脚本"

# 允许的规则
- id: allow-ls
pattern: "ls\\s+.*"
action: allow

- id: allow-cat
pattern: "cat\\s+.*"
action: allow

- id: allow-grep
pattern: "grep\\s+.*"
action: allow

步骤 5:编写测试用例

文件: tests/test.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/bin/bash
# 权限系统水晶包测试

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEST_PASSED=0
TEST_FAILED=0

# 测试:危险命令拒绝
test_dangerous_command_deny() {
echo "Test: Dangerous command deny..."

local output=$(bash "$SCRIPT_DIR/../scripts/permission-check.sh" \
--tool bash \
--command "rm -rf /" 2>&1 || true)

if echo "$output" | grep -q "操作被拒绝"; then
echo "✅ PASS"
((TEST_PASSED++))
else
echo "❌ FAIL"
((TEST_FAILED++))
fi
}

# 测试:安全命令允许
test_safe_command_allow() {
echo "Test: Safe command allow..."

local output=$(bash "$SCRIPT_DIR/../scripts/permission-check.sh" \
--tool bash \
--command "ls -la" 2>&1)

if echo "$output" | grep -q "操作已允许"; then
echo "✅ PASS"
((TEST_PASSED++))
else
echo "❌ FAIL"
((TEST_FAILED++))
fi
}

# 测试:规则添加
test_rule_add() {
echo "Test: Rule add..."

local output=$(bash "$SCRIPT_DIR/../scripts/rule-management.sh" \
add \
--pattern "test-command" \
--action allow \
--scope workspace)

if echo "$output" | grep -q "规则已添加"; then
echo "✅ PASS"
((TEST_PASSED++))
else
echo "❌ FAIL"
((TEST_FAILED++))
fi
}

# 测试:规则列表
test_rule_list() {
echo "Test: Rule list..."

local output=$(bash "$SCRIPT_DIR/../scripts/rule-management.sh" list)

if echo "$output" | grep -q "权限规则"; then
echo "✅ PASS"
((TEST_PASSED++))
else
echo "❌ FAIL"
((TEST_FAILED++))
fi
}

# 运行所有测试
run_tests() {
echo "=================================="
echo "权限系统水晶包测试"
echo "=================================="
echo ""

test_dangerous_command_deny
test_safe_command_allow
test_rule_add
test_rule_list

echo ""
echo "=================================="
echo "测试结果:$TEST_PASSED 通过,$TEST_FAILED 失败"
echo "=================================="

if [[ $TEST_FAILED -gt 0 ]]; then
exit 1
fi
}

run_tests

权限管理最佳实践

实践 1:配置全局规则

1
2
3
4
5
6
7
# 编辑全局规则
vim ~/.openclaw/config/permissions/global-rules.yaml

# 添加项目特定规则
- id: allow-npm-test
pattern: "npm\\s+test.*"
action: allow

实践 2:配置工作区规则

1
2
3
4
5
6
7
8
9
# 编辑工作区规则
vim ./.openclaw/permissions.yaml

# 添加工作区特定规则
- id: allow-deploy
pattern: "npm\\s+run\\s+deploy.*"
action: allow
conditions:
agent: devops

实践 3:查看审计日志

1
2
3
4
5
6
7
8
# 查看所有决策
openclaw run permission-manager audit --limit 50

# 查看拒绝的决策
openclaw run permission-manager audit --filter "deny"

# 导出 JSON 格式
openclaw run permission-manager audit --format json --output audit.json

实践 4:生成统计报告

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 生成统计报告
openclaw run permission-manager report

# 输出:
权限决策统计报告:
─────────────────────────────────────
总决策数:200
允许:160 (80%)
拒绝:30 (15%)
需要确认:10 (5%)

决策来源:
规则匹配:140 (70%)
AI 分类器:40 (20%)
用户确认:20 (10%)

总结

核心要点

  1. 基于 Claude Code - Permission Decision Engine OpenClaw 化
  2. 多层规则 - 全局/工作区/会话三级规则
  3. AI 风险评估 - 智能判断风险级别
  4. 审批流程 - 支持记住选择
  5. 审计日志 - 完整决策记录

实战成果

成果 说明
permission-manager 水晶包 完整的权限管理能力
3 个核心命令 check / rule-management / audit
配置文件 全局规则、工作区规则
完整测试 4 个测试用例

权限决策示例

1
2
3
4
5
6
7
8
9
10
# 检查危险命令
$ openclaw run permission-manager check \
--tool bash \
--command "rm -rf /"

权限决策结果:
决策:deny
来源:ai_classifier

❌ 操作被拒绝

下一步

  • 集成 LLM AI 分类器
  • 添加审批通知
  • 实现规则导入/导出
  • 添加合规报告

系列文章:

  • [1-20] Claude Code 源码解析 (已完成)
  • [21] 水晶包开发完整指南 (已完成)
  • [22] 任务管理水晶包开发 (已完成)
  • [23] Bash 安全水晶包开发 (已完成)
  • [24] 权限系统水晶包开发 (本文)
  • [25+] 更多实战案例 (继续中…)

关于作者: John,OpenClaw 平台开发者,专注 AI 助手架构设计与实现。