多个仓库能在同一台远程 Mac 上被 Codex CLI 打开、修改、构建,不代表它已经适合长期运行;一旦共享高权限账户、工作区边界或凭据范围没有验证,Agent 可能接触到预期之外的源码、密钥和签名资产。

本周建议动作:先不要把 Codex CLI 放进共享高权限账户。为每个试验节点准备独立系统账户、按仓库划分工作区,保留默认最小沙盒与审批策略,再按文件、网络、凭据、Xcode 执行和重启恢复五类指标验收;无法证明隔离有效时,回退到单仓库临时节点或双轨运行。

这篇内容适合三类人:

  • 专业开发者:需要让 Codex CLI 在远程 Mac 上修改、构建或测试多个仓库,但不确定工作区边界是否可靠。
  • DevOps 工程师:负责长期在线 Mac 节点、账户权限、任务清理和重启恢复。
  • 安全与平台负责人:需要审核 Agent 对源码、网络、Keychain、签名资产和 Xcode 工具链的实际访问范围。

Codex CLI 远程 Mac 多仓库安全,先看哪些指标?

Codex CLI 的安全验收不能只问“命令是否执行成功”。你要同时记录核查对象、测试方法、证据、通过条件和停止条件,否则一次成功构建只能证明流程能跑,不能证明 Agent 被限制在正确边界内。

官方资料将沙盒、审批策略和网络访问分开控制:workspace-write 可以允许工作区写入,但网络是否开放仍取决于单独的网络配置;关闭审批也不会自动开启网络。macOS 上的本地命令还会经过系统级沙盒机制,不能把提示词里的“只能修改当前仓库”当成权限边界。可先核对 OpenAI 的沙盒与审批说明Codex 配置源码中的权限字段

验收里程碑怎么排?

建议把上线前工作拆成四个里程碑:

  1. 准入:账户、工作区和凭据都能独立回收。
  2. 边界:文件、网络和外部工具测试没有越界证据。
  3. 执行:Xcode 构建、脚本和多仓库任务不会互相污染。
  4. 恢复:中断、退出、SSH 断开和重启后,节点能回到可审计状态。

任何一个里程碑出现无法解释的越界,都不要用“再加一条提示词”补救。应先降低权限、拆分节点或停止试运行。

第一步:文件边界是单仓库写入,还是整台 Mac 可写?

核查对象

先检查 Codex CLI 启动目录、当前工作区、额外可写根目录、/tmp、仓库中的 .git、项目配置文件、脚本目录和符号链接。多仓库任务尤其要确认以下情况:

  • 仓库 A 的任务能否读取仓库 B 的源文件;
  • 仓库 A 的脚本能否改写仓库 B 的构建文件;
  • .git 元数据是否被意外修改;
  • 临时目录中是否残留另一个仓库的补丁、日志或配置;
  • 符号链接是否把可写路径指向工作区之外。

官方配置中,workspace-write 的可写范围、额外 writable_roots、临时目录和符号链接行为是不同控制项;权限配置也可以把工作区根目录和网络规则分别描述。不要看到“可写工作区”就推断为“只能写当前仓库”。可参考 Codex 权限配置说明

测试方法

为每个仓库创建一个独立路径,例如:

/Users/<AGENT_USER>/work/<REPO_A>
/Users/<AGENT_USER>/work/<REPO_B>
/Users/<AGENT_USER>/tmp/<RUN_ID>

仓库名、账户名和运行编号都使用占位符。分别启动 Codex CLI,要求它完成三组动作:

  1. 读取当前仓库的一个普通源文件;
  2. 尝试读取另一个仓库中预先放置的非敏感探针文件;
  3. 尝试在工作区外创建一个测试文件。

记录终端输出、拒绝日志、文件差异和进程退出状态。不要使用真实密钥或生产源代码作为探针。

通过与停止条件

通过:当前仓库可以按预期修改;其他仓库的探针读取和写入都被拒绝或明确需要审批;工作区外没有新增文件。

停止:Agent 在无审批情况下读写其他仓库、跟随符号链接越界,或通过项目脚本间接修改共享目录。

如果你要限制 Codex CLI 只能修改当前代码仓库,系统权限必须先做到这一点,提示词只能作为行为约束,不能替代沙盒、系统账户和文件系统权限。

第二步:网络访问与外部工具,不能混成一个开关

你要分别验收什么?

远程 Mac 上的 Codex CLI 可能涉及至少五条不同路径:

  • 模型通信;
  • 包管理器和依赖下载;
  • Git 远程操作;
  • 项目脚本调用外部 API;
  • MCP 或其他工具执行器。

“关闭审批”只改变是否询问,不等于已经开启网络;同样,“允许网络”也不代表任意外部工具都被授权。官方资料明确区分沙盒网络、审批策略和权限配置;权限配置中的网络开关还可能需要配合网络代理,才能真正执行域名级限制。可参考 Codex 权限配置文档Codex 官方仓库的网络说明

测试方法

先以默认拒绝网络的配置运行一个只读任务,再分别测试:

  • 访问允许的依赖源;
  • 访问未列入允许范围的域名;
  • 执行 git fetch 或等价的只读远程操作;
  • 调用项目中的网络脚本;
  • 通过 MCP 或工具代理发起外部请求。

每一项都要记录目标域名、触发方式、是否出现审批、是否有日志以及任务结束后的网络进程。社区 Issue 可以作为待复核线索,例如某些报告曾讨论 MCP 远程执行是否可能绕开本地沙盒,但单个 Issue 不能直接证明存在普遍漏洞。可将 相关社区报告 放进风险登记表,而不要直接写进上线结论。

⚠️ 注意:如果 MCP、插件或外部执行器拥有自己的网络和文件权限,你必须单独验收它们。Codex 本地沙盒通过,不代表外部工具自动继承同样的限制。

第三步:账户、SSH 密钥和 Keychain 要做分层验证

先确认 Agent 使用的不是共享管理员身份

远程 Mac 的系统账户权限决定了 Codex CLI 能看到哪些目录、进程和用户级配置。至少要核查:

  • Codex CLI 的实际运行账户;
  • 是否属于管理员组;
  • 是否能读取其他用户目录;
  • 是否继承登录 Shell 的环境变量;
  • 是否连接了共享的 SSH Agent;
  • 是否能访问登录钥匙串;
  • 是否能读取 Xcode 签名身份和发布凭据。

建议使用独立的非管理员账户,并将仓库、缓存和临时目录都放在该账户范围内。不要通过共享管理员账户解决“某个构建命令权限不足”,那会把单个构建问题扩大成整台 Mac 的 Agent 权限问题。

三组凭据测试

使用三组可回收测试材料,而不是生产资产:

  1. 无凭据:确认代码阅读、静态检查和本地构建能否正常运行。
  2. 只读凭据:仅允许读取测试仓库或依赖源,验证 Git 操作不会写入远程。
  3. 临时凭据:限定有效期、范围和目标,用于验证必须签名或上传的步骤。

SSH 私钥不要直接放进默认 Agent 会话。更稳妥的方式是使用短期凭据、受限的 SSH Agent 转发或单独的发布节点,并在任务结束后撤销。

macOS Keychain 也不能简单归类为“本地文件”。Apple 的说明显示,应用访问钥匙串项目时可能需要用户授权;一旦选择持续允许,后续读取行为就可能不再重复提示。可参考 Apple 关于 Keychain 访问授权的说明

通过与停止条件

通过:无凭据任务仍可完成不涉及发布的工作;只读凭据不能用于写入;临时凭据可以单独撤销;默认 Agent 会话看不到生产 SSH 私钥、发布证书和生产 Keychain 项目。

停止:Codex CLI 无需额外审批即可读取生产签名私钥、长期发布 Token、共享 SSH Agent 或含有生产密码的钥匙串项目。

生产签名私钥不应直接暴露给默认 Agent 会话。需要签名时,优先把签名步骤拆到受控的发布节点,或使用只能完成单一任务的临时凭据。

第四步:Xcode 能执行,不等于构建链路可复现

Xcode 构建验收至少要覆盖 xcodebuild、Simulator、项目脚本、Derived Data、依赖缓存、签名身份和上传步骤。你要区分两个结论:

  • 命令可执行:Codex CLI 能启动 Xcode 工具链并得到退出状态;
  • 流水线可复现:相同仓库、相同参数和相同权限下,构建结果、日志和产物边界稳定。

测试时使用非生产项目和可回收签名材料,记录以下证据:

  • 构建前后的工作区差异;
  • Derived Data 和缓存的实际路径;
  • Simulator 是否能访问其他任务的设备状态;
  • 脚本是否读取用户级配置;
  • 签名失败时是否触发越权重试;
  • 上传步骤是否能被单独禁用。

如果多仓库任务共享同一个 Derived Data、缓存目录、端口或日志目录,就要测试串扰。并发任务不能只看 CPU 使用率或构建是否成功,还要看仓库 A 的产物是否出现在仓库 B 的工作区,任务 B 是否复用了任务 A 的签名或配置。

第五步:清理、审计和重启恢复决定能否长期在线

任务结束后检查什么?

每次任务结束,无论成功还是失败,都要核查:

  • Codex CLI 主进程和子进程是否退出;
  • xcodebuild、Simulator、脚本进程是否残留;
  • 临时目录是否删除;
  • 工作区是否只留下预期差异;
  • SSH Agent、环境变量和临时 Token 是否失效;
  • 日志中是否出现其他仓库路径或凭据片段;
  • 后台任务是否仍监听端口或持有文件句柄。

模拟四种故障场景:SSH 断开、Codex CLI 进程被终止、Mac 重启、任务切换到另一个仓库。每次都保存权限快照、任务日志、差异文件、进程列表和恢复结果。

用四种结论替代“安全/不安全”

根据证据作出以下判断:

  • 可上线:五类边界测试均通过,凭据可回收,重启后无残留越界。
  • 限用:只允许单仓库轮换、只读审查或不含签名的构建。
  • 重建节点:文件、账户或凭据边界无法解释,需要重新创建独立系统账户和工作区。
  • 暂缓:存在跨仓库读取、生产凭据暴露、MCP 绕过路径或任务无法清理。

如果你还没有现成的远程 Mac 验收流程,可以先从 VMSPIN 的远程 Mac 节点方案 了解节点交付边界,再把上述测试放进自己的上线记录中。需要长期运行时,也应先比较 远程 Mac 的套餐与计费方式,不要在未完成权限复测前直接把生产仓库迁移过去。

上线前的条件分支:你该选哪种运行方式?

  • 若满足独立系统账户、单仓库可写根目录、默认网络受限、生产凭据不进入 Agent 会话、任务可清理且重启可恢复,则可以进入多仓库灰度。
  • 若只能满足文件隔离和账户隔离,但网络或 Xcode 签名边界尚未证明,则选择单仓库临时节点,只做审查、测试构建或非生产签名。
  • 若多个仓库必须共享管理员账户、共享 SSH Agent 或共享 Keychain,则不要让 Codex CLI 自动修改代码,回退到只读审查或人工审批。
  • 若 MCP、外部执行器或脚本可以绕过本地沙盒,则先拆分执行节点,再重新验收;不能通过提示词承诺“只访问当前仓库”来放行。
  • 若 SSH 断开、重启或任务中断后仍会残留进程和凭据,则暂停长期在线运行,先建立清理钩子和恢复步骤。
验收维度 可上线的证据 常见回退方案
文件访问 只能写当前仓库及明确声明的临时目录 单仓库临时节点或只读审查
网络访问 允许目标可解释,未授权域名被拒绝,审批有记录 关闭网络,改用预下载依赖
SSH 与 Keychain 使用短期、只读或任务专用凭据 移除凭据,拆到发布节点
Xcode 构建 构建、签名、缓存和产物路径可追溯 仅运行非签名构建
多仓库并发 工作区、端口、缓存和日志互不串扰 单节点轮换或独立节点分池
清理与恢复 中断、退出、重启后无残留越界 重建节点,暂缓生产任务

对于需要临时算力、隔离试跑或短期 Codex CLI 环境的团队,VMSPIN 的远程 Mac 比“把自己的开发 Mac 长期开成共享服务器”更容易拆分账户、工作区和任务生命周期;但它也不会替你完成安全验收。你仍应先用非生产仓库复测文件、网络、凭据、Xcode 和恢复指标,再决定使用单节点轮换、独立节点,还是双轨 CI。需要购买或交付节点时,可以从 VMSPIN 远程 Mac 方案开始比较;如果你的任务是长期稳定重负载、依赖物理接口,或必须完全掌控硬件固件,自购 Mac 仍可能更合适。