核心摘要
Cloud Coding Agent 是远程软件执行系统,模型只是其中一个组件。生产架构还必须控制:
task -> policy -> Run 级身份 -> 隔离 Workspace
-> 工具与网络 -> 仅分支改动 -> 验收证据
-> 人工/策略决策 -> 清理与保留
Pull Request 是待审提案,不是任务正确的证明。安全系统应为每个 Run 签发有边界的身份,把仓库和 Web 内容视为不可信输入,分离 Setup Credential 与 Agent Runtime Secret,限制网络出口,在执行前定义验收门禁,并保证取消或恢复不会重复产生外部副作用。
本文不再讨论“编程进入哪个时代”或引用厂商采用率,而是聚焦团队真正需要评审的运行时架构。
核心要点
- Cloud 只是运行位置,不是可信属性。 远程执行会改变数据、身份、网络和保留边界。
- 隔离单位应是单次 Run。 每个 Run 都要有确定的基础 Commit、环境镜像、策略、身份、分支、预算和清理状态。
- Prompt Injection 会变成系统风险。 Issue、源文件、Package 文档、测试 Fixture、工具结果和网页都是不可信输入。
- 证据必须可机器验证。 日志和摘要有助于调查;退出码、签名 Commit、Artifact Hash 和最终状态检查才支撑验收。
- 并行 Agent 会同时放大审查负担和爆炸半径。 并发应受冲突域、预算、环境容量和 Reviewer 吞吐限制。
先定义运行时边界
Cloud Agent 平台至少包含六个平面:
| 平面 | 职责 | 核心控制 |
|---|---|---|
| 控制面 | 任务、策略、预算、生命周期 | 不可变 Run Spec |
| 身份面 | Git、Cloud、Package、工具凭证 | 短期最小权限 |
| Workspace | Checkout、文件系统、进程、缓存 | Run 级隔离与清理 |
| 网络面 | DNS、HTTP、Registry、内部服务 | Deny/Allow 策略与审计 |
| 交付面 | 分支、Commit、Pull Request | 受保护主分支与范围化 Push |
| 证据面 | 命令、测试、Artifact、决策 | 完整性、保留、脱敏 |
厂商可以在内部合并这些平面,但企业安全评审应逐一检查。
Run 生命周期
1. 接收任务
先把请求规范化成 RunSpec:
- 仓库与基础 Commit;
- 任务文本与可信指令来源;
- 允许修改的文件范围;
- 可用工具;
- 网络策略;
- 密钥类型;
- 资源与时间预算;
- 必须通过的验收门禁;
- 交付目标;
- 保留级别。
如果请求权限超过策略,应在 Provision 前直接拒绝。
2. Provision
从固定镜像或经过证明的模板创建专属环境,并记录:
- Image Digest;
- CPU、内存、磁盘和时间上限;
- Tenant 与 Run ID;
- Host 隔离类型;
- Mount Volume 与 Cache 来源;
- 初始策略版本。
“临时 VM”不等于“不保留数据”。Transcript、Snapshot、Build Cache、Artifact 和供应商日志都可能比活动 VM 存活更久,必须逐条评审保留路径。
3. Bootstrap
Checkout 准确的基础 Commit,并在独立 Setup Policy 下安装依赖。
依赖安装会执行第三方代码,必须进入威胁模型:
- 要求 Lockfile;
- 固定 Registry 和 Mirror;
- 在可用时验证 Checksum 或签名;
- 任务不需要时阻止未评审 Lockfile 变化;
- 依赖安装期间不注入 Runtime Secret;
- 来源变化后失效缓存。
4. 执行
Agent Runtime 至少要具备:
- 有边界的文件系统写权限;
- 命令与工具策略;
- 显式网络出口;
- Run 级预算;
- 结构化事件采集;
- 取消传播。
仓库指令是有用上下文,但恶意源文件同样可以包含指令。信任顺序必须明确:平台策略和 Run Spec 高于仓库指令;仓库或外部内容永远无权授予新能力。
5. 验证
验收门禁应独立于 Agent 自己的结论运行:
- 必需测试和 Lint;
- 生成文件和 Lockfile 策略;
- 密钥与依赖扫描;
- 改动文件 Allowlist;
- Migration 与 API 兼容性检查;
- 确定性最终状态断言;
- 必要时的 UI 或运行时证据。
Agent 可以在预算内尝试修复失败门禁,但不能通过解释“为什么应该通过”来把门禁改成成功。
6. 交付
只允许 Push 到分配分支,并创建或更新审查 Artifact。基础分支继续执行普通仓库规则。Agent 不应绕过:
- Required Reviewer;
- CI;
- Signed Commit;
- Deployment Approval;
- Code Owner;
- Environment Protection。
7. 清理
撤销 Run Credential、停止进程、释放 Lease,只保留获批证据,并安排 Workspace 和 Snapshot 删除。清理本身应可观测、可重试。
身份:一次 Run,一个有边界 Principal
不能把开发者长期凭证复制进 Workspace。
源码托管身份
优先使用 Git App 或 Credential Broker,确保:
- 只能读取指定仓库;
- 只能 Push 到 Run 分支;
- 不能修改 Branch Protection;
- 不能批准或合并自己的改动;
- Agent Commit 可归因并签名;
- 凭证随 Run 到期。
GitHub 官方文档说明其 Cloud Agent 在临时 Actions 环境中工作,并围绕单一任务分支执行。Anthropic 则说明 Hosted Cloud Session 使用短期 Session Credential、通过代理访问 Git,并限制 Push 到当前工作分支。这些是有用的架构参照,但不能替代对实际套餐和配置的核验。
Cloud 与内部服务身份
在可行时使用 Workload Federation:
Run Attestation -> OIDC Token -> Cloud Role Exchange
-> 短期、Audience-scoped Credential
授权绑定:
- 组织与仓库;
- Run ID;
- 环境;
- 允许动作;
- 过期时间;
- Audience;
- 可选资源标签。
即使 Token 泄漏,也应无法离开该窄范围使用。
密钥:分离 Build、Runtime 与模型可见性
按暴露面分类:
| 密钥类型 | 示例 | 模型可见性 | 生命周期 |
|---|---|---|---|
| Build-only | 私有 Package Registry | Broker 时不可见 | Bootstrap |
| Runtime Tool | 测试 API Token | 尽量 Broker/脱敏 | 单次 Run |
| Deploy Approval | 生产发布 Token | 永不可见 | 外部门禁系统 |
| User Data Key | 解密生产记录 | 默认永不可见 | 避免签发 |
Redaction 只是纵深防御,不是隔离。进程可以在不打印原值的情况下转换或外泄密钥。优先使用 Proxy 代执行授权操作,不把原始 Credential 放进 VM 或模型上下文。
生产密钥绝不能出现在:
- Prompt;
- 仓库文件;
- 被 Commit 的
.env; - 无限制 Shell History;
- Demo Artifact;
- Agent 摘要。
网络出口本身就是授权面
联网 Agent 可以通过看似正常的请求外泄代码。Allowlist 会降低可达范围,但每个允许目的地仍是一条数据通道。
策略模式
| 模式 | 适用场景 |
|---|---|
| 禁用 | Hermetic Test 与预装依赖 |
| 仅 Proxy/Cache | 语言依赖与已知文档 |
| 严格 Allowlist | 已批准 API 与 Registry |
| 临时审批 | 有日志的例外目的地 |
| 无限制 | 敏感仓库应避免 |
OpenAI 公开了带允许、拒绝和需审批目的地的托管网络策略。Cursor 明确把 Prompt Injection 导致外泄列为 Cloud Agent 风险,并提供可配置 Egress。Anthropic 也说明 Cloud Session 默认限制网络访问,可配置 Domain Allowlist。
Domain 之外的控制
- 通过受控 Proxy 解析;
- 防止直接 IP 和其他协议绕过;
- 考虑 DNS Rebinding 与 Redirect;
- 分离只读文档站和可写 API;
- 限制请求大小和速率;
- 记录目的地、决策、工具和 Run ID;
- 适当扫描或分类出站 Payload;
- 拒绝 Metadata Service 和内部控制面。
Package Registry 必须特殊处理,因为下载 Package 会执行代码。
Prompt Injection:把上下文当数据
潜在注入来源包括:
- Issue 与 Pull Request 描述;
- 仓库文档和注释;
- 测试 Fixture;
- Package README 与 Install Script;
- 网页与搜索结果;
- Compiler Error 与工具输出;
- MCP 或 Plugin 返回。
控制必须是结构化的:
- 能力只来自策略,不能来自内容;
- 不可信文本要隔离并标记;
- 高风险工具需要独立授权判断;
- 注入发生后,Egress 与 Secret 仍被限制;
- 受保护文件和分支配置不可修改;
- 可疑序列产生证据并停止或升级。
Prompt Filter 不能成为唯一防线。应假设部分注入会被模型解释,并限制其实际后果。
Go 示例:Provision 前校验 Run Policy
下面的标准库示例拒绝宽泛网络、无范围写权限、缺失验证和自助合并。生产 Policy Engine 还应评估组织、仓库敏感度、任务类型和签名策略包。
package main
import (
"errors"
"fmt"
"path/filepath"
"strings"
"time"
)
type RunSpec struct {
Repository string
BaseCommit string
Branch string
WritableRoots []string
AllowedDomains []string
RequiredChecks []string
MaxDuration time.Duration
CanMerge bool
ProductionSecret bool
}
func Validate(spec RunSpec) error {
if spec.Repository == "" || spec.BaseCommit == "" || spec.Branch == "" {
return errors.New("repository, base commit, and branch are required")
}
if spec.CanMerge {
return errors.New("agent runs cannot merge their own changes")
}
if spec.ProductionSecret {
return errors.New("production secrets are not allowed")
}
if spec.MaxDuration <= 0 || spec.MaxDuration > 2*time.Hour {
return errors.New("run duration is outside policy")
}
if len(spec.WritableRoots) == 0 || len(spec.RequiredChecks) == 0 {
return errors.New("write scope and required checks must be explicit")
}
for _, root := range spec.WritableRoots {
clean := filepath.Clean(root)
if clean == "." || clean == "/" || strings.HasPrefix(clean, "..") {
return fmt.Errorf("unsafe writable root %q", root)
}
}
for _, domain := range spec.AllowedDomains {
if domain == "*" || strings.HasPrefix(domain, "*.") {
return fmt.Errorf("wildcard domain %q is not allowed", domain)
}
}
return nil
}
func main() {
spec := RunSpec{
Repository: "org/service",
BaseCommit: "4d2f7c1",
Branch: "agent/run-42",
WritableRoots: []string{"internal", "tests"},
AllowedDomains: []string{"proxy.example.test"},
RequiredChecks: []string{"go test ./...", "go vet ./..."},
MaxDuration: 45 * time.Minute,
}
fmt.Println(Validate(spec))
}
Runtime Enforcement 必须与这份校验一致。只有当文件系统、Proxy、Credential Broker 和 Git Provider 都执行它时,Run Spec 字段才是真正的安全控制。
验收证据,而不是 Agent 自证
Evidence Bundle
每次 Run 都应返回:
run_id
task_hash 与可信指令版本
policy_version
environment_image_digest
base_commit 与 final_commit
Credential 签发与撤销
命令、时间戳与退出码
网络 Allow/Deny/Approval 决策
改动文件与 Diff Hash
测试、扫描与最终状态检查
Artifact URI 与 Hash
未解决失败和 Degraded 状态
分支与 Pull Request 标识
Teardown 状态
根据威胁模型,使用 Append-only Storage、签名 Statement 或平台审计控制保护完整性。
证据层级
| 证据 | 能证明什么 |
|---|---|
| Agent 摘要 | Agent 声称做了什么 |
| Terminal Transcript | Shell 返回了什么文字 |
| Exit Code | 进程是否报告成功 |
| Test Report | 哪些测试执行及其结果 |
| Artifact Hash | Artifact 身份 |
| Final-state Assertion | 必需状态是否存在 |
| 独立 CI Run | Agent Workspace 外的验证 |
| Reviewer Approval | 可问责人工判断 |
单一证据无法证明整体正确。应按任务风险组合证据包。
取消、超时与恢复
远程 Run 一定会失败:供应商超时、VM 消失、测试卡死、Base Branch 前进,或人工取消。
必需语义
- 取消传播到子进程和工具调用;
- 即使 Teardown 部分失败,也撤销 Credential;
- Lease 和预算由服务端到期;
- Checkpoint 区分安全重放和外部副作用;
- 恢复后的 Run 记录新 Execution Attempt;
- Base Commit 过期时触发 Rebase 或 Restart Policy;
- 重复投递不会创建两个分支或两次外部变更;
- 部分 Artifact 标为 Incomplete,而不是 Passed。
如果某个步骤已发消息、改数据库、发布 Package 或修改 Cloud Infrastructure,除非操作有 Idempotency Key 且已验证状态,否则不能自动重试。
任务选择与自主等级
| 任务 | 默认模式 | 原因 |
|---|---|---|
| 文档修复 | Branch-only 自主执行 | Diff 客观且爆炸半径小 |
| 聚焦补测试 | 自主执行 + CI | 验收可复现 |
| 依赖更新 | 限制 Egress + Lockfile 评审 | 供应链代码执行 |
| Auth 重构 | 先计划 + 人工 Checkpoint | 高安全影响 |
| Schema Migration | Sandbox 模拟 + 审批 | 不可逆数据风险 |
| 生产故障 | 监督执行,先只读 | 在线系统不确定性 |
| 多仓发布 | 编排工作流,不使用单个宽权限 Agent | 身份与回滚复杂 |
自主程度应由风险和可验证性决定,而不是模型语气有多自信。
运营指标
采用率和 PR 数量不能证明价值,应衡量:
- Eligible Task 中被接受的任务比例;
- First-pass Gate Rate;
- 人工修正时间;
- Escaped Defect 与 Rollback Rate;
- P50/P95 运行与排队时间;
- 每个接受变更的计算、模型和环境成本;
- 取消与基础设施失败率;
- Prompt Injection 与 Policy Denial 事件;
- Reviewer Backlog 与可问责审批时长;
- 证据和 Teardown 完整的 Run 比例。
必须与同类任务的旧工作流比较。生成更多 PR 可能因为审查需求或缺陷风险上升而降低真实吞吐。
发布检查清单
- 每次 Run 都有不可变范围、Base Commit、策略和预算。
- Workspace 隔离与保留 Snapshot 已记录。
- Git 和 Cloud 身份短期且 Run-scoped。
- 默认不存在生产凭证。
- Egress 被禁用或显式 Allowlist,并完整记录。
- 仓库和外部内容无法授予新能力。
- 受保护文件、分支规则和合并控制由外部强制执行。
- 验收门禁独立于 Agent 自我评估运行。
- 已测试取消、过期 Base、重复任务和 Teardown 失败。
- 证据保留与删除符合仓库敏感度。
- 高风险改动由人工或可问责策略 Owner 批准。
- 指标比较接受结果,而不是生成活动。
常见问题
Cloud Agent 比本地 Agent 更安全吗?
两者风险不同。Run 级隔离与 Egress Policy 可能强于开发者电脑;Cloud Storage、无人值守执行和远程凭证又引入新风险。应比较实际控制,而不是运行位置。
Draft Pull Request 是否足以构成人在回路?
只有当 Branch Protection、Required Check、Reviewer 和 Deployment Approval 都不可绕过时才足够。Draft 标签本身只是展示状态。
Agent 是否应该联网?
只有任务价值足以支持这条通道时才应联网。优先无网络、可信缓存或严格 Allowlist,并把依赖访问与任意浏览分开。
Secret Redaction 能防止外泄吗?
不能。Redaction 只能防止部分原值出现在日志或模型上下文,无法阻止进程使用、转换或发送 Credential。应最小化签发并使用 Broker。
应并行运行多少个 Cloud Agent?
并发应由环境预算、冲突域、Reviewer 容量和任务独立性决定。无限并发会制造队列、冲突分支和无法审查的输出。
一手资料
- OpenAI,在 OpenAI 内部安全运行 Codex:Sandbox、审批、托管 Egress、Credential Storage、规则与 Agent-aware Telemetry。
- GitHub,About GitHub Copilot Cloud Agent:临时 Actions 环境、分支执行、自定义、限制和 PR 结果指标。
- Cursor,Cloud Agents Security Overview:生命周期、Run 隔离、身份、保留、Egress、Secret、Prompt Injection 控制与审计。
- Anthropic,Claude Code Security:权限架构、Prompt Injection 防御、Sandbox,以及 Hosted Cloud Session 的身份和分支限制。
- AI Code Review 自动化流水线:代码生成后的证据化审查门禁。
关联学习路径
- 如何构建 AI Agent:Coding Agent 底层的控制循环、工具、状态与评测。
- 多 Agent 系统:多个 Run 协作时的协调和失败边界。
- Model Context Protocol:仍需应用层授权的工具传输协议。
- Context Engineering:可信指令、仓库上下文与证据选择。
总结
Cloud Coding Agent 适合范围明确、环境可复现、验收客观,且产出停留在可回滚分支的任务。其价值并不是移除人,而是把执行迁移到受控、可观测运行时,同时保留可问责审批。
在扩大自主程度前,应先设计身份、Egress、Secret、分支限制、证据、取消和清理。缺少这些控制时,所谓“后台执行”只是套着有说服力界面的无人值守代码执行。