Appearance
Gemini CLI 的 Policy Engine 通过 TOML 规则文件实现工具级精细授权:每条规则指定工具名、参数模式(正则)、运行模式,以及 allow/deny/ask_user 三种决策。规则按五层优先级(Default→Extension→Workspace→User→Admin)排序,Admin 层始终优先于用户设置。deny 决策还会从模型上下文中完全隐藏工具,节省 Token 并防止绕过尝试。
Policy Engine 策略引擎
Policy Engine 是 Gemini CLI 内置的工具调用授权系统,通过 TOML 规则文件对每次工具调用做精细化决策:允许、拒绝或要求用户确认。
快速开始
创建策略目录:
bash# macOS/Linux mkdir -p ~/.gemini/policiespowershell# Windows PowerShell New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.gemini\policies"创建规则文件(文件名任意,后缀必须是
.toml):toml# ~/.gemini/policies/my-rules.toml [[rule]] toolName = "run_shell_command" commandPrefix = "rm -rf" decision = "deny" priority = 100向 Gemini CLI 发出触发该规则的命令,工具调用将被自动拦截。
核心概念
条件(Conditions)
条件决定规则适用于哪些工具调用:
| 条件字段 | 说明 |
|---|---|
toolName | 工具名,支持通配符 *、mcp_server_*、mcp_* |
argsPattern | 工具参数序列化为 JSON 后与此正则匹配 |
commandPrefix | Shell 命令前缀匹配(run_shell_command 语法糖) |
commandRegex | Shell 命令正则匹配(不可与 commandPrefix 同用) |
mcpName | 指定 MCP 服务器名(推荐用于 MCP 工具规则) |
subagent | 指定子代理名(只对该子代理发起的调用生效) |
toolAnnotations | 工具注解键值对,所有指定键值均需存在才匹配 |
interactive | true 只在交互模式生效;false 只在无头模式生效 |
modes | 运行模式数组,见运行模式 |
决策(Decisions)
| 决策 | 效果 |
|---|---|
allow | 自动执行,无需用户确认 |
deny | 拦截工具调用;对全局规则(无 argsPattern),工具还会从模型上下文中完全隐藏 |
ask_user | 弹出确认对话框;在无头模式中等同于 deny |
deny是移除工具的推荐方式,替代已废弃的tools.exclude配置项。
优先级与分层
引擎按优先级从高到低评估所有规则,第一个匹配的规则生效。
五个层级及其基础值:
| 层级 | Base | 说明 |
|---|---|---|
| Default | 1 | Gemini CLI 内置的默认规则 |
| Extension | 2 | 扩展插件中定义的规则 |
| Workspace | 3 | 当前已禁用(见注意事项) |
| User | 4 | 用户自定义规则(~/.gemini/policies/) |
| Admin | 5 | 管理员强制规则(系统级策略目录) |
TOML 文件中的 priority 取值范围 0–999,最终优先级计算公式:
final_priority = tier_base + (toml_priority / 1000)示例:
- Default 层
priority: 50→ 最终1.050 - User 层
priority: 100→ 最终4.100 - Admin 层
priority: 20→ 最终5.020(始终高于所有 User 规则)
注意:Workspace 层(项目级
.gemini/policies/)目前不可用,相关 issue 见 #18186。请使用 User 或 Admin 层策略替代。
运行模式
通过 modes 字段将规则绑定到特定运行模式:
| 模式 | 说明 |
|---|---|
default | 标准交互模式,写操作默认需要确认 |
autoEdit | 代码编辑自动化模式,部分写操作自动批准 |
plan | 只读规划模式,参见 Plan Mode |
yolo | 所有工具自动批准(极度谨慎使用) |
模式宽松度从低到高:plan < default < autoEdit < yolo。
持久授权("Allow for all future sessions")的模式继承规则:
- 在
plan模式中授权 → 规则包含所有模式(plan/default/autoEdit/yolo) - 在
default模式中授权 → 规则包含 default/autoEdit/yolo - 在
autoEdit模式中授权 → 规则包含 autoEdit/yolo - 在
yolo模式中授权 → 规则仅包含 yolo
TOML 规则字段完整参考
toml
[[rule]]
# 工具名,支持通配符,或字符串数组
toolName = "run_shell_command"
# (可选) 子代理名,只对该子代理发起的工具调用生效
subagent = "codebase_investigator"
# (可选) MCP 服务器名(推荐用于 MCP 工具规则)
mcpName = "my-custom-server"
# (可选) 工具注解键值对,全部匹配才触发
toolAnnotations = { readOnlyHint = true }
# (可选) 工具参数 JSON 的正则表达式
argsPattern = '"command":"(git|npm)'
# (可选) Shell 命令前缀匹配(不可与 commandRegex 同用)
commandPrefix = "git"
# (可选) Shell 命令正则匹配(不可与 commandPrefix 同用)
commandRegex = "git (commit|push)"
# 决策:allow / deny / ask_user
decision = "ask_user"
# 规则优先级,0–999(最终优先级 = tier_base + priority/1000)
priority = 10
# (可选) 拒绝时展示给用户和模型的说明信息
denyMessage = "Deletion is permanent"
# (可选) 生效的运行模式数组,缺省时对所有模式生效
modes = ["default", "autoEdit", "yolo"]
# (可选) true = 只在交互模式生效;false = 只在无头模式生效
interactive = true
# (可选) 是否允许重定向操作符(>、>>、<、<<)
# 默认下,即使规则匹配,检测到重定向也会再次询问用户
allowRedirection = true常用规则示例
拒绝危险删除命令
toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = "rm -rf"
decision = "deny"
priority = 100
denyMessage = "rm -rf 已被策略禁止,请使用更安全的删除方式。"Git 命令需要确认
toml
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git"
decision = "ask_user"
priority = 50多个工具统一策略
toml
[[rule]]
toolName = ["write_file", "replace"]
decision = "ask_user"
priority = 10无头模式下禁止所有写操作
toml
[[rule]]
toolName = ["write_file", "run_shell_command"]
interactive = false
decision = "deny"
priority = 200
denyMessage = "非交互模式下禁止写操作。"MCP 工具规则(推荐语法)
使用 mcpName 字段针对 MCP 服务器定义规则,是比 FQN 通配符更稳健的方式。
警告:MCP 服务器名中不要包含下划线(
_),应使用连字符(如my-server)。策略解析器在mcp_前缀后按第一个下划线分割 FQN,服务器名含下划线会导致规则静默失效。
针对服务器上的特定工具
toml
[[rule]]
mcpName = "my-jira-server"
toolName = "search"
decision = "allow"
priority = 200拒绝整个服务器的所有工具
toml
[[rule]]
mcpName = "untrusted-server"
decision = "deny"
priority = 500
denyMessage = "此服务器不在管理员信任列表中。"所有 MCP 服务器的默认策略
toml
[[rule]]
toolName = "*"
mcpName = "*"
decision = "ask_user"
priority = 10子代理规则
将子代理名作为 toolName 来控制子代理的调用权限:
toml
[[rule]]
toolName = "codebase_investigator"
decision = "deny"
priority = 500
denyMessage = "深度代码库分析在当前会话中受限。"管理员系统级策略
策略文件路径
| 层级 | 路径 |
|---|---|
| User(用户) | ~/.gemini/policies/*.toml |
| Admin(管理员) | 见下表 |
系统标准路径(Admin):
| 操作系统 | 路径 |
|---|---|
| Linux | /etc/gemini-cli/policies |
| macOS | /Library/Application Support/GeminiCli/policies |
| Windows | C:\ProgramData\gemini-cli\policies |
补充管理员策略
管理员还可以通过以下方式指定补充策略路径:
- 命令行标志:
--admin-policy <路径> - 系统配置文件中的
adminPolicyPaths设置
安全防护:如果标准系统目录中已存在 .toml 文件,补充策略将被忽略,防止通过标志绕过已建立的中央策略。
文件权限安全要求
为防止权限提升,CLI 对标准系统策略目录有严格安全检查,检查失败时该目录下的策略将被忽略:
- Linux/macOS:必须由
root(UID 0)所有,且组和其他用户不可写(如chmod 755) - Windows:必须位于
C:\ProgramData,标准用户(Users/Everyone)不得有写入、修改或完全控制权限
默认策略行为
Gemini CLI 出厂内置默认策略:
- 只读工具(
read_file、glob等):默认allow - 代理委托:默认
ask_user(确保远程代理能请求确认,本地子代理静默执行后单独检查) - 写操作工具(
write_file、run_shell_command等):默认ask_user - YOLO 模式:高优先级规则允许所有工具
- autoEdit 模式:特定写操作无需用户确认
常见问题
Q: Policy Engine 的 deny 和 tools.exclude 有什么区别?
A: tools.exclude(已废弃)只是过滤工具列表;Policy Engine 的 deny 对全局规则(无 argsPattern)会将工具从模型的上下文中完全删除,模型甚至不会"看到"这个工具存在,安全性更高,还能节省 Token。
Q: 如何让某条规则只在 CI/CD 无头模式下生效?
A: 设置 interactive = false,例如:
toml
[[rule]]
toolName = "run_shell_command"
interactive = false
decision = "deny"
priority = 200这样规则只在非交互模式(无头、CI/CD)下生效,不影响本地交互使用。
Q: Admin 层策略文件权限检查失败会怎样?
A: CLI 会静默忽略该目录下的所有策略文件,并不会报错中断运行。管理员需要通过日志或调试输出确认策略是否正确加载。建议部署后用测试命令验证策略是否生效。