该版本修复了配置allowed_non_write_users时所有Bash命令在GitHub托管运行器上失败的问题,升级即可解决。
Claude Code 2.1.227 修复了一个回归问题:在 GitHub-hosted runner 上,当配置了 allowed_non_write_users 时,每个 Bash 命令都可能在 claude-code-action 中失败。Claude Code Action 1.0.190 则固定了该修复 CLI 版本。
升级后,证明任务已安装 Claude Code 2.1.227+,并在一个独立 step 中检查一个一次性 Bash 标记。不要使用 CLAUDE_CODE_SUBPROCESS_ENV_SCRUB: "0" 作为生产修复方案:它会禁用针对不可信输入工作流的保护机制。
本指南适用于那些 Claude Code Action 工作流需要接收来自没有仓库写权限用户的 issue 或 pull request 输入的维护者。可识别的失败表现是 Bash 工具报错,例如:
bwrap: Can't create file at /home/.mcp.json: Permission denied
Read、Write 或 Edit 可能看起来仍然正常工作,而依赖 shell 的测试、提交或推送永远不会发生。这使得仅从 Claude 的最终叙述来判断工作流是否成功变得危险。
与 2.1.223 的权限回归检查清单或 2.1.224 的自托管环境指南不同,本任务旨在恢复 GitHub-hosted action 的非写用户沙箱。
Anthropic 的 2.1.227 发布版本明确表示已修复在 GitHub-hosted runner 上,当 allowed_non_write_users 配置时,每个 Bash 命令在 claude-code-action 中失败的问题。相应的 Claude Code Action 1.0.190 源码固定了 Claude Code 2.1.227 和 Agent SDK 0.3.227。
安全边界仍然是强制的。allowed_non_write_users 会绕过正常的写权限检查,并需要 github_token 输入。官方指导称其存在风险,在最佳努力基础上从子进程环境中移除 secrets,在支持的 Linux runner 上添加 PID 命名空间隔离,并要求使用 job-scoped 的 GITHUB_TOKEN、最小权限以及窄化的工具列表。
第一行是公开的复现证据,而非官方支持范围。已交付的事实是 2.1.227 修复;请以任务的安装日志为准。
使用 anthropics/claude-code-action@v1.0.190,或固定经过审查的 commit。对于可变的 @v1,在每次运行中记录解析后的 action commit 和 CLI 版本。
移除任何紧急的 CLAUDE_CODE_SUBPROCESS_ENV_SCRUB: "0" 覆盖。只使用 ${{ secrets.GITHUB_TOKEN }} 作为 github_token,绝不要使用 PAT。从最小的事件和权限集开始:issue-labeling 流程不要仅仅因为未来工作流可能需要就授予 contents: write 或 pull-request writes。
在一个一次性仓库或分支中,让 Claude 执行一个完全无害的命令并读取回来:
- uses: anthropics/claude-code-action@v1.0.190
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
allowed_non_write_users: "test-contributor"
prompt: |
Run `printf 'CLAUDE_BASH_OK\n' > claude-bash-smoke.txt`, then read the file.
Do not modify any other file.
claude_args: |
--allowedTools "Bash"
- name: Verify Bash executed outside the model narrative
shell: bash
run: test "$(tr -d '\r\n' < claude-bash-smoke.txt)" = "CLAUDE_BASH_OK"
宽泛的 Bash 权限仅在这个空的一性次 canary 中可接受。在真实工作流中用命令级别的工具替换它。
使用伪造的哨兵凭证,绝不要用生产 secrets。让 Bash 只报告已知凭证变量是否缺失,如果哨兵值出现在日志、文件、注释、artifacts 或最终答案中则失败。保持父 action 所需的认证与子进程断言分离。
测试一个命名的允许用户、一个未列出权限的非写用户和一个 bot。确认只有命名用户能访问 Claude,且任务无法在其声明目的之外写入。避免使用 allowed_non_write_users: "*";白名单并不能使不可信的 prompt 变得安全。
要求 Bash 标记通过、版本符合预期、没有 scrub 退出选项、没有哨兵泄露、角色决策正确,以及预期的 GitHub 结果。绿色的结论或自信的 assistant 消息是不够的。如果旧版 CLI 损坏,回滚工作流能力而非 CLI。
如果 allowed_non_write_users 未配置,请调查其他类型的 Bash 失败。
如果日志显示 CLI 版本早于 2.1.227,更新 action 或修复一个过时的 pin。
如果已安装 2.1.227+ 但标记失败,保留日志并停止;不要在生产环境中禁用 scrubbing。
如果标记通过但角色或 secret canary 失败,在任何发布之前减少权限和工具。
只有在同一个 action commit 和 runner 镜像上通过全部六个门禁后,才能恢复具有写权限的自动化。
假设 @v1 始终指向相同的代码;记录解析后的 commit 和 CLI 版本。
将开放 issue 的推断根因视为产品合约。官方发布确认了修复,但不是每个内部机制。
因为它曾让 Bash 工作过就保留 scrub 退出选项。
在不可信 prompt 上使用 PAT 或授予宽泛的 contents: write 权限。
询问 Claude Bash 是否工作了,而不是断言外部标记。
使用真实的 secret、仓库或发布凭证重新测试。
对于额外的出口控制,请将此恢复方案与严格的网络白名单检查清单配对使用。对于角色到写权限的映射,请使用 GitHub issue agent 审批置信度检查清单。
action_ref / resolved_commit:
installed_claude_code_version:
runner_image:
allowed_non_write_users: named list | wildcard
subprocess_env_scrub_override: absent | present
workflow_permissions:
allowed_tools:
bash_marker_external_assertion: pass | fail
fake_secret_absent_from_child_outputs: pass | fail
unlisted_actor_denied: pass | fail
expected_write_scope_only: pass | fail
rollback_ref:
owner / evidence_url / decision:
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB 设置为 0 来修复失败吗?它可以诊断旧的耦合问题,但会移除旨在保护不可信输入工作流的保护机制。请升级并验证 2.1.227+ 版本。
allowed_non_write_users: "*" 安全吗?不安全。修复恢复了 Bash 执行;它并不会使任意贡献者的 prompt 变得可信。优先使用命名用户、最小权限、窄化工具和确定性输出验证。
报告的回归问题可能使非 shell 工具仍然正常运作,并仍然产生看起来成功的答案。标记证明了命令实际上独立于模型声明运行。