文档索引
在此处获取完整文档索引:https://code.claude.com/docs/llms.txt 使用此文件发现所有可用页面,然后再进一步探索。
安全部署 AI 智能体
通过隔离、凭据管理和网络控制来保护 Claude Code 和 Agent SDK 部署的指南
Claude Code 和 Agent SDK 是强大的工具,可以代表你执行代码、访问文件和与外部服务交互。与任何具有这些功能的工具一样,深思熟虑地部署它们可以确保你在获得收益的同时保持适当的控制。
与遵循预定代码路径的传统软件不同,这些工具根据上下文和目标动态生成操作。这种灵活性使它们非常有用,但也意味着它们的行为可能受到所处理内容的影响:文件、网页或用户输入。这有时被称为提示注入。例如,如果某个代码仓库的 README 包含不寻常的指令,Claude Code 可能会以操作者未预料到的方式将这些内容纳入其操作中。本指南涵盖了减少此类风险的实用方法。
好消息是,保护智能体部署并不需要特殊的基础设施。适用于运行任何半可信代码的原则同样适用于这里:隔离、最小权限和纵深防御。Claude Code 包含多项安全功能来帮助解决常见问题,本指南将详细介绍这些功能以及针对需要额外加固的用户的选项。
并非每个部署都需要最高级别的安全性。开发者在笔记本电脑上运行 Claude Code 的要求与在多租户环境中处理客户数据的公司不同。本指南提供了从 Claude Code 内置安全功能到加固生产架构的各种选项,以便你选择适合自身情况的方案。
威胁模型
智能体可能由于提示注入(嵌入在处理内容中的指令)或模型错误而执行非预期操作。Claude 模型经过设计以抵御此类攻击;请参阅模型概述和你部署的模型的系统卡以了解评估详情。
尽管如此,纵深防御仍然是最佳实践。例如,如果智能体处理了一个恶意文件,该文件指示它将客户数据发送到外部服务器,网络控制可以完全阻止该请求。
内置安全功能
Claude Code 包含多项安全功能,可解决常见问题。有关完整详情,请参阅安全文档。
- 权限系统:每个工具和 bash 命令都可以配置为允许、阻止或提示用户批准。使用 glob 模式创建规则,例如"允许所有 npm 命令"或"阻止任何带有 sudo 的命令"。组织可以设置适用于所有用户的策略。请参阅权限。
- 命令解析用于权限控制:在执行 bash 命令之前,Claude Code 将其解析为 AST 并将结果与你的权限规则进行匹配。无法干净解析的命令,或不匹配任何允许规则的命令,需要明确批准。一小部分构造(如
eval)无论允许规则如何都需要批准。这是一个权限门控,而非沙箱;它不会从目标路径或效果推断命令是否危险。 - 网页搜索摘要:搜索结果会被摘要处理,而不是直接将原始内容传入上下文,从而降低了恶意网页内容导致提示注入的风险。
- 沙箱模式:Bash 命令可以在限制文件系统和网络访问的沙箱环境中运行。有关详情,请参阅沙箱文档。
安全原则
对于需要在 Claude Code 默认设置之外进行额外加固的部署,这些原则指导可用的选项。
安全边界
安全边界将具有不同信任级别的组件分开。对于高安全性部署,你可以将敏感资源(如凭据)放置在包含智能体的边界之外。如果智能体环境出现问题,边界之外的资源仍然受到保护。
例如,与其让智能体直接访问 API 密钥,你可以在智能体环境之外运行一个代理,将密钥注入请求中。智能体可以进行 API 调用,但永远看不到凭据本身。这种模式对于多租户部署或处理不受信任的内容非常有用。
最小权限
在需要时,你可以将智能体限制为仅其特定任务所需的功能:
| 资源 | 限制选项 |
|---|---|
| 文件系统 | 仅挂载所需目录,优先使用只读 |
| 网络 | 通过代理限制到特定端点 |
| 凭据 | 通过代理注入而非直接暴露 |
| 系统能力 | 在容器中丢弃 Linux 能力 |
纵深防御
对于高安全性环境,叠加多层控制可以提供额外的保护。选项包括:
- 容器隔离
- 网络限制
- 文件系统控制
- 代理处的请求验证
正确的组合取决于你的威胁模型和运维需求。
隔离技术
不同的隔离技术在安全强度、性能和运维复杂度之间提供不同的权衡。
在所有这些配置中,Claude Code(或你的 Agent SDK 应用程序)运行在隔离边界内(沙箱、容器或虚拟机)。下面描述的安全控制限制了智能体从该边界内可以访问的内容。
| 技术 | 隔离强度 | 性能开销 | 复杂度 |
|---|---|---|---|
| 沙箱运行时 | 良好(安全默认值) | 非常低 | 低 |
| 容器(Docker) | 取决于配置 | 低 | 中等 |
| gVisor | 优秀(配置正确时) | 中/高 | 中等 |
| 虚拟机(Firecracker、QEMU) | 优秀(配置正确时) | 高 | 中/高 |
沙箱运行时
对于无需容器的轻量级隔离,sandbox-runtime 在操作系统级别强制执行文件系统和网络限制。
主要优点是简单:无需 Docker 配置、容器镜像或网络设置。代理和文件系统限制是内置的。你只需提供一个指定允许的域和路径的设置文件。
工作原理:
- 文件系统:使用操作系统原语(Linux 上的
bubblewrap,macOS 上的sandbox-exec)限制对已配置路径的读/写访问 - 网络:移除网络命名空间(Linux)或使用 Seatbelt 配置文件(macOS)将网络流量路由到内置代理
- 配置:基于 JSON 的域和文件系统路径允许列表
设置:
npm install @anthropic-ai/sandbox-runtime
然后创建一个指定允许路径和域的配置文件。
安全注意事项:
-
同主机内核:与虚拟机不同,沙箱进程共享主机内核。内核漏洞理论上可以实现逃逸。对于某些威胁模型来说这是可以接受的,但如果你需要内核级隔离,请使用 gVisor 或单独的虚拟机。
-
无 TLS 检查:代理根据客户端提供的主机名对域进行允许列表检查,不会终止或检查加密流量。在沙箱内运行的代码可能使用域前置或类似技术来访问允许列表之外的主机。如果你的威胁模型需要更强的保证,请配置 TLS 终止代理。有关更多详情,请参阅沙箱安全限制。另外,如果智能体对允许的域拥有宽松的凭据,请确保它无法使用该域触发其他网络请求或泄露数据。
对于许多单人开发者和 CI/CD 用例,sandbox-runtime 以最少的设置显著提高了安全基线。下面的章节介绍了需要更强隔离的部署的容器和虚拟机方案。
容器
容器通过 Linux 命名空间提供隔离。每个容器拥有自己的文件系统、进程树和网络栈视图,同时共享主机内核。
安全加固的容器配置可能如下所示:
docker run \
--cap-drop ALL \
--security-opt no-new-privileges \
--security-opt seccomp=/path/to/seccomp-profile.json \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
--tmpfs /home/agent:rw,noexec,nosuid,size=500m \
--network none \
--memory 2g \
--cpus 2 \
--pids-limit 100 \
--user 1000:1000 \
-v /path/to/code:/workspace:ro \
-v /var/run/proxy.sock:/var/run/proxy.sock:ro \
agent-image
以下是每个选项的作用:
| 选项 | 用途 |
|---|---|
--cap-drop ALL | 移除 Linux 能力(如 NET_ADMIN 和 SYS_ADMIN),这些能力可能被用于权限提升 |
--security-opt no-new-privileges | 防止进程通过 setuid 二进制文件获取权限 |
--security-opt seccomp=... | 限制可用的系统调用;Docker 默认阻止约 44 个,自定义配置文件可以阻止更多 |
--read-only | 使容器的根文件系统不可变,防止智能体持久化更改 |
--tmpfs /tmp:... | 提供可写的临时目录,在容器停止时清除 |
--network none | 移除所有网络接口;智能体通过下面挂载的 Unix 套接字进行通信 |
--memory 2g | 限制内存使用以防止资源耗尽 |
--pids-limit 100 | 限制进程数量以防止 fork 炸弹 |
--user 1000:1000 | 以非 root 用户身份运行 |
-v ...:/workspace:ro | 以只读方式挂载代码,使智能体可以分析但不能修改。避免挂载敏感的主机目录,如 ~/.ssh、~/.aws 或 ~/.config |
-v .../proxy.sock:... | 挂载连接到容器外部运行的代理的 Unix 套接字(见下文) |
Unix 套接字架构:
使用 --network none 时,容器完全没有网络接口。智能体与外界通信的唯一方式是通过挂载的 Unix 套接字,该套接字连接到主机上运行的代理。此代理可以强制执行域允许列表、注入凭据并记录所有流量。
这与 sandbox-runtime 使用的架构相同。即使智能体通过提示注入被攻陷,它也无法将数据泄露到任意服务器。它只能通过代理进行通信,代理控制哪些域可达。有关更多详情,请参阅 Claude Code 沙箱化博客文章。
额外加固选项:
| 选项 | 用途 |
|---|---|
--userns-remap | 将容器 root 映射到非特权主机用户;需要守护进程配置但可以限制容器逃逸造成的损害 |
--ipc private | 隔离进程间通信以防止跨容器攻击 |
gVisor
标准容器共享主机内核:当容器内的代码进行系统调用时,它直接传递到运行主机的同一内核。这意味着内核漏洞可能允许容器逃逸。gVisor 通过在用户空间拦截系统调用来解决这个问题,使其在到达主机内核之前被拦截,实现了自己的兼容层来处理大多数系统调用,而不涉及真实内核。
如果智能体运行恶意代码(可能是由于提示注入),该代码在容器内运行并可能尝试内核漏洞利用。使用 gVisor 时,攻击面要小得多:恶意代码需要首先利用 gVisor 的用户空间实现,并且对真实内核的访问有限。
要在 Docker 中使用 gVisor,安装 runsc 运行时并配置守护进程:
// /etc/docker/daemon.json
{
"runtimes": {
"runsc": {
"path": "/usr/local/bin/runsc"
}
}
}
然后使用以下命令运行容器:
docker run --runtime=runsc agent-image
性能注意事项:
| 工作负载 | 开销 |
|---|---|
| CPU 密集型计算 | 约 0%(无系统调用拦截) |
| 简单系统调用 | 慢约 2 倍 |
| 文件 I/O 密集型 | 对于频繁的 open/close 模式慢 10-200 倍 |
对于多租户环境或处理不受信任的内容时,额外的隔离通常值得付出性能开销。
虚拟机
虚拟机通过 CPU 虚拟化扩展提供硬件级隔离。每个虚拟机运行自己的内核,创建强大的边界。客户内核中的漏洞不会直接危及主机。然而,虚拟机并不自动比 gVisor 等替代方案"更安全"。虚拟机的安全性在很大程度上取决于虚拟机管理器和设备模拟代码。
Firecracker 专为轻量级微虚拟机隔离设计。它可以在 125 毫秒内启动虚拟机,内存开销不到 5 MiB,通过去除不必要的设备模拟来减少攻击面。
使用此方法时,智能体虚拟机没有外部网络接口。相反,它通过 vsock(虚拟套接字)进行通信。所有流量通过 vsock 路由到主机上的代理,代理在转发请求之前强制执行允许列表并注入凭据。
云部署
对于云部署,你可以将上述任何隔离技术与云原生网络控制结合使用:
- 在没有互联网网关的私有子网中运行智能体容器
- 配置云防火墙规则(AWS 安全组、GCP VPC 防火墙)以阻止除代理之外的所有出口流量
- 运行代理(如带有
credential_injector过滤器的 Envoy)来验证请求、强制执行域允许列表、注入凭据并转发到外部 API - 为智能体的服务账户分配最小的 IAM 权限,在可能的情况下将敏感访问通过代理路由
- 在代理处记录所有流量以用于审计
凭据管理
智能体通常需要凭据来调用 API、访问仓库或与云服务交互。挑战在于提供这种访问而不暴露凭据本身。
代理模式
推荐的方法是在智能体安全边界之外运行代理,将凭据注入到传出请求中。智能体发送不带凭据的请求,代理添加凭据,然后将请求转发到目的地。
这种模式有几个好处:
- 智能体永远看不到实际的凭据
- 代理可以强制执行允许的端点列表
- 代理可以记录所有请求以用于审计
- 凭据存储在一个安全位置,而不是分发到每个智能体
配置 Claude Code 使用代理
Claude Code 支持两种方法来通过代理路由采样请求:
选项 1:ANTHROPIC_BASE_URL(简单但仅适用于采样 API 请求)
export ANTHROPIC_BASE_URL="http://localhost:8080"
这告诉 Claude Code 和 Agent SDK 将采样请求发送到你的代理,而不是直接发送到 Claude API。你的代理接收明文 HTTP 请求,可以检查和修改它们(包括注入凭据),然后转发到真正的 API。
选项 2:HTTP_PROXY / HTTPS_PROXY(系统级)
export HTTP_PROXY="http://localhost:8080"
export HTTPS_PROXY="http://localhost:8080"
Claude Code 和 Agent SDK 遵循这些标准环境变量,将所有 HTTP 流量通过代理路由。对于 HTTPS,代理创建加密的 CONNECT 隧道:它无法在没有 TLS 拦截的情况下查看或修改请求内容。
实现代理
你可以构建自己的代理或使用现有的:
- Envoy Proxy:生产级代理,带有用于添加认证头的
credential_injector过滤器 - mitmproxy:用于检查和修改 HTTPS 流量的 TLS 终止代理
- Squid:带有访问控制列表的缓存代理
- LiteLLM:具有凭据注入和速率限制的 LLM 网关
其他服务的凭据
除了从 Claude API 进行采样外,智能体通常还需要对其他服务进行认证访问,如 git 仓库、数据库和内部 API。有两种主要方法:
自定义工具
通过 MCP 服务器或自定义工具提供访问,将请求路由到在智能体安全边界之外运行的服务。智能体调用该工具,但实际的认证请求在外部发生。工具调用代理,代理注入凭据。
例如,一个 git MCP 服务器可以从智能体接受命令,但将它们转发到主机上运行的 git 代理,该代理在联系远程仓库之前添加认证。智能体永远看不到凭据。
优点:
- 无需 TLS 拦截:外部服务直接进行认证请求
- 凭据留在外部:智能体只看到工具接口,而不是底层凭据
流量转发
对于 Claude API 调用,ANTHROPIC_BASE_URL 允许你将请求路由到代理,代理可以以明文形式检查和修改它们。但对于其他 HTTPS 服务(GitHub、npm 注册表、内部 API),流量通常是端到端加密的。即使你通过 HTTP_PROXY 将其路由到代理,代理也只能看到不透明的 TLS 隧道,无法注入凭据。
要修改任意服务的 HTTPS 流量而不使用自定义工具,你需要一个 TLS 终止代理来解密流量、检查或修改它,然后在转发之前重新加密。这需要:
- 在智能体容器之外运行代理
- 在智能体的信任存储中安装代理的 CA 证书(使智能体信任代理的证书)
- 配置
HTTP_PROXY/HTTPS_PROXY通过代理路由流量
此方法可以处理任何基于 HTTP 的服务,无需编写自定义工具,但增加了证书管理的复杂性。
请注意,并非所有程序都遵循 HTTP_PROXY/HTTPS_PROXY。大多数工具(curl、pip、npm、git)都遵循,但有些可能会绕过这些变量直接连接。例如,Node.js 的 fetch() 默认忽略这些变量;在 Node 24+ 中你可以设置 NODE_USE_ENV_PROXY=1 来启用支持。要获得全面覆盖,你可以使用 proxychains 来拦截网络调用,或配置 iptables 将出站流量重定向到透明代理。
透明代理在网络级别拦截流量,因此客户端不需要配置使用它。常规代理需要客户端显式连接并使用 HTTP CONNECT 或 SOCKS。透明代理(如 Squid 或处于透明模式的 mitmproxy)可以处理原始重定向的 TCP 连接。
两种方法仍然需要 TLS 终止代理和受信任的 CA 证书。它们只是确保流量确实到达代理。
文件系统配置
文件系统控制决定了智能体可以读取和写入哪些文件。
只读代码挂载
当智能体需要分析代码但不修改时,以只读方式挂载目录:
docker run -v /path/to/code:/workspace:ro agent-image
即使是对代码目录的只读访问也可能暴露凭据。挂载前应排除或清理的常见文件:
| 文件 | 风险 |
|---|---|
.env, .env.local | API 密钥、数据库密码、密钥 |
~/.git-credentials | Git 密码/令牌(明文) |
~/.aws/credentials | AWS 访问密钥 |
~/.config/gcloud/application_default_credentials.json | Google Cloud ADC 令牌 |
~/.azure/ | Azure CLI 凭据 |
~/.docker/config.json | Docker 注册表认证令牌 |
~/.kube/config | Kubernetes 集群凭据 |
.npmrc, .pypirc | 包注册表令牌 |
*-service-account.json | GCP 服务账户密钥 |
*.pem, *.key | 私钥 |
考虑仅复制所需的源文件,或使用 .dockerignore 风格的过滤。
可写位置
如果智能体需要写入文件,根据你是否希望更改持久化,有几种选择:
对于容器中的临时工作区,使用 tmpfs 挂载,它们仅存在于内存中,并在容器停止时清除:
docker run \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
--tmpfs /workspace:rw,noexec,size=500m \
agent-image
如果你想在持久化之前审查更改,覆盖文件系统允许智能体写入而不修改底层文件。更改存储在单独的层中,你可以检查、应用或丢弃该层。对于完全持久化的输出,挂载专用卷,但将其与敏感目录分开。