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

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

闸门 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"Blocked: '{pattern}' is on the deny list"
return None
闸门 2负责规则匹配,用来描述"什么时候需要问用户"。每条规则指定工具和检查条件。
import re
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": "Access outside workspace",
},
{
"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": "Potentially destructive command",
},
]
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
闸门 3:规则命中后,暂停等用户输入。
def ask_user(tool_name: str, args: dict, reason: str) –> str:
print(f"\\n⚠ {reason}")
print(f" Tool: {tool_name}({args})")
choice = input(" Allow? [y/N] ").strip().lower()
return "allow" if choice in ("y", "yes") else "deny"
三道闸门串在一起,插在工具执行之前:
def check_permission(block) –> bool:
# 闸门 1: 硬拒绝
if block.name == "bash":
reason = check_deny_list(block.input.get("command", ""))
if reason:
print(f"\\n⛔ {reason}")
return False
# 闸门 2 + 3: 规则匹配 → 用户审批
reason = check_rules(block.name, block.input)
if reason:
decision = ask_user(block.name, block.input, reason)
if decision == "deny":
return False
return True
# 在 agent_loop 中——s02 的循环只加了一行:
for block in tool_calls:
if not check_permission(block): # ← 新增
results.append({... "content": "Permission denied."})
continue
output = TOOL_HANDLERS[block.name](**block.input) # s02 原有
results.append(...)
相对 s02 的变更
| 安全模型 | 无(信任模型) | 三道闸门权限管线 |
| 新函数 | — | check_deny_list, check_rules, ask_user, check_permission |
| 循环 | 直接执行所有工具 | 执行前插入 check_permission() |
试一下
cd learn-claude-code
python s03_permission/code.py
试试这些 prompt:
观察重点:哪些操作直接通过?哪些需要你确认?哪些被直接拒绝?
源码地址:https://github.com/shareAI-lab/learn-claude-code
蓝奏云地址:https://wwbfs.lanzouv.com/iva494dg0h4f
密码:cc39
辛辛苦苦写完,不知道csdn抽什么风,保存草稿没成功,就这张就重新发原文了
网硕互联帮助中心


评论前必须登录!
注册