DeepDojo.AI发布 2026-11-13更新 2026-11-13English
Claude Code 跑在 CI 里,权限怎么设
平时在交互终端里和 Claude 对话,感觉很自由:下一步怎么走没想好,可以多问两句;缺什么文档随时补;改完代码还能当场扫一眼,再决定要不要继续。
换到“每天半夜跑定时巡检、自动分析几百行构建报错”这种固定场景,事情的性质就变了:输入是现成的日志文件,输出是给报警系统消费的摘要。这时候还得半夜手动开个窗口敲回车,你就成了人肉转接器。
边界和格式已经固定的重复工作,很适合交给脚本:
- CI 跑完单元测试后自动提炼失败堆栈;
- 本地脚本批量扫描代码,提出测试补丁建议;
- 定时任务拉取慢查询日志,输出格式化的 JSON 告警。
难点在于,把键盘交给脚本的那一刻,就没人替你看权限提示了。交互里随手点的“允许”,在无人值守时要么卡住整个流程,要么被一刀切地跳过。办法是先从只读分析起步,再按脚本的实际动作逐项设权限:模型能拿到哪些工具、哪些调用不用确认、哪些动作要单独拦住,最后给轮次、预算和并发加上上限。
01 一次 CLI 调用经过哪些环节
在终端输入 claude 时,你用的就是 CLI,也就是命令行接口。一个 CLI 调用可以拆成这条链路:
命令行输入
|
v
claude [options] [query]
|
v
选择模式:交互 / print
|
v
加载上下文、模型、权限、MCP、agents
|
v
生成输出:text / json / stream-json
|
v
终端显示、脚本处理、CI 消费或管道传给下一个命令下面的命令会启动交互式会话,也可以带一个初始问题启动:
claude
claude "解释这个认证流程"如果任务要把一次请求的结果交给脚本,就用打印模式,输出后退出:
claude -p "这个函数做什么?"你可以把文件内容通过管道传进去,也可以把输出继续交给其他工具:
cat error.log | claude -p "解释这些错误并给出修复建议"
claude -p "列出待办事项" | grep "URGENT"开始只需分清:要接着讨论,用 claude;要让脚本接结果,用 claude -p。恢复会话、登录、管理 MCP、后台会话或插件,遇到时再查对应入口。
02 交互模式和打印模式怎么选
交互模式适合需要人持续判断的任务,例如探索架构、逐步重构、比较方案,或让 Claude Code 先读代码再提计划。打印模式适合一次性、可脚本化的任务,例如解释日志、总结测试失败、输出 JSON、生成固定格式报告或批量分析文件。
| 模式 | 启动方式 | 特点 | 适合场景 |
|---|---|---|---|
| 交互模式 | claude | 多轮对话、历史记录、Tab 补全、slash commands | 探索、讨论、重构、人工确认 |
| 打印模式 | claude -p | 单次查询、可管道化、可输出 JSON | 脚本、CI、批处理、机器消费 |
把两类任务放在一起想。支付模块偶发重复扣款,当前还不知道根因,要不断追证据、排除假设,交互会话便于接着谈。每晚总结构建日志,材料和用途早已确定,打印模式就能把结果交给脚本。
打印进程退出后,如果直接发起新请求继续追问,前面的结论未必还在。恢复会话或传入必要结论,才有条件接着做;否则可能重复读一遍代码。
无人值守先从只读分析、日志总结和格式化输出开始。文件修改、部署、推送、删除和数据迁移涉及实际状态,要把人工确认留在相应动作前。
03 -p 退出得快,内部仍然是多轮
-p(print)在打印结果后退出进程,一次调用内部仍可能包含多轮推理和工具交互。
比如你让它“审查这个函数并报告隐患”,它得先调用 Read 工具读文件,发现引用了外部工具类又得去 Grep 跨文件定位,必要时还要在终端里跑测试,最后才把综合分析结果打印出来。
所以给脚本设置轮次上限和预算时,要站在“完成整条业务链路”的视角来衡量。如果随手写一个 --max-turns 1,它可能刚用工具读完第一个文件就因为轮次耗尽被掐断,最终吐出一个半截报告。
拿到脚本输出后,也得回过头扫一眼工具调用日志,确认它在报告里声称“跑过测试”“翻过源码”的结论,是真的查过,还是凭空推断出来的。打印模式省下的是人机交互的等待时间,排查过程本身的步骤一步也没少。
04 按实际动作逐项设权限
无人值守任务缺少现场确认,权限边界因此更重要。CLI 提供了几类控制参数:
| 参数 | 作用 |
|---|---|
--tools | 限制可用的内置工具,"" 表示全部关闭 |
--allowedTools | 指定无需提示即可执行的工具 |
--disallowedTools | 拒绝规则:写工具名会把它从可用工具里移除,写带范围的规则只拒绝匹配的调用 |
--permission-mode | 用指定权限模式启动 |
--permission-mode auto | 由自动权限机制判断调用风险 |
--dangerously-skip-permissions | 跳过权限提示,高风险 |
配置前先判断任务风险。只读分析只开放读取工具;修改文件或外部系统的任务,还要明确无需提示的允许项和禁止项。
假设无人值守任务是“每晚审查新增代码并生成报告”,可按实际动作确定权限:
- 保留 Read、Grep、Glob,用于阅读代码。
- 允许必要测试命令,例如
Bash(npm test *),避免无人处理确认。 - 用
--disallowedTools "Edit,Write"移除编辑工具。 - 拒绝不属于报告任务的 push 和部署操作。
下面分别演示权限设置,它们不是一条可复制即用的完整安全策略:
# 只读审查
claude --permission-mode plan -p "审查这个代码库"
# 只允许读取和搜索
claude --tools "Read,Grep,Glob" --disallowedTools "mcp__*" -p "找出所有 TODO 注释"
# 允许特定 git 查询,无需提示
claude --allowedTools "Bash(git status *)" "Bash(git log *)"
# 阻止危险命令
claude --disallowedTools "Bash(rm -rf *)" "Bash(git push --force *)"回到“每晚只出报告”的任务,先逐项问:模型还能拿到哪些工具,哪些调用不用确认,还有哪种能力需要另外限制?按 Claude Code 的 CLI 参考,--tools 只筛内置工具,MCP 工具要用 --disallowedTools "mcp__*" 单独拒绝;--allowedTools 只免去提示,没列出的工具并不会因此消失。这和斜杠命令里 allowed-tools 的原理相同,详见Claude Code 只读命令为什么还能改文件。
再看拒绝列表。只写 rm -rf 和强推两种写法,其他等效命令仍可能没覆盖。Plan 模式适合先分析,外部账号却仍需自己的只读权限。工具、命令和账号各管一段,只收紧其中一项,代替不了其余检查。
检查仍需确认的操作能否从任务中移除;无法收紧的部分,安排在有人值守的流程中。权限范围要覆盖脚本的实际效果,不能只看名称。若某步还要等待确认,就考虑把它移出无人值守流程,跳过提示并不等于获得授权。
--dangerously-skip-permissions 只适合在可随时销毁重建的沙盒或一次性容器里使用。在日常主机上给无人值守脚本这样的权限,会让文件、远端仓库、生产部署和核心数据库面临风险,先在权限层限制这些操作。
05 留意那些不经过工具也会运行的东西
权限参数管的是模型调用的工具,有些内容在调用开始时就会自己运行。官方的 Claude Code 程序化运行文档提醒:不加 --bare 时,claude -p 会像交互会话一样加载项目配置,运行 .claude/settings.json 里的 Hook、连接 .mcp.json 里的服务器,即使是在一个从未信任过的文件夹里,而且打印模式不会弹出信任对话框。
所以即使把模型的内置工具和 MCP 都关了,配置里的 Hook 仍可能执行。选择可信目录,把这部分副作用单独查过,再谈这次分析是不是只读。
--bare 能排除这些干扰,先看看它会一起拿掉什么:Hooks、Skills、插件、MCP、自动记忆和 CLAUDE.md 都会跳过,订阅登录凭据和系统钥匙串也不会读取,使用 Anthropic API 时需要另给 ANTHROPIC_API_KEY。配置少了,测试条件也变了;先确认规则与认证来源,再决定用不用它。
--no-session-persistence 只决定是否留下可恢复的会话记录。CI 只要当前结果时可以用它,但不能因此推断磁盘或外部状态也被隔开了。
06 目录、MCP 和模型参数只给当前任务需要的
工作目录和外部工具同样会扩大范围。规范做法是先 cd 进项目目录再启动,跨仓库任务再按需追加:
| 参数 | 作用 |
|---|---|
--add-dir | 追加可见目录 |
--mcp-config | 从文件加载 MCP 配置 |
--strict-mcp-config | 仅使用 --mcp-config 提供的 MCP 配置 |
# 在后端目录工作,同时读取前端目录
(cd ./backend && claude --add-dir ../frontend)
# 严格只启用指定 MCP
claude --strict-mcp-config --mcp-config ./configs/strict-mcp.json括号让 cd 只影响这次调用;相对路径按进入后的目录解释。严格 MCP 示例要求配置文件里只包含本次需要的服务。多目录和 MCP 会同时扩大上下文与权限范围,自动化脚本只加载当前任务必需的部分。
模型参数同样按需调整。--model 指定模型,--fallback-model 在主模型不可用或负载过高时换用后备模型,--effort 设置推理强度。普通批处理沿用默认值即可;复杂架构、排错或审查任务再调整。只指定一个高负载模型可能提高失败率,配置后备模型能增加可用性,但后备模型也要足以完成任务。
如果某次 CLI 会话需要临时使用一个只读的审查角色,可以用 --agents 传入 JSON 定义,再用 --agent 指定。定义里用 tools 只给 Read、Grep、Glob,用 description 和 prompt 写清调用时机与方法;临时定义只作用于本次会话。
07 批处理先定三个上限
当文件数量成百上千时,稍不留神就会碰上 API 限流或预算失控。在脚本全量放开跑之前,先定三个上限:
| 控制项 | 限制什么 |
|---|---|
| 轮次 | 单项工作量 |
| 预算 | 费用 |
| 并发 | 同时运行的数量 |
# 处理多个文件,每个文件限制轮次和预算
find src -name "*.ts" -print0 | xargs -0 -I{} claude -p --max-turns 5 --max-budget-usd 1 "review {}"这里的数值只是示例,不能当成所有任务的推荐值。官方说明 --max-budget-usd 按客户端估算的花费判断,实际花费可能越过上限,要留出余量。
先用一小批文件试跑,看清失败项和成本,再定上限;直接扩大批次,可能会让尚未查清的问题更难处理。失败项仍由人决定缩小输入还是重试。
环境变量适合统一脚本环境,比如 ANTHROPIC_MODEL 设默认模型、CLAUDE_CODE_EFFORT_LEVEL 设推理强度。准备在另一台机器运行时,沿脚本确认三件事:在哪里执行、输出交给谁、使用哪份 MCP 配置,分别用 cd、--output-format 和 --mcp-config 明确写出。真实密钥由安全的环境配置注入,不写进教程、仓库和命令模板。
出故障时,先按失败位置选择检查:
| 现象 | 先查什么 |
|---|---|
找不到 claude | 安装、PATH,再重开终端 |
| 登录或 API key 失败 | 认证状态、有效期与 API 网络 |
| 找不到会话 | 名称、ID、账号,以及是否用了 --no-session-persistence |
| 权限拒绝 | --permission-mode、--allowedTools、--disallowedTools,按任务补最小权限 |
| MCP 不可用 | 配置路径、server 名和本次是否启用 |
权限设好之后,脚本拿到的结果还要校验:JSON 能解析、调用没报错,结论是否有依据仍是另一回事。这一步接着看 校验 Claude Code 输出的 JSON。
半夜那次巡检能放心交给脚本,靠的是权限覆盖了它真正会做的每一个动作;仍要等人确认的那一步,就留在白天有人值守的流程里。