CLI 权限
基于 Cursor 官方 Permissions 文档解释 Shell、Read、Write、WebFetch、MCP permission tokens、allow/deny 优先级和配置位置。
Cursor CLI permissions 用 permission tokens 控制 Agent 能做什么。它们可以写在全局 ~/.cursor/cli-config.json,也可以写在项目级 <project>/.cursor/cli.json。
阅读目标:读完本章,你应该能写出一份最小权限配置,区分 shell、read、write、web fetch 和 MCP 工具权限,并理解 deny 为什么优先。
1. 配置位置
| Scope | Path | 用途 |
|---|---|---|
| Global | ~/.cursor/cli-config.json | 当前用户默认 CLI 配置 |
| Project | <project>/.cursor/cli.json | 当前项目权限配置 |
项目级配置适合团队仓库,因为它能把“这个项目里 Agent 可以做什么”写进仓库边界。
2. 五类 permission tokens
| 类型 | 格式 | 控制什么 |
|---|---|---|
| Shell | Shell(commandBase) | shell command base |
| Read | Read(pathOrGlob) | 文件和目录读取 |
| Write | Write(pathOrGlob) | 文件和目录写入 |
| WebFetch | WebFetch(domainOrPattern) | web fetch 可访问域名 |
| MCP | Mcp(server:tool) | MCP server tool 调用 |
核心规则:allow 只是允许,deny 是硬阻止。deny rules take precedence over allow rules。
3. Shell 权限
Shell token 看命令行第一个 token,也支持 command:args 做更细控制。
| 示例 | 含义 |
|---|---|
Shell(ls) | 允许 ls |
Shell(git) | 允许任意 git subcommand |
Shell(npm) | 允许 npm |
Shell(curl:*) | 允许 curl 及任意参数 |
Shell(rm) | 常见 deny,用于阻止删除 |
生产默认不要轻易 allow git、gh、rm、sudo、curl 和包管理器全量命令。它们要么能改历史,要么能访问外部网络,要么能破坏文件系统。
4. Read 和 Write 权限
Read 控制可读范围:
| 示例 | 含义 |
|---|---|
Read(src/**/*.ts) | 允许读 src 下 TypeScript |
Read(**/*.md) | 允许读任意 Markdown |
Read(.env*) | 常见 deny,阻止读环境文件 |
Read(/etc/passwd) | 常见 deny,阻止读系统文件 |
Write 控制可写范围。官方提醒:print mode 中写文件需要 --force。
| 示例 | 含义 |
|---|---|
Write(src/**) | 允许写 src |
Write(package.json) | 允许改 package.json |
Write(**/*.key) | 常见 deny,阻止写私钥文件 |
Write(**/.env*) | 常见 deny,阻止写环境文件 |
商业项目里,Write 的范围应该比 Read 更窄。能读全仓不等于能写全仓。
5. WebFetch 和 MCP
WebFetch 控制网页读取域名:
| 示例 | 含义 |
|---|---|
WebFetch(docs.github.com) | 允许 GitHub docs |
WebFetch(*.example.com) | 允许 example.com 子域名 |
WebFetch(*) | 允许任意域名,高风险 |
MCP token 使用 server:tool:
| 示例 | 含义 |
|---|---|
Mcp(datadog:*) | 允许 Datadog MCP 所有工具 |
Mcp(*:search) | 允许任意 server 的 search 工具 |
Mcp(*:*) | 允许所有 MCP 工具,高风险 |
WebFetch(*) 和 Mcp(*:*) 都不适合默认生产配置。它们方便,但审计边界太宽。
6. 最小配置示例
{
"permissions": {
"allow": [
"Shell(ls)",
"Shell(grep)",
"Read(src/**/*.ts)",
"Read(**/*.md)",
"Write(docs/**/*)",
"WebFetch(docs.github.com)"
],
"deny": [
"Shell(rm)",
"Shell(git)",
"Shell(gh)",
"Read(.env*)",
"Write(**/*.key)",
"WebFetch(*)"
]
}
}这不是通用答案,而是思路:先只开放任务需要的读、写、命令和域名;再用 deny 锁住高风险区域。
7. Pattern matching
官方规则:
- glob 支持
**、*、?。 - relative paths 以当前 workspace 为作用域。
- absolute paths 可以指向项目外文件。
- deny 优先于 allow。
command:args可对命令和参数做 glob 匹配。
这意味着 <project>/.cursor/cli.json 里的相对路径要结合 workspace 理解。CI 中最好显式设置 workspace,避免路径作用域误判。
深读:为什么 deny 要写得比 allow 更保守
allow 定义任务能力,deny 定义事故边界。任务变化时,allow 可能需要扩展;但 .env*、private key、删除命令、系统文件、生产凭据这类边界通常长期稳定。
把稳定红线写进 deny,可以减少因为临时任务扩权导致的泄露或破坏。
本章自检
完成本章后,用这 3 个问题检查自己是否真正理解:
- 为什么 Write 范围通常应该小于 Read 范围?
WebFetch(*)和Mcp(*:*)为什么不适合默认生产配置?- deny 和 allow 同时命中时谁优先?
通过标准:你能为 docs-only CI workflow 写出 permissions,并解释每条 allow / deny 的业务原因。
官方来源
- Cursor CLI Permissions —— 官方 permission tokens、配置示例和 pattern matching。
- Cursor CLI Configuration —— 官方配置文件位置和 schema。
- Cursor GitHub Actions —— 官方 CI permissions 示例。