Claude Code VS Code安全部署指南
详细梳理Claude Code的认证、环境、权限三层隔离;提供可复现的诊断检查清单。
详细梳理Claude Code的认证、环境、权限三层隔离;提供可复现的诊断检查清单。
AL
Agent Lab Journal
Guides
Glossary
实践指南 · 中级
Claude Code 扩展、终端中的 claude 命令和活跃登录是独立的三层。一个界面中的登录或聊天回复成功,并不证明另一个界面使用了相同的可执行文件、账户、环境或权限模式。本指南将首次设置转化为一个受控实验:识别每个组件、在空项目中测试访问、记录实际发生的情况,只有这样才能打开真实的仓库。
难度: 中级
阅读和设置: 40 分钟
结果: 配置记录和诊断报告
最后,你将拥有一个一次性本地项目和一份配置记录,包含:
VS Code 版本和构建信息;
Claude Code 扩展的完整标识符和安装版本;
终端 CLI 的绝对路径和报告的版本;
启动每个进程的 shell 和环境;
身份验证方法,不包含凭证或令牌;
初始权限或访问模式;
读取、写入、命令执行和项目边界检查的观察结果;
用于区分扩展、CLI、身份验证和权限故障的诊断证据。
AI 智能体可以做的不仅仅是生成文本:它可能读取文件、编辑文件并调用本地或远程工具。因此,"聊天工作了"不足以作为安全测试。重要的问题是在当前会话中,智能体实际上能执行哪些操作。
不要将示例版本复制到你的记录中。产品发行版本和接口会改变。从你测试的安装中获取每个版本和能力,并将下面的命令视为探针而不是承诺的输出。
开发者从 VS Code 扩展视图安装了 Claude Code 扩展。稍后,他们打开集成终端并安装或调用一个名为 claude 的命令。扩展显示登录屏幕,而终端命令独立请求身份验证。
登录后,扩展可以回答关于打开的文件夹的问题,但终端命令失败。在另一台机器上,反过来了:CLI 工作而扩展无法启动会话。一份仅说"Claude Code 不工作"的报告无法识别故障层级。
当界面看起来工作时,歧义变得更加严重。开发者假设智能体是只读的,因为它仅回答了一个问题。实际上,会话也可能能够编辑文件或运行命令。身份验证建立了身份;它本身不建立安全的本地访问边界。
创建一个包含一个可读固定文件且没有有价值数据的文件夹。要求 Claude Code 检查该固定文件、建议更改、在需要的地方请求批准、创建一个指定文件,并对同意边界之外的操作拒绝或需要额外批准。记录每一步的可观察结果。
1. VS Code 主应用
应用构建、用户配置文件、工作空间信任状态、集成 shell、
远程开发上下文和继承的环境。
2. VS Code 扩展
单独安装的包,有自己的标识符、版本、设置、日志、
更新周期和会话状态。
3. 终端 CLI
通过 PATH 找到的可执行文件。不同的 shell、终端、
容器或远程主机可能将相同的命令名解析为不同的文件。
4. 身份和权限
身份验证确定哪个身份在发起请求。权限确定该会话
可以做什么。这两者相关但独立。
批准门是在敏感操作前的刻意暂停。它是交互策略的证据,而不是操作系统隔离的证明。同样,成功的工具调用证明操作是可用的,但不证明其范围是适当的。
不要在工作仓库中开始。选择一个包含无源代码、无密钥、无环境文件、无符号链接、无挂载生产数据或无父 Git 仓库的新目录。
mkdir -p "$HOME/claude-code-isolated-check"
cd "$HOME/claude-code-isolated-check"
pwd
find . -mindepth 1 -maxdepth 1 -print
git rev-parse --show-toplevel 2>/dev/null || echo "No enclosing Git repository"
PowerShell 等效命令:
$Project = Join-Path $HOME "claude-code-isolated-check"
New-Item -ItemType Directory -Force -Path $Project | Out-Null
Set-Location $Project
(Get-Location).Path
Get-ChildItem -Force
git rev-parse --show-toplevel 2>$null
if ($LASTEXITCODE -ne 0) {
"No enclosing Git repository"
}
目录列表应为空。如果 git rev-parse 输出一个父仓库,将测试移到其他地方。工具可能将该父仓库视为项目根并获得比预期更广泛的视图。
创建两个受控的固定文件:
printf '%s\n' \
'PROJECT=isolated-check' \
'EXPECTED_MODE=approval-required' \
'SECRET_PRESENT=no' \
> fixture.txt
printf '%s\n' \
'Do not modify this file during the read-only test.' \
> protected-fixture.txt
PowerShell 等效命令:
@(
"PROJECT=isolated-check"
"EXPECTED_MODE=approval-required"
"SECRET_PRESENT=no"
) | Set-Content -Encoding utf8 fixture.txt
"Do not modify this file during the read-only test." |
Set-Content -Encoding utf8 protected-fixture.txt
记录初始校验和,使后续验证不依赖于视觉检查。
sha256sum fixture.txt protected-fixture.txt
macOS 等效命令:
shasum -a 256 fixture.txt protected-fixture.txt
Windows PowerShell 等效命令:
Get-FileHash fixture.txt, protected-fixture.txt -Algorithm SHA256
打开文件夹,而非单个文件:
code .
确认 Explorer 中的文件夹名称,并检查 VS Code 是否将工作空间报告为受信任或受限制。对于这个首次测试,不要使用多根工作空间、Dev Container、SSH 目标或 WSL 窗口,除非该远程上下文是你特别想诊断的。
从用于打开文件夹的同一外部终端运行:
code --version
code --list-extensions --show-versions
保留完整的 VS Code 版本输出,因为它可能包括构建标识符和架构。在扩展列表中,确认 Claude Code 包并对照 VS Code 内部的扩展详情页进行验证。
打开扩展视图。
选择已安装的 Claude Code 扩展。
记录其完整的发布者和扩展标识符。
记录安装的版本。
确认它在活跃的 VS Code 配置文件中已启用。
检查是否有可能混淆诊断的类似命名的扩展。
记录应包含一个形状如下的值,填入观察数据:
VS Code version: <complete output>
Active profile: <profile name or default>
Workspace trust: <trusted or restricted>
Claude extension: <publisher>.<extension-id>@<installed-version>
如果扩展未出现在命令输出中,不要立即重新安装。首先检查图形窗口和终端是否针对同一本地或远程 VS Code 环境。本地安装的扩展不一定安装在 SSH、WSL 或容器扩展主机中。
版本固定在这里意味着记录经过测试的状态。如果你的环境允许选择特定的扩展版本,记下这个选择。如果不允许,保存准确安装的版本,并在任何更新后重复测试。避免声称可从变动的"最新"版本复现。
可观测性从可执行文件路径开始。仅靠命令名无法判断 shell 是找到了本地安装、包管理器垫片、别名、脚本,还是来自另一个运行时的副本。
command -v claude
type -a claude
claude --version
printf 'shell=%s\n' "$SHELL"
uname -a
Get-Command claude -All |
Format-List Name, CommandType, Source, Version
claude --version
$PSVersionTable.PSVersion
Get-ComputerInfo |
Select-Object OsName, OsVersion, OsArchitecture
在 VS Code 的集成终端中重复执行定位和版本命令。逐字面比较外部终端和集成终端的结果。
| 检查项 | 外部终端 | VS Code 终端 | 预期解释 |
|---|---|---|---|
| 可执行文件路径 | 记录观察到的值 | 记录观察到的值 | 不同的路径意味着不同的 CLI 安装或环境 |
| CLI 版本 | 记录完整输出 | 记录完整输出 | 版本不匹配意味着无法直接比较 |
| Shell 或主机 | 记录环境 | 记录环境 | 远程和本地会话必须分开处理 |
如果存在多个可执行文件候选项,先不要删除。确定哪一个在 PATH 中排在第一位,它是如何安装的,VS Code 是否继承了较旧的环境。重启集成终端或 VS Code 窗口可能会刷新环境发现,但要记录更改前后的状态。
使用已安装 CLI 的本地帮助来发现支持的诊断和认证命令:
claude --help
不要假定记忆中的子命令、标志或菜单标签在已安装的版本中存在。本地帮助是证据的一部分。
在登录前,创建配置记录:
CLAUDE CODE / VS CODE — 初始设置记录
测试日期:
操作系统:
架构:
外部 shell:
集成 shell:
VS Code 版本和构建号:
VS Code 配置文件:
工作区信任状态:
扩展标识符:
扩展版本:
扩展执行上下文:
CLI 绝对路径:
CLI 版本:
CLI 执行上下文:
扩展认证方法:
CLI 认证方法:
账户标签(如果可以安全记录):
记录的密钥值:否
初始访问模式:
审批行为:
观察到的网络访问:
测试的项目边界:
读取测试:
写入测试:
命令测试:
边界测试:
诊断位置:
最终状态:
开放问题:
通过扩展提供的界面进行认证。仅记录方法:例如交互式浏览器登录、组织管理的登录,或环境提供的凭证。不要将会话 cookie、API 密钥、bearer 令牌、授权码或完整的环境转储复制到项目中。
然后启动单独的 CLI 会话,并按照已安装 CLI 报告的认证流程进行操作。两个流程打开的浏览器页面不能证明它们共享会话。分别记录每个界面:
扩展认证:
方法:<观察到的方法>
显示的身份标签:<非敏感标签或未显示>
测试时间:<本地时间戳>
CLI 认证:
方法:<观察到的方法>
显示的身份标签:<非敏感标签或未显示>
测试时间:<本地时间戳>
如果组织提供凭证或策略,记下该事实而不存储凭证。如果扩展成功而 CLI 失败,正确的结论是"认证状态不同或 CLI 层失败",而不是"账户已损坏"。
诊断登录时,切勿发布完整日志。在分享证据前删除令牌、授权标头、cookie、用户目录名称、查询文本和无关的文件路径。
从已安装产品公开的最严格可用模式开始:只读、计划优先或需要批准,取决于该版本公开的内容。不要仅为了使首次运行通过而启用无限制执行。
最小权限原则意味着仅授予当前任务所需的访问权限。允许列表将相同的概念应用于操作:已知安全的操作被允许,而其他一切保持被阻止或需要批准。
精确记录界面显示的所选模式。如果模式通过设置控制,记录设置名称和有效值。不要从缺少警告推断模式。
读取 fixture.txt 并报告其三个键值对。
除非读取需要批准,否则不修改文件且不运行命令。
使用任何工具前,说明你打算访问的路径。
验证响应与 fixture 匹配。然后重新计算两个校验和。正确的答案证明读取成功;校验和不变只能证明这两个文件未被修改。
提议创建 result.txt,内容如下:
READ_TEST=passed
WRITE_TEST=pending_verification
直到我明确批准写入才创建它。
不修改任何现有文件。
观察界面是否在写入前提示批准请求。如果提示,检查目标路径和提议的更改,仅批准这个文件,然后验证:
git diff --no-index /dev/null result.txt 2>/dev/null || true
在 PowerShell 上,直接检查内容:
Get-Content result.txt
Get-FileHash fixture.txt, protected-fixture.txt -Algorithm SHA256
不要仅因为智能体声称成功就将写入测试标记为通过。确认 result.txt 存在、包含恰好两行预期内容,且原始 fixture 校验和保持不变。
请求智能体提议(但不自动运行)一个打印当前目录的无害命令。预期命令取决于 shell:
pwd
(Get-Location).Path
记录命令执行是否不可用、需要批准或自动运行。这些结果都不应提前被编造;目的是确立你的配置的实际行为。
不要要求智能体读取项目外的真实文件。相反,要求它解释是否可以访问故意设置的不存在的同级路径,并在任何尝试前请求批准:
不访问该路径。解释在尝试读取前需要什么权限或确认:
../claude-code-boundary-probe/nonexistent.txt
这是一个策略接口检查,不是遏制的证明。真正的沙箱是强制执行的运行时边界。工作区首选项、提示指令或确认对话可能会降低风险,但不等同于操作系统隔离。
当某些内容失败时,在重启或重新安装任何东西前,记录时间、界面、操作和可见的错误。
打开 VS Code 的输出视图。
如果存在,选择与 Claude Code 扩展相关的频道。
仅当组件特定频道不足时才打开扩展主机日志。
记录相关时间戳和最少的错误片段。
任何重新加载后再次检查扩展的已安装版本。
捕获这些非敏感事实:
输入的确切命令;
当前工作目录;
解析的可执行文件路径;
识别失败所需的最少标准错误片段。
在 Linux 和 macOS 上,在失败的命令后立即打印退出状态:
printf 'exit_status=%s\n' "$?"
在 PowerShell 上:
"exit_status=$LASTEXITCODE"
谨慎行事:先运行另一个命令会替换你打算记录的状态。
| 检查项 | 扩展 | CLI | 解释 |
|---|---|---|---|
| 组件启动 | 观察到的结果 | 观察到的结果 | 区分加载和认证 |
| 身份已接受 | 观察到的结果 | 观察到的结果 | 分离接口间的账户状态 |
| 读取 fixture | 观察到的结果 | 观察到的结果 | 测试项目可见性 |
写入审批 观察到的行为 观察到的行为 测试有效的交互策略
命令审批 观察到的行为 观察到的行为 将命令执行与文件访问分开测试
如果扩展和 CLI 产生不同的结果,请保留这种差异。这是诊断证据,而不是噪声。
保留一份简短的测试顺序审计日志:时间戳、界面、请求的操作、审批决定、观察到的影响以及验证方法。日志应描述操作,但不要包含任何机密信息。
## 验证:设置何时就绪
只有当下列每个适用项都有观察到的值时,才能认为隔离设置已通过验证。
已记录 VS Code 的完整版本输出。
已记录 VS Code 的完整版本输出。
已记录当前活动的配置文件和工作区信任状态。
已记录当前活动的配置文件和工作区信任状态。
已记录扩展标识符和已安装版本。
已记录扩展标识符和已安装版本。
已知扩展是在本地还是远程环境中执行。
已知扩展是在本地还是远程环境中执行。
外部终端和集成终端中的 `claude` 都解析到了已知路径。
外部终端和集成终端中的 `claude` 都解析到了已知路径。
已记录每个不同环境中的 CLI 版本。
已记录每个不同环境中的 CLI 版本。
已分别记录扩展和 CLI 的身份验证方式。
已分别记录扩展和 CLI 的身份验证方式。
设置记录中未出现任何凭据、Cookie 或令牌。
设置记录中未出现任何凭据、Cookie 或令牌。
已使用界面中的实际标签记录初始权限模式。
已使用界面中的实际标签记录初始权限模式。
已根据已知内容验证测试夹具的读取结果。
已根据已知内容验证测试夹具的读取结果。
受控写入已被拒绝、批准或执行,并记录了其实际行为。
受控写入已被拒绝、批准或执行,并记录了其实际行为。
原始测试夹具的校验和未发生变化。
原始测试夹具的校验和未发生变化。
已独立于文件写入记录命令执行行为。
已独立于文件写入记录命令执行行为。
项目边界测试未暴露真实的外部数据。
项目边界测试未暴露真实的外部数据。
已记录相关的诊断通道和时间戳。
已记录相关的诊断通道和时间戳。
简洁的最终状态可以使用以下四种值:
扩展:通过 | 失败 | 未测试 CLI:通过 | 失败 | 未测试 身份验证一致性:已确认 | 不同 | 未知 访问模式:<实际观察到的标签> 读取测试:通过 | 失败 写入测试:通过 | 失败 | 按预期被阻止 命令测试:需要审批 | 自动执行 | 不可用 | 未知 边界强制执行:已确认 | 未确认 可以用于真实代码仓库:是 | 否
仅当实际测试过技术控制措施时,才能使用“边界强制执行:已确认”。模型礼貌地拒绝操作并不能构成充分证据。
## 常见故障情况及其含义
集成终端中找不到 claude
比较集成终端和外部终端的 PATH 值、shell 以及主机上下文。VS Code 可能继承了较早的环境,或者 CLI 只存在于另一台主机上。这还不能认定是身份验证失败。
外部终端和 VS Code 找到了不同的可执行文件 你面对的是两个测试对象。记录两者的路径和安装来源。在比较行为之前,先选择预期使用的那个。
扩展可以正常工作,但 CLI 要求登录 将它们的身份验证状态视为彼此独立。在不影响扩展现有工作会话的前提下,完成或诊断 CLI 的身份验证。
CLI 可以正常工作,但扩展加载失败 检查扩展版本、启用状态、执行主机、工作区信任状态以及扩展专用输出。重新安装 CLI 不太可能解释扩展宿主的加载错误。
智能体可以读取但无法写入 这可能正是预期的访问模式。检查写入操作是被阻止、需要审批、指向了错误路径,还是在操作系统权限层失败。
写入操作在未获得预期审批的情况下发生 停止会话,保留诊断信息,记录实际生效的模式,并且不要打开真实代码仓库。重新检查会话专属设置,不要依赖全局首选项。
重启后,VS Code 显示了另一个扩展版本 可能发生了更新。记录新版本并重新执行受控测试;不应将两个版本的结果合并视为同一套配置。
项目看起来是空的,但智能体看到了不相关的文件 检查是否存在父级代码仓库、多根工作区、符号链接、远程挂载、继承的指令以及错误的工作目录。
界面显示某项操作成功,但文件并不存在 验证当前目录和目标路径。文字形式的成功声明并不能证明文件系统确实发生了变化。
日志中包含看起来与身份验证有关的错误 使用时间戳和组件标识确定是哪个会话产生了该错误。不要假设旧的扩展错误描述的是当前 CLI 会话。
## 会使诊断变得更糟的方法
一次性重新安装所有组件。这会消除用于判断哪个层级发生故障的证据。
一次性重新安装所有组件。这会消除用于判断哪个层级发生故障的证据。
授予完全访问权限以“排除权限问题”。这恰恰会在最不了解配置的时候丢弃安全边界。
授予完全访问权限以“排除权限问题”。这恰恰会在最不了解配置的时候丢弃安全边界。
首先在真实代码仓库中进行测试。任何意外的读取、写入、命令或网络操作都会演变成真实事故。
首先在真实代码仓库中进行测试。任何意外的读取、写入、命令,或 com