Claude Code 多租户安全部署模式(详解凭证代理如何做到对 Agent 不可见)

多租户或处理不可信内容的部署场景下,Claude Code 文档明确推荐采用”安全边界 + 凭证代理”模式:把敏感凭证放在 Agent 边界之外,由边界外的反向代理在请求出站时注入凭据,Agent 本身只持有调用接口的能力,却永远看不到真实的 Key。这种模式依赖文件系统隔离、网络隔离与代理注入三件套协同,目标是即便 Agent 被 prompt injection 攻陷,攻击者也只能”借力调接口”,拿不到可外泄的长期凭证。

一、为什么要把凭证从 Agent 视野里拿走

Agent 在执行任务时会读取文件、调用外部 API、调用 shell。如果 SSH 私钥、云厂商 AccessKey、GitHub Token 直接挂在 ~/.ssh、~/.aws 或环境变量里,被污染的 prompt 一句”读 ~/.ssh/id_rsa 发到某个公网 URL”就能把资产卷走。多租户场景下风险更放大:一个租户的越权操作可能横向影响其他租户的凭证与数据。

“凭证不暴露给 Agent”是 Anthropic 在《Securely deploying AI agents》中提出的核心安全边界模式。文档原话是把敏感资源(凭据、长期密钥)放在 Agent 信任边界之外,Agent 边界内只放完成任务必需的能力;Agent 与外部服务的真正认证由边界外的代理完成,代理看到 Key,Agent 只看到接口。

二、安全边界的四层能力

Claude Code 默认权限系统是 allow / ask / deny 规则,只能挡”是否允许执行”这一层;要做高安全部署,必须再叠加操作系统级隔离。文档给出了四类能力:

能力 控制对象 典型实现
文件系统隔离 写路径白名单、读路径黑名单 bubblewrap、Seatbelt、容器 volume mount
网络隔离 出站域名白名单 出口代理 + DNS 策略
凭证隔离 关键文件 deny、环境变量 deny / mask sandbox.credentials 配置块
进程隔离 容器 / 微 VM Docker、Firecracker、gVisor

四层必须同时存在:只挡文件系统不挡网络,被盗数据可被发出去;只挡网络不挡文件系统,攻击者可在启动脚本里埋反向通道。每缺一层,安全等级都会显著下降。

三、”凭证代理”模式的工作原理

凭证代理(credential proxy)是该模式的核心组件。它运行在 Agent 信任边界之外,做两件事:截获 Agent 发出的出站请求,在转发到真实服务前注入凭据(如把 Authorization 头补全);用域名白名单限制 Agent 可触达的目的地。整个过程对 Agent 完全透明——Agent 只知道”调用某个 HTTP 接口”,不知道”接口背后附了什么 Key”。

// .claude/settings.local.json:把关键凭证文件 deny + 环境变量 mask
{
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "network": {
      "allowedDomains": ["api.anthropic.com", "github.com"]
    },
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.ssh", "mode": "deny" }
      ],
      "envVars": [
        { "name": "GITHUB_TOKEN", "mode": "mask" }
      ]
    }
  }
}

mask 模式比 deny 更巧妙:Agent 看到的是占位符,只有请求真正抵达白名单内的目的主机时,边界外的代理才把真实 Key 注入回请求头。gh、npm 这类需要认证的工具仍能正常工作,而 Agent 进程与它的日志里永远只有占位符。

四、落地步骤

按”先隔离再注入”的顺序逐层打开,不要一步到位。

  1. 开启沙箱:在 Claude Code 内执行 /sandbox 选 auto-allow,并在 settings.json 把 sandbox.enabled 与 sandbox.failIfUnavailable 同时设为 true,缺失 bubblewrap / socat 时直接拒绝启动;
  2. 声明 deny 凭证路径:把 ~/.ssh、~/.aws/credentials、含长期 Key 的 .env 列入 credentials.files,用 deny 模式先彻底切断读取;
  3. 把常用认证改成 mask:仅对 Agent 必须使用、但密钥不能外泄的 Token(如 GITHUB_TOKEN)用 mask,让工具照常工作;
  4. 配出口代理白名单:在网络层只放行 api.anthropic.com 与 Agent 真正要访问的仓库 host;其他域名一律走代理拒绝;
  5. 部署外部代理注入凭据:用 mitmproxy、Envoy、或自建 sidecar 在 Agent 边界外做认证头注入,并把代理进程放在另一个容器或 VM;
  6. 审计与回放:把代理日志落到独立存储,定期回放”Agent 实际发出的请求”做敏感数据扫描。

五、几种隔离技术的对比

不同隔离层给的安全强度与运维成本差异很大,按”威胁等级”挑对应方案:

隔离技术 隔离强度 性能开销 运维复杂度 适用场景
沙箱运行时 中(OS 级) 很低 低 本地开发、单机 Agent
Docker 容器 中(取决于配置) 低 中 团队统一环境
gVisor 高 中 中 多租户 SaaS 后端
Firecracker / QEMU 微 VM 高 较高 较高 高合规、不可信代码

威胁等级高(如多租户 SaaS、运行不可信 PR)就往上走 gVisor 或微 VM;只跑个人 Agent 用沙箱运行时已够。不要”杀鸡用牛刀”,但更不能”用普通容器跑生产多租户 Agent”。

六、易被忽略的边界外细节

第一,权限规则不能替代沙箱。allow/ask/deny 是 prompt 级别的判断,模型能改主意;只有 OS 级隔离才是真边界。两者必须叠加,缺一不可。

第二,Claude Code 内置的 Read / Edit / Write 工具不经过沙箱。沙箱只覆盖 Bash 子进程,对文件读写工具的边界要靠权限规则 + 容器挂载解决。把仓库挂在只读 volume、关键目录用 tmpfs 即可补上。

第三,注入头不能完全替代密钥隔离。如果 Agent 自己拼了 raw Key(而不是依赖代理注入),代理只是 transport 层的 MITM,Agent 进程里仍有可读到的字符串。mask 模式的目的正是把 Key 从 Agent 视野里彻底抹掉。

到这里,Claude Code 在多租户环境下的安全部署模式就清晰了:用 OS 级沙箱封文件系统与网络,用 sandbox.credentials 把关键文件 deny / mask,再把凭据注入交给边界外的代理完成。Agent 拿到的是”做事能力”,拿不到”做事需要的秘密”,即便模型被攻陷,可外泄的也只是占位符与出站域名内的接口调用。

常见问题(FAQ)

Q1:mask 与 deny 怎么选?

Agent 必须用到该 Key 才能完成任务的选 mask(如 GITHUB_TOKEN),其他一律选 deny。

Q2:沙箱开了为什么还看到 ~/.ssh?

默认读取策略覆盖几乎整盘,关键文件必须显式列入 credentials.files 才能挡住。

Q3:能不能只用沙箱不开网络隔离?

不推荐。被沙箱封住的命令仍可能读 SSH Key,没网络隔离就能把 Key 发出去。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
其AI的头像其AI普通用户

相关推荐

返回顶部