第12章 权限系统 —— Deny→ask→allow的安全边界

上一篇我们剖析了工具系统的分发机制。本章我们看权限系统——保护安全的三级边界。

权限系统是什么

一句话定义:安全边界和审批流程——控制哪些操作可以自动执行,哪些需要用户确认。

Permissions = 安全边界系统 定位:Harness 的管理层核心,保护用户环境

图表 代码
graph LR
    A[工具调用请求] --> B{权限检查}
    B -->|deny| C[❌ 禁止执行
返回错误] B -->|ask| D[⚠️ 请求审批
等待用户确认] B -->|allow| E[✅ 自动执行
返回结果]
graph LR
    A[工具调用请求] --> B{权限检查}
    B -->|deny| C[❌ 禁止执行
返回错误] B -->|ask| D[⚠️ 请求审批
等待用户确认] B -->|allow| E[✅ 自动执行
返回结果]
graph LR
    A[工具调用请求] --> B{权限检查}
    B -->|deny| C[❌ 禁止执行
返回错误] B -->|ask| D[⚠️ 请求审批
等待用户确认] B -->|allow| E[✅ 自动执行
返回结果]
graph LR
    A[工具调用请求] --> B{权限检查}
    B -->|deny| C[❌ 禁止执行<br/>返回错误]
    B -->|ask| D[⚠️ 请求审批<br/>等待用户确认]
    B -->|allow| E[✅ 自动执行<br/>返回结果]

核心机制:

  • deny:禁止执行,返回错误
  • ask:请求审批,等待用户确认
  • allow:自动执行,无需用户干预

权限三级模式

三级对比

模式行为适用场景示例
deny❌ 禁止执行危险操作删除系统文件、访问密钥
ask⚠️ 请求审批中等风险git push、npm install、rm -rf
allow✅ 自动执行安全操作Read、Glob、Grep
图表 代码
graph TB
    subgraph Security["安全分级"]
        S1[deny
危险操作
禁止] S2[ask
中等风险
审批] S3[allow
安全操作
自动] end S1 --> S2 --> S3
graph TB
    subgraph Security["安全分级"]
        S1[deny
危险操作
禁止] S2[ask
中等风险
审批] S3[allow
安全操作
自动] end S1 --> S2 --> S3
graph TB
    subgraph Security["安全分级"]
        S1[deny
危险操作
禁止] S2[ask
中等风险
审批] S3[allow
安全操作
自动] end S1 --> S2 --> S3
graph TB
    subgraph Security["安全分级"]
        S1[deny<br/>危险操作<br/>禁止]
        S2[ask<br/>中等风险<br/>审批]
        S3[allow<br/>安全操作<br/>自动]
    end
    
    S1 --> S2 --> S3

deny —— 禁止执行

触发场景:

  • 删除系统关键文件(/bin、/usr、/etc)
  • 访问敏感文件(.env、credentials.json)
  • 执行危险命令(rm -rf /、sudo)
  • 访问私有密钥(SSH keys、API keys)

规则示例:

{
  "permissions": {
    "deny": [
      {
        "tool": "Bash",
        "command": "rm -rf /",
        "reason": "禁止删除根目录"
      },
      {
        "tool": "Read",
        "file_path": ".env",
        "reason": "禁止访问环境变量文件"
      },
      {
        "tool": "Read",
        "file_path": "*credentials.json",
        "reason": "禁止访问凭证文件"
      }
    ]
  }
}

ask —— 请求审批

触发场景:

  • Git 操作(git push、git commit)
  • 安装依赖(npm install、pip install)
  • 删除文件(rm -rf、unlink)
  • 网络请求(WebFetch 到敏感 URL)

规则示例:

{
  "permissions": {
    "ask": [
      {
        "tool": "Bash",
        "command": "git push",
        "reason": "推送代码需要确认"
      },
      {
        "tool": "Bash",
        "command": "npm install",
        "reason": "安装依赖可能影响环境"
      },
      {
        "tool": "Bash",
        "command": "rm -rf",
        "reason": "删除文件需要确认"
      }
    ]
  }
}

审批流程:

图表 代码
graph LR
    A[工具调用
ask 规则匹配] --> B[暂停执行] B --> C[显示审批界面] C --> D{用户响应} D -->|批准| E[执行工具] D -->|拒绝| F[返回拒绝信息] E --> G[继续 Loop] F --> H[Model 收到拒绝信息]
graph LR
    A[工具调用
ask 规则匹配] --> B[暂停执行] B --> C[显示审批界面] C --> D{用户响应} D -->|批准| E[执行工具] D -->|拒绝| F[返回拒绝信息] E --> G[继续 Loop] F --> H[Model 收到拒绝信息]
graph LR
    A[工具调用
ask 规则匹配] --> B[暂停执行] B --> C[显示审批界面] C --> D{用户响应} D -->|批准| E[执行工具] D -->|拒绝| F[返回拒绝信息] E --> G[继续 Loop] F --> H[Model 收到拒绝信息]
graph LR
    A[工具调用<br/>ask 规则匹配] --> B[暂停执行]
    B --> C[显示审批界面]
    C --> D{用户响应}
    D -->|批准| E[执行工具]
    D -->|拒绝| F[返回拒绝信息]
    
    E --> G[继续 Loop]
    F --> H[Model 收到拒绝信息]

allow —— 自动执行

触发场景:

  • 文件读取(Read)
  • 文件搜索(Glob、Grep)
  • 网络搜索(WebSearch)
  • 页面浏览(Browser_snapshot)

规则示例:

{
  "permissions": {
    "allow": [
      {
        "tool": "Read",
        "reason": "读取文件安全"
      },
      {
        "tool": "Glob",
        "reason": "搜索文件路径安全"
      },
      {
        "tool": "Grep",
        "reason": "搜索文件内容安全"
      },
      {
        "tool": "WebSearch",
        "reason": "网络搜索安全"
      }
    ]
  }
}

权限规则设计

规则匹配机制

匹配优先级:

图表 代码
graph LR
    A[工具调用] --> B{匹配 deny 规则}
    B -->|匹配| C[deny
禁止执行] B -->|不匹配| D{匹配 ask 规则} D -->|匹配| E[ask
请求审批] D -->|不匹配| F{匹配 allow 规则} F -->|匹配| G[allow
自动执行] F -->|不匹配| H[默认 ask
请求审批]
graph LR
    A[工具调用] --> B{匹配 deny 规则}
    B -->|匹配| C[deny
禁止执行] B -->|不匹配| D{匹配 ask 规则} D -->|匹配| E[ask
请求审批] D -->|不匹配| F{匹配 allow 规则} F -->|匹配| G[allow
自动执行] F -->|不匹配| H[默认 ask
请求审批]
graph LR
    A[工具调用] --> B{匹配 deny 规则}
    B -->|匹配| C[deny
禁止执行] B -->|不匹配| D{匹配 ask 规则} D -->|匹配| E[ask
请求审批] D -->|不匹配| F{匹配 allow 规则} F -->|匹配| G[allow
自动执行] F -->|不匹配| H[默认 ask
请求审批]
graph LR
    A[工具调用] --> B{匹配 deny 规则}
    B -->|匹配| C[deny<br/>禁止执行]
    B -->|不匹配| D{匹配 ask 规则}
    D -->|匹配| E[ask<br/>请求审批]
    D -->|不匹配| F{匹配 allow 规则}
    F -->|匹配| G[allow<br/>自动执行]
    F -->|不匹配| H[默认 ask<br/>请求审批]

匹配规则:

匹配维度说明示例
工具名称匹配 tool_name"tool": "Bash"
命令匹配匹配命令前缀"command": "git push"
文件路径匹配匹配文件路径模式"file_path": "*.env"
参数匹配匹配参数值"url": "https://sensitive.com"

匹配顺序:

  1. deny 规则优先(最严格)
  2. ask 规则其次(中等)
  3. allow 规则最后(最宽松)
  4. 无匹配时默认 ask(保守策略)

规则配置文件

JSON 配置示例:

{
  "permissions": {
    "deny": [
      {"tool": "Bash", "command": "rm -rf /"},
      {"tool": "Read", "file_path": ".env"},
      {"tool": "Read", "file_path": "*credentials*"}
    ],
    "ask": [
      {"tool": "Bash", "command": "git push"},
      {"tool": "Bash", "command": "npm install"},
      {"tool": "Bash", "command": "rm -rf"}
    ],
    "allow": [
      {"tool": "Read"},
      {"tool": "Glob"},
      {"tool": "Grep"},
      {"tool": "WebSearch"}
    ]
  }
}

规则模式匹配

通配符支持:

模式说明示例
*匹配任意字符"file_path": "*.env" 匹配所有 .env 文件
**匹配任意路径"file_path": "**/*.json" 匹配所有 JSON 文件
?匹配单个字符"command": "git ?" 匹配 git add, git commit 等
``或匹配

正则匹配:

{
  "permissions": {
    "deny": [
      {
        "tool": "Bash",
        "command": "^rm -rf.*",  // 正则:匹配所有 rm -rf
        "reason": "禁止所有删除操作"
      }
    ]
  }
}

权限检查流程

完整流程

图表 代码
sequenceDiagram
    participant Loop as Agent Loop
    participant PermCheck as 权限检查器
    participant Rules as 规则配置
    participant User as 用户审批界面
    participant ToolExec as 工具执行器
    
    Loop->>PermCheck: 工具调用请求
    
    PermCheck->>Rules: 检查 deny 规则
    Rules-->>PermCheck: deny 规则匹配?
    
    alt deny 匹配
        PermCheck-->>Loop: deny,返回错误
    else deny 不匹配
        PermCheck->>Rules: 检查 ask 规则
        Rules-->>PermCheck: ask 规则匹配?
        
        alt ask 匹配
            PermCheck->>User: 显示审批界面
            User-->>PermCheck: 用户确认
            
            alt 用户批准
                PermCheck->>ToolExec: 执行工具
                ToolExec-->>PermCheck: 返回结果
                PermCheck-->>Loop: 返回工具输出
            else 用户拒绝
                PermCheck-->>Loop: 返回拒绝信息
            end
        else ask 不匹配
            PermCheck->>Rules: 检查 allow 规则
            Rules-->>PermCheck: allow 规则匹配?
            
            alt allow 匹配
                PermCheck->>ToolExec: 执行工具
                ToolExec-->>PermCheck: 返回结果
                PermCheck-->>Loop: 返回工具输出
            else 无匹配
                PermCheck->>User: 默认 ask
                User-->>PermCheck: 用户确认
                PermCheck-->>Loop: 返回结果
            end
        end
    end
sequenceDiagram
    participant Loop as Agent Loop
    participant PermCheck as 权限检查器
    participant Rules as 规则配置
    participant User as 用户审批界面
    participant ToolExec as 工具执行器
    
    Loop->>PermCheck: 工具调用请求
    
    PermCheck->>Rules: 检查 deny 规则
    Rules-->>PermCheck: deny 规则匹配?
    
    alt deny 匹配
        PermCheck-->>Loop: deny,返回错误
    else deny 不匹配
        PermCheck->>Rules: 检查 ask 规则
        Rules-->>PermCheck: ask 规则匹配?
        
        alt ask 匹配
            PermCheck->>User: 显示审批界面
            User-->>PermCheck: 用户确认
            
            alt 用户批准
                PermCheck->>ToolExec: 执行工具
                ToolExec-->>PermCheck: 返回结果
                PermCheck-->>Loop: 返回工具输出
            else 用户拒绝
                PermCheck-->>Loop: 返回拒绝信息
            end
        else ask 不匹配
            PermCheck->>Rules: 检查 allow 规则
            Rules-->>PermCheck: allow 规则匹配?
            
            alt allow 匹配
                PermCheck->>ToolExec: 执行工具
                ToolExec-->>PermCheck: 返回结果
                PermCheck-->>Loop: 返回工具输出
            else 无匹配
                PermCheck->>User: 默认 ask
                User-->>PermCheck: 用户确认
                PermCheck-->>Loop: 返回结果
            end
        end
    end
sequenceDiagram
    participant Loop as Agent Loop
    participant PermCheck as 权限检查器
    participant Rules as 规则配置
    participant User as 用户审批界面
    participant ToolExec as 工具执行器
    
    Loop->>PermCheck: 工具调用请求
    
    PermCheck->>Rules: 检查 deny 规则
    Rules-->>PermCheck: deny 规则匹配?
    
    alt deny 匹配
        PermCheck-->>Loop: deny,返回错误
    else deny 不匹配
        PermCheck->>Rules: 检查 ask 规则
        Rules-->>PermCheck: ask 规则匹配?
        
        alt ask 匹配
            PermCheck->>User: 显示审批界面
            User-->>PermCheck: 用户确认
            
            alt 用户批准
                PermCheck->>ToolExec: 执行工具
                ToolExec-->>PermCheck: 返回结果
                PermCheck-->>Loop: 返回工具输出
            else 用户拒绝
                PermCheck-->>Loop: 返回拒绝信息
            end
        else ask 不匹配
            PermCheck->>Rules: 检查 allow 规则
            Rules-->>PermCheck: allow 规则匹配?
            
            alt allow 匹配
                PermCheck->>ToolExec: 执行工具
                ToolExec-->>PermCheck: 返回结果
                PermCheck-->>Loop: 返回工具输出
            else 无匹配
                PermCheck->>User: 默认 ask
                User-->>PermCheck: 用户确认
                PermCheck-->>Loop: 返回结果
            end
        end
    end
sequenceDiagram
    participant Loop as Agent Loop
    participant PermCheck as 权限检查器
    participant Rules as 规则配置
    participant User as 用户审批界面
    participant ToolExec as 工具执行器
    
    Loop->>PermCheck: 工具调用请求
    
    PermCheck->>Rules: 检查 deny 规则
    Rules-->>PermCheck: deny 规则匹配?
    
    alt deny 匹配
        PermCheck-->>Loop: deny,返回错误
    else deny 不匹配
        PermCheck->>Rules: 检查 ask 规则
        Rules-->>PermCheck: ask 规则匹配?
        
        alt ask 匹配
            PermCheck->>User: 显示审批界面
            User-->>PermCheck: 用户确认
            
            alt 用户批准
                PermCheck->>ToolExec: 执行工具
                ToolExec-->>PermCheck: 返回结果
                PermCheck-->>Loop: 返回工具输出
            else 用户拒绝
                PermCheck-->>Loop: 返回拒绝信息
            end
        else ask 不匹配
            PermCheck->>Rules: 检查 allow 规则
            Rules-->>PermCheck: allow 规则匹配?
            
            alt allow 匹配
                PermCheck->>ToolExec: 执行工具
                ToolExec-->>PermCheck: 返回结果
                PermCheck-->>Loop: 返回工具输出
            else 无匹配
                PermCheck->>User: 默认 ask
                User-->>PermCheck: 用户确认
                PermCheck-->>Loop: 返回结果
            end
        end
    end

权限检查实现

# 权限检查实现
def check_permission(tool_name, tool_args, rules):
    # 1. 检查 deny 规则
    for rule in rules["deny"]:
        if match_rule(tool_name, tool_args, rule):
            return "deny", rule["reason"]
    
    # 2. 检查 ask 规则
    for rule in rules["ask"]:
        if match_rule(tool_name, tool_args, rule):
            return "ask", rule["reason"]
    
    # 3. 检查 allow 规则
    for rule in rules["allow"]:
        if match_rule(tool_name, tool_args, rule):
            return "allow", None
    
    # 4. 无匹配时默认 ask(保守策略)
    return "ask", "默认需要审批"

# 规则匹配
def match_rule(tool_name, tool_args, rule):
    # 工具名称匹配
    if rule.get("tool") and rule["tool"] != tool_name:
        return False
    
    # 命令匹配
    if rule.get("command"):
        command = tool_args.get("command", "")
        if not pattern_match(command, rule["command"]):
            return False
    
    # 文件路径匹配
    if rule.get("file_path"):
        file_path = tool_args.get("file_path", "")
        if not pattern_match(file_path, rule["file_path"]):
            return False
    
    return True

用户审批界面

审批提示格式

⚠️ 权限审批请求

工具: Bash
命令: git push origin main
原因: 推送代码需要确认

是否批准执行?
[批准] [拒绝] [查看详情]

审批选项

选项行为后果
批准执行工具工具执行,返回结果
拒绝拒绝执行返回拒绝信息,Model 调整策略
查看详情显示详细信息查看工具参数、风险评估

批量审批

问题:连续多个 ask 工具调用,频繁打断用户。

解决方案:批量审批

图表 代码
graph LR
    A[连续 ask 工具调用] --> B[暂停执行]
    B --> C[收集所有请求]
    C --> D[显示批量审批界面]
    D --> E{用户响应}
    E -->|全部批准| F[执行所有工具]
    E -->|逐个审批| G[逐个确认]
graph LR
    A[连续 ask 工具调用] --> B[暂停执行]
    B --> C[收集所有请求]
    C --> D[显示批量审批界面]
    D --> E{用户响应}
    E -->|全部批准| F[执行所有工具]
    E -->|逐个审批| G[逐个确认]
graph LR
    A[连续 ask 工具调用] --> B[暂停执行]
    B --> C[收集所有请求]
    C --> D[显示批量审批界面]
    D --> E{用户响应}
    E -->|全部批准| F[执行所有工具]
    E -->|逐个审批| G[逐个确认]
graph LR
    A[连续 ask 工具调用] --> B[暂停执行]
    B --> C[收集所有请求]
    C --> D[显示批量审批界面]
    D --> E{用户响应}
    E -->|全部批准| F[执行所有工具]
    E -->|逐个审批| G[逐个确认]

批量审批界面:

⚠️ 批量权限审批请求

1. Bash: git push origin main
2. Bash: npm install
3. Write: /src/new.ts

[全部批准] [逐个审批] [全部拒绝]

权限配置级别

配置级别对比

配置级别位置影响范围优先级
全局配置~/.claude/settings.json所有项目最高
项目配置.claude/settings.json当前项目中
临时配置会话内临时设置当前会话最低
图表 代码
graph TB
    Global[全局配置
~/.claude/settings.json
所有项目] --> Project[项目配置
.claude/settings.json
当前项目] Project --> Session[临时配置
会话内设置
当前会话] Global[优先级最高] Project[优先级中] Session[优先级最低]
graph TB
    Global[全局配置
~/.claude/settings.json
所有项目] --> Project[项目配置
.claude/settings.json
当前项目] Project --> Session[临时配置
会话内设置
当前会话] Global[优先级最高] Project[优先级中] Session[优先级最低]
graph TB
    Global[全局配置
~/.claude/settings.json
所有项目] --> Project[项目配置
.claude/settings.json
当前项目] Project --> Session[临时配置
会话内设置
当前会话] Global[优先级最高] Project[优先级中] Session[优先级最低]
graph TB
    Global[全局配置<br/>~/.claude/settings.json<br/>所有项目] --> Project[项目配置<br/>.claude/settings.json<br/>当前项目]
    Project --> Session[临时配置<br/>会话内设置<br/>当前会话]
    
    Global[优先级最高]
    Project[优先级中]
    Session[优先级最低]

配置示例

全局配置:

// ~/.claude/settings.json
{
  "permissions": {
    "deny": [
      {"tool": "Bash", "command": "rm -rf /"}
    ],
    "allow": [
      {"tool": "Read"},
      {"tool": "Glob"}
    ]
  }
}

项目配置:

// .claude/settings.json
{
  "permissions": {
    "ask": [
      {"tool": "Bash", "command": "git push"}  // 项目级 ask
    ]
  }
}

权限系统的设计格言

格言

“先划边界, 再给自由” —— 先判断操作能不能做,要不要问用户

设计要点

要点说明实现方式
默认 deny未知操作默认禁止无匹配时默认 ask
最小权限只授予必要权限精确匹配规则
信任边界区分可信/不可信操作分级权限模式
透明审批审批信息清晰完整显示工具、参数、原因
图表 代码
graph TB
    subgraph Philosophy["权限设计哲学"]
        P1[默认 deny
保守策略] P2[最小权限
只授予必要] P3[信任边界
分级权限] P4[透明审批
信息清晰] end
graph TB
    subgraph Philosophy["权限设计哲学"]
        P1[默认 deny
保守策略] P2[最小权限
只授予必要] P3[信任边界
分级权限] P4[透明审批
信息清晰] end
graph TB
    subgraph Philosophy["权限设计哲学"]
        P1[默认 deny
保守策略] P2[最小权限
只授予必要] P3[信任边界
分级权限] P4[透明审批
信息清晰] end
graph TB
    subgraph Philosophy["权限设计哲学"]
        P1[默认 deny<br/>保守策略]
        P2[最小权限<br/>只授予必要]
        P3[信任边界<br/>分级权限]
        P4[透明审批<br/>信息清晰]
    end

权限系统 vs 无权限系统

对比

维度权限系统无权限系统
安全性✅ 高(危险操作需审批)❌ 低(任何操作自动执行)
用户体验⚠️ 中(需要审批确认)✅ 高(无需打断)
误操作风险✅ 低(有保护)❌ 高(无保护)
适用场景生产环境、重要项目实验、测试环境
图表 代码
graph TB
    subgraph WithPerm["有权限系统"]
        W1[安全]
        W2[误操作风险低]
        W3[需用户确认]
    end
    
    subgraph WithoutPerm["无权限系统"]
        O1[不安全]
        O2[误操作风险高]
        O3[无需打断]
    end
    
    style WithPerm fill:#E0FFE0
    style WithoutPerm fill:#FFE0E0
graph TB
    subgraph WithPerm["有权限系统"]
        W1[安全]
        W2[误操作风险低]
        W3[需用户确认]
    end
    
    subgraph WithoutPerm["无权限系统"]
        O1[不安全]
        O2[误操作风险高]
        O3[无需打断]
    end
    
    style WithPerm fill:#E0FFE0
    style WithoutPerm fill:#FFE0E0
graph TB
    subgraph WithPerm["有权限系统"]
        W1[安全]
        W2[误操作风险低]
        W3[需用户确认]
    end
    
    subgraph WithoutPerm["无权限系统"]
        O1[不安全]
        O2[误操作风险高]
        O3[无需打断]
    end
    
    style WithPerm fill:#E0FFE0
    style WithoutPerm fill:#FFE0E0
graph TB
    subgraph WithPerm["有权限系统"]
        W1[安全]
        W2[误操作风险低]
        W3[需用户确认]
    end
    
    subgraph WithoutPerm["无权限系统"]
        O1[不安全]
        O2[误操作风险高]
        O3[无需打断]
    end
    
    style WithPerm fill:#E0FFE0
    style WithoutPerm fill:#FFE0E0

权限系统的最佳实践

推荐配置

保守配置(推荐生产环境):

{
  "permissions": {
    "deny": [
      {"tool": "Bash", "command": "rm -rf /"},
      {"tool": "Bash", "command": "sudo"},
      {"tool": "Read", "file_path": ".env"},
      {"tool": "Read", "file_path": "*credentials*"}
    ],
    "ask": [
      {"tool": "Bash", "command": "git push"},
      {"tool": "Bash", "command": "npm install"},
      {"tool": "Bash", "command": "pip install"},
      {"tool": "Write"},
      {"tool": "Edit"}
    ],
    "allow": [
      {"tool": "Read"},
      {"tool": "Glob"},
      {"tool": "Grep"},
      {"tool": "WebSearch"}
    ]
  }
}

宽松配置(推荐测试环境):

{
  "permissions": {
    "deny": [
      {"tool": "Bash", "command": "rm -rf /"}
    ],
    "allow": [
      {"tool": "Read"},
      {"tool": "Write"},
      {"tool": "Edit"},
      {"tool": "Bash"},
      {"tool": "Glob"},
      {"tool": "Grep"}
    ]
  }
}

权限审计

审计内容:

  • 记录所有权限决策(deny/ask/allow)
  • 记录审批结果(批准/拒绝)
  • 分析频繁 ask 工具(可能需要调整权限)

审计日志:

2026-05-21 10:30:15 | Bash: git push | ask | 批准
2026-05-21 10:30:20 | Write: /src/new.ts | ask | 批准
2026-05-21 10:30:25 | Bash: rm -rf temp | ask | 拒绝

本章小结

  • 权限系统定义:安全边界和审批流程
  • 三级模式:deny(禁止)、ask(审批)、allow(自动)
  • 规则匹配:deny→ask→allow→默认ask
  • 规则配置:工具名称、命令、文件路径、参数匹配
  • 审批流程:暂停执行→显示界面→用户确认→执行或拒绝
  • 配置级别:全局→项目→临时,优先级递减
  • 设计格言:先划边界,再给自由;默认deny,最小权限
  • 最佳实践:生产环境保守配置,测试环境宽松配置
  • 权限审计:记录决策,分析频繁 ask

预告:下一篇我们深入上下文管理——自动注入、压缩与惰性加载。



相关内容

如果这篇文章对你有帮助,欢迎请我喝杯咖啡 ☕
Cygnus Yang 支付宝支付宝
Cygnus Yang 微信微信