Skip to content
预计 1 分钟右侧目录可快速定位

Container 为什么不是完整 Sandbox:Resource、Credential 与 Security Boundary ​

前置:Sandbox 该隔离什么:Process、Filesystem 与 Network
核心问题:Container 已经隔离进程后,为什么还要限制资源和 Credential,真正的 Sandbox 安全边界还缺什么?

一个 Container 仍然可能拥有过大的能力 ​

假设 Coding Agent 在普通容器里执行生成代码,但容器同时具备:

text
root
+ host Docker socket
+ writable host volume
+ unrestricted network egress
+ long-lived cloud credential

即使进程被“装进容器”,它仍可能控制宿主容器、读取不该读的文件或把凭证发到外部。Container 只提供隔离机制的一部分,真正的 Sandbox 是一组按 Threat Model 组合起来的限制。

Resource Limits:限制失控代码最多消耗多少资源 ​

CPU、memory、pid、disk、execution time 等限制控制的是资源 blast radius。例如 fork bomb 应被 PID limit 阻断,大量日志不能无限吃满磁盘,CPU-heavy Tool 不能长期拖死同宿主的 Worker。

Resource Limit 解决的是“最多能耗多少”,不解决“能访问什么”。一个只给 512MB 内存的进程,仍然可能拿着高权限 token 删除生产资源。

Credential Isolation:限制它代表谁、能调用什么 ​

Model Context、workspace 文件和普通日志都不应该成为 Secret Store。更安全的流程是:

text
Model proposes ToolCall
→ Runtime validates tool / tenant / scope / approval
→ Executor requests short-lived credential
→ credential injected only at execution boundary
→ Tool executes
→ credential expires / is discarded

例如代码搜索 Tool 只需要 repo read token;生产部署 Tool 只有在审批后才获取短期 deployment credential。模型通常只需要知道“存在这个 capability”,不需要看到 token 字符串本身。

🔍 源码对照:认证完成状态与 Agent Resume 分离 ​

精确定位

ts
class AuthWaitRegistry {
  register(wait) {
    waits.set(connectorKey(wait), {
      agentId: wait.agentId,
      serverId: wait.serverId,
      expiresAtMs: now() + ttl,
    })
  }

  take(completion) {
    const wait = matchByServerIdOrName(completion)
    if (wait) waits.delete(wait.key)
    return wait?.agentId ?? null
  }
}
ts
function resolveAuthCompletion(completion) {
  const waitingAgent = waits.take(completion)
  if (completion.outcome === "cancelled") return

  const agentId = completion.requestingAgentId ?? waitingAgent
  if (agentId) resumeAfterMcpAuth(agentId, completion.serverName)
}

对照理解

  • Auth flow 被建模成可等待、可过期、可匹配 completion 的 Runtime state,而不是把“请登录”文本交给模型自己记住。
  • 完成事件只携带 server/account identity,并触发对应 Agent Resume;认证流程状态与 user-visible Turn 生命周期是两个 owner。
  • 这里没有证据表明 host-secret-store.ts 是 OAuth token vault;该文件实际主要维护 host machine identity。Credential value 如何安全存储仍应以正式 auth/secret 实现和协议规范为准。

Security Sandbox 要同时限制多种能力 ​

一个可执行 Agent 的实际安全边界至少要看:

text
process privilege
filesystem mounts
network egress
syscall / device access
CPU / memory / pid / time
credential exposure

Container 的 namespace/cgroup 可以支撑其中一部分,但 privileged、Docker socket、宽泛 volume、任意出网或完整云凭据都会重新扩大权限面。高风险场景还可能需要更强的 VM/微虚机隔离。

因此判断“够不够安全”不能问:

是否用了 Docker?

而要问:

这个执行环境在最坏情况下到底能碰到哪些资源、网络和凭证?

Failure Modes ​

把资源限制当成权限控制 ​

症状: Sandbox 有 CPU/memory limit,但进程仍能读取宿主敏感目录或使用高权限 credential。

处理: Resource、filesystem/network capability 和 credential isolation 分开设计;任何一层都不能替代其他层。

把完整 Secret 放进 Prompt / Workspace ​

后果: Prompt injection、Tool output、日志或 artifact 都可能把 Secret 带出边界。

处理: Executor 按需获取短期最小 scope credential;模型和普通 workspace 只看到 capability/reference。

如何验证 ​

场景必须成立
Tool 触发 fork bombPID/resource limit 生效,宿主仍可用
Read-only Tool 尝试获取 deploy credential被 credential policy 拒绝
Sandbox 尝试访问未授权公网地址egress policy 阻断
Prompt 要求打印环境中的 Secret模型/普通 Tool 环境中不存在可直接读取的完整 credential

关联源码 ​

自测 ​

  1. Container 已隔离文件系统,但内部仍能拿到宿主云凭证。为什么“在容器里”不等于安全 Sandbox?
  2. CPU/memory/pid resource limit 与 credential boundary 分别阻止什么类型的风险?

Sources ​

AI Engineering · Agent · Harness · Backend Systems