s03: Permission --- 执行前做权限判断
问题
s02 的 Agent 有 5 个工具。file tools 受 safe_path 保护,但 bash 不受限制。让它"清理一下项目",可能执行 rm -rf /。
安全边界由代码负责,判断发生在工具执行之前。
解决方案:工具执行前加一道门

工具执行前插入 check_permission()。每个工具调用依次经过三道闸门:硬拒绝优先,软询问次之,都没命中就放行。
三道闸门对应三种决策:
| 闸门 | 作用 | 命中后 |
|---|---|---|
| 1. 拒绝列表 | 永远禁止的操作(rm -rf /、sudo) |
直接拒绝,不执行 |
| 2. 规则匹配 | 取决于上下文的操作(读/写工作区外、rm 文件) |
交给闸门 3 |
| 3. 用户审批 | 闸门 2 命中后,暂停等用户确认 | 用户决定允许或拒绝 |
三道都没命中 → 直接执行。大部分日常操作走这条路。
工作原理

工具执行前加三道闸门
第一道闸门:硬拒绝
python
# 关卡 1:硬性拒绝列表 - 始终禁止
DENY_LIST = ["rm -rf /", "sudo", "shutdown", "reboot", "mkfs", "dd if=", "> /dev/sda"]
def check_deny_list(command: str) -> str | None:
for pattern in DENY_LIST:
if pattern in command:
return f"已阻止:'{pattern}' 在拒绝列表中"
return None
第二道闸门:规则匹配
python
# 关卡 2:规则匹配 - 上下文相关检查
# 检测 shell 命令中是否包含 rm 或 del 这类破坏性删除命令
DESTRUCTIVE_COMMAND_WORD = re.compile(
r"(?i)(?:^|[;&|()\n])\s*(?:rm|del)(?=\s|$|[;&|()])"
)
def contains_destructive_command(command: str) -> bool:
return bool(DESTRUCTIVE_COMMAND_WORD.search(command))
PERMISSION_RULES = [
{"tools": ["read_file", "write_file", "edit_file"],
"check": lambda args: not (WORKDIR / args.get("path", "")).resolve().is_relative_to(WORKDIR),
"message": "写入工作区外"},
{"tools": ["bash"],
"check": lambda args: contains_destructive_command(args.get("command", "")) or
any(kw in args.get("command", "") for kw in ["rm ", "> /etc/", "chmod 777"]),
"message": "潜在破坏性命令"},
]
def check_rules(tool_name: str, args: dict) -> str | None:
for rule in PERMISSION_RULES:
if tool_name in rule["tools"] and rule["check"](args):
return rule["message"]
return None
第三道闸门:用户审批
python
# 关卡 3:用户审批 - 规则匹配后等待确认
def ask_user(tool_name: str, args: dict, reason: str) -> str:
print(f"\n\033[33m[权限] {reason}\033[0m")
print(f" 工具:{tool_name}({args})")
choice = input(" 允许?[y/N] ").strip().lower()
return "允许" if choice in ("y", "yes") else "拒绝"
权限流水线
python
# 流水线:三道关卡串联
def check_permission(block) -> bool:
if block.name == "bash":
reason = check_deny_list(block.input.get("command", ""))
if reason:
print(f"\n\033[31m[已阻止] {reason}\033[0m")
return False
reason = check_rules(block.name, block.input)
if reason:
decision = ask_user(block.name, block.input, reason)
if decision == "拒绝":
return False
return True
Agent 循环新增权限校验层
在工具执行前,插入权限校验
python
def agent_loop(messages: list):
while True:
response = client.messages.create(
model=MODEL, system=SYSTEM, messages=messages,
tools=TOOLS, max_tokens=8000,
)
messages.append({"role": "assistant", "content": response.content})
tool_calls = [
block for block in response.content if block.type == "tool_use"
]
if not tool_calls:
return
results = []
for block in tool_calls:
print(f"\033[36m> {block.name}\033[0m")
# s03 变更:执行前先经过权限流水线
if not check_permission(block):
results.append({"type": "tool_result", "tool_use_id": block.id,
"content": "权限被拒绝。"})
continue
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input) if handler else f"未知:{block.name}"
print(str(output)[:200])
results.append({"type": "tool_result", "tool_use_id": block.id, "content": output})
messages.append({"role": "user", "content": results})
每步输出打印
用户输入内容:删除hello.py
text
s03:权限系统
输入问题,按回车发送。输入 q 退出。
s03 >> 删除hello.py
第一轮工具调用
text
工具执行block:
ToolUseBlock(
id='call_fa61b3a4b8234aa780241380',
caller=None,
input={
'command': 'del "H:\\AI\\Agent\\Coding Agent\\learn-claude-code\\s03_permission\\hello.py"'
},
name='bash',
type='tool_use',
toolset_name=None
)
执行命令
text
> bash
执行校验,命中第二道闸门,匹配到规则,执行第三道闸门,用户审批。用户审批通过。
text
[权限] 潜在破坏性命令
工具:
bash(
command='del "H:\\AI\\Agent\\Coding Agent\\learn-claude-code\\s03_permission\\hello.py"'
)
允许?[y/N] y
第一轮工具调用结果
text
工具执行输出 output: 找不到 H:\AI\Agent\Coding Agent\learn-claude-code\s03_permission\hello.py
第二轮工具调用
text
工具执行block:
ToolUseBlock(
id='call_64ac39a992174147ae148405',
caller=None,
input={
'command': 'dir "H:\\AI\\Agent\\Coding Agent\\learn-claude-code\\s03_permission"'
},
name='bash',
type='tool_use',
toolset_name=None
)
执行shell命令
text
> bash
第二轮工具调用结果
text
工具执行输出 output: 驱动器 H 中的卷是 新加卷
卷的序列号是 4EB5-DF96
H:\AI\Agent\Coding Agent\learn-claude-code\s03_permission 的目录
2026/10/17 21:26 <DIR> .
2026/10/17 21:26 <DIR> ..
2026/10/17 21:26
最终输出
text
当前目录下没有 `hello.py` 文件。目录中存在的 Python 文件有:
- code-zh.py
- code.py
- test.py
请问您是要删除其中一个文件吗?如果是,请告诉我具体是哪一个。