凭据与传输边界

代理编码会话需要凭据——用于与 Claude 通信的 Anthropic 密钥、用于推送的 GitHub 令牌、用于部署的 AWS 密钥。它还会运行任意代码、安装任意软件包,并遵循它自己并未编写的文件中的指令。把你真实的机密交给这样的环境,正是密钥最终落入窃密者收件箱的原因。

Bromure Agentic Coding 通过传输边界化解了这种矛盾:VM 内部的代理只会看到伪造的占位符令牌。你真实的凭据以加密形式存放在 macOS 宿主机上,并由宿主机侧的 MITM 代理服务器在最后可能的时刻——在请求已经离开 VM 之后,且仅当它发往凭据所属的主机时——将其替换到传输线路上。VM 内部的任何文件、环境变量或进程都绝不会包含真实的 API 密钥、OAuth 令牌、AWS 机密或 SSH 私钥。

本章先从头到尾讲解其机制,然后依次介绍代理如何登录、每种受支持的凭据类型及其生命周期、按次使用的批准系统、入侵检测器、在拦截下无法工作的主机所需的应急手段,以及如何亲自验证这道边界。

凭据按机器配置。机器就是设置编辑器仍称为工作区的东西;两个词指的是同一台虚拟机及其设置。

注意: 本章介绍概念和运行时行为。设置面板的逐字段参考,参见设置 → 凭据。代理的 API 密钥和订阅不再在该面板中设置;它们位于 偏好设置 › 模型(参见模型与提供方)。

传输边界概览

三条原则定义了这个模型:

  1. VM 中是伪造值。 你配置的每个凭据在 VM 内部都会被一个保留结构的伪造值替换。伪造值保持验证器所期望的形状——Anthropic 伪造值以 sk-ant-api03-brm- 开头,GitHub 伪造值是 ghp_ 加 36 个字符——因此 claude、gh、doctl 等工具会毫无怨言地接受它们。
  2. 仅在传输线路上使用真实值。 VM 发出的每个 HTTPS 请求都会被隧道传输到宿主机代理服务器,后者将其解密、把伪造值替换为真实值,然后在上游重新加密。替换的作用域限定为该凭据所铸造的目标主机。
  3. 失败即关闭。 如果有任何东西绕过了代理服务器,请求就只携带一个伪造值,上游身份验证将失败。不存在任何真实机密会意外泄露的路径。

伪造值是确定性的:每个伪造值都通过 HKDF-SHA256 从真实值加上每次安装独立的 32 字节盐派生而来。同一个真实密钥在你的 Mac 上始终映射到同一个伪造值,因此对其密钥进行指纹识别的客户端(例如 Claude Code 会缓存密钥哈希)绝不会看到凭据在会话之间"轮换"。

凭据VM 中的伪造形状
Anthropic API 密钥sk-ant-api03-brm-…
OpenAI API 密钥sk-brm-…
xAI API 密钥xai-brm-…
Moonshot(Kimi)API 密钥sk-kimi-brm-…
Claude Code 使用的 OpenRouter 密钥sk-or-v1-brm-…
Amazon Bedrock API 密钥bedrock-brm-…
GitHub 令牌ghp_ + 36 个字符(共 40 个)
GitLab 令牌glpat- + 20 个字符
DigitalOcean PATdop_v1_ + 十六进制(共 64 个字符)
Linear API 密钥lin_api_ + 40 个字符(共 48 个)
Twilio 认证令牌/API 密钥机密brm-twilio-…(至少 32 个字符)
MCP bearer 令牌brm-mcp_…
Docker 注册表密码brm-docker-…(至少 40 个字符)
Kubernetes bearer 令牌brm-k8s-…
数据库机密brm-db-…(至少 32 个字符)
通用手动令牌brm_…

边界没有开关。代理服务器是 VM 唯一的出口路径;替换就是本应用中凭据的工作方式。

替换如何端到端工作

一个经过身份验证的请求的完整往返:

  1. 会话启动——令牌计划。 机器的虚拟机启动时,应用会为每台机器构建一份令牌计划,把每个真实凭据与其派生的伪造值配对。伪造值会写入虚拟机:环境变量(ANTHROPIC_API_KEY、GH_TOKEN、LINEAR_API_KEY、…)和配置文件(~/.git-credentials、~/.docker/config.json、~/.kube/config、~/.aws/config、~/.config/doctl/config.yaml、MCP 配置)。真实值则加载到代理服务器内存中的替换映射里,各自绑定到所属的目标主机。
  2. 请求离开 VM。 客户机的 HTTPS 流量通过 virtio 套接字(vsock 端口 8443)隧道传输到宿主机代理服务器。VM 没有其他通往网络的路由。
  3. TLS 终止。 代理服务器出示一个伪造的按主机叶证书——以目标主机名作为 CN 和 SAN,使用按主机的 EC 密钥——由 Bromure Agentic Coding Root CA 签名。由于该 CA 的公开证书在启动时已安装到 VM 的信任存储中,客户机的 TLS 客户端会接受该连接,代理服务器便可以读取明文请求。
  4. 替换。 代理服务器查找请求中出现的每个伪造令牌(请求头,以及对于已选择加入的凭据类型,还包括请求体),如果目标主机与凭据的作用域匹配,就将其替换为真实值。
  5. 上游重新加密。 重写后的请求通过 Apple 的 URLSession(即 macOS 自己的 TLS 栈)重新发送到真实目标,该栈会验证上游服务器的真实证书。响应通过隧道流回客户机。

如果目标与某个伪造值的作用域不匹配,伪造值就原样发出(并在上游身份验证失败)——或者,当这种不匹配看起来像是数据外泄时,请求会被直接阻止(参见下文入侵检测器)。

Bromure Agentic Coding Root CA

该 CA 是每次安装独立的,位于 ~/Library/Application Support/BromureAC/ca/(cert.pem 加上一个 mode-0600 的 key.pem)。它的主题为 "Bromure Agentic Coding Root CA",组织为 "Bromure"。值得了解的属性:

  • CA 有效期为 10 年。伪造的按主机叶证书有效期为 1 年,并回溯 24 小时,因此在挂起/恢复期间时钟漂移的客户机仍然会接受它们。叶证书在应用进程的生命周期内按主机缓存。
  • 公开证书在启动时安装到每个 VM 的信任存储中(通过 meta 共享传递,并用 update-ca-certificates 应用)。它绝不会离开你的机器,除了你的 VM 之外没有任何东西信任它。
  • 要轮换 CA,请退出应用并删除 ca/ 目录。下次启动时会铸造一个新的 CA,每个 VM 在下次启动时获取新的公开证书。轮换不会使其他任何东西失效——工作区机密和 profile.json 元数据保持不变。

主机作用域

每个替换条目都绑定到一个主机作用域。匹配是精确或子域匹配且不区分大小写,绝不是子串匹配:作用域限定为 openai.com 的凭据匹配 api.openai.com,但不匹配 openai.com.evil.example——一个仿冒主机无法诱骗代理服务器用真实密钥装点其请求。手动令牌规则可以有意使用空白主机过滤器,这意味着"在任何主机上注入";这是你为每个条目做出的明确选择(参见通用 API 密钥)。

从构造上失败即关闭

这个设计从不依赖代理服务器不可绕过来保证保密性——它依赖于机密根本不在那里:

  • 一个以某种方式跳过代理服务器的请求携带的是伪造令牌;上游 API 会拒绝它。
  • 在 VM 内部签名的 AWS 请求是用伪造的机密密钥签名的;如果它们直接到达 AWS,会因 InvalidSignatureException 而失败(参见下文 AWS)。
  • SSH 私钥字节根本不在 VM 中;只有签名会跨越边界。

在工作区编辑器中管理凭据

服务凭据——git 令牌、云密钥、镜像仓库、数据库、SSH 密钥——按机器配置。打开机器的设置(机器菜单中的 设置…,或会话菜单中的 “机器”设置…),然后在侧边栏的 安全 下选择 凭据。

Web app 工作区编辑器的凭据面板:Git 身份的姓名和电子邮件字段、空状态“暂无凭据”,以及“添加凭据”和“导入 env 文件…”按钮

面板开头是 Git 身份(写入虚拟机中 ~/.gitconfig 的姓名和电子邮件;两者都留空可保留 git 的默认值——占位文字只是示例,不是凭据),接着是只列出你已配置凭据的列表,按类别标题分组(Agents、Git、Cloud、Databases、SSH、Other)。尚未配置任何内容时,面板显示 暂无凭据。底部有两个按钮:添加凭据 会打开凭据类型选择器——Git token、SSH key、AWS credentials、DigitalOcean token、Linear API key、Twilio API key、Kubernetes、Container registry、Database 和 Other API key——而 导入 env 文件… 会从 .env 或 ~/.bashrc 批量导入。点按 存储;下次启动会话时,会把伪造值写入虚拟机,并把真实值加载到代理服务器中。

代理的 API 密钥(Anthropic、OpenAI、xAI、Moonshot 及其他模型提供方)不在此选择器中:它们在下面介绍的 偏好设置 › 模型 中设置。Agents 分组只出现在仍保存着早期版本遗留的专属代理密钥的工作区上;其 在“模型”中编辑… 菜单项会打开 偏好设置 › 模型。要更改模型访问,请使用 偏好设置 › 模型 或机器的 模型 面板。

每个凭据的批准关卡(使用前询问)和各服务的写入策略是在护栏面板中设置的,而不是在这里。逐字段参考参见设置 → 凭据。

有七个提供方会被自动处理——Anthropic、OpenAI、GitHub、GitLab、DigitalOcean、Twilio 和 Kubernetes 不需要手动令牌规则;它们各自的章节会介绍。其他一切都通过其他 API 密钥处理。

从 env 文件导入。 导入 env 文件… 会读取已有的 .env 文件——或 ~/.bashrc——并把其中的变量转换为凭据。解析器能处理 KEY=VALUE 和 export KEY=VALUE,去掉外围引号和行尾注释,并刻意跳过任何需要 shell 求值的内容($VAR 插值或 $(…) 替换),因此指向真实的 .bashrc 也很安全。随后,审阅表单会以遮蔽的值显示这些变量:已识别的名称(GH_TOKEN/GITHUB_TOKEN、GITLAB_TOKEN、AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN、DIGITALOCEAN_ACCESS_TOKEN、LINEAR_API_KEY、TWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKEN,以及模型提供方密钥 ANTHROPIC_API_KEY、OPENAI_API_KEY、XAI_API_KEY、MOONSHOT_API_KEY 和 KIMI_API_KEY,后者会进入 偏好设置 › 模型 中对应的提供方——如果是远程机器,则进入其自己的 模型 覆盖)会自动映射到其凭据类型,而未识别的名称可以作为通用手动令牌导入,并附上你提供的、以逗号分隔的主机范围。已配置的条目会被标记并保持未勾选,因此重新导入绝不会悄悄覆盖机密。

代理密钥与订阅

每个编程代理——Claude Code、Codex、Grok、Kimi 和 omp——都从 偏好设置 › 模型(⌘, 然后选择 模型)中配置的提供方获得模型访问权限。每台机器的设置中也有同样的面板,作为可选的按机器覆盖。完整参考——提供方、各代理的模型选择、按机器覆盖、OpenRouter、自定义服务器和设备端模型——见模型与提供方。本节介绍与凭据相关的要点:密钥或订阅如何在不进入虚拟机的情况下到达代理。

标题为“Bromure — 偏好设置”的偏好设置窗口,默认页面,模型面板:提供方栏(Anthropic (Claude)、OpenAI 和 OpenRouter 带 API 密钥和绿点;xAI (Grok)、z.ai (GLM)、Moonshot (Kimi)、Amazon Bedrock、自定义服务器和设备端未设置)以及代理栏(带尺寸的默认、Claude Code、Codex、Grok、Kimi、omp)

在 提供方 栏中点按一个提供方即可打开其弹出窗口。每个提供方的弹出窗口都有 API 密钥 字段;提供订阅的四个提供方还有登录控件。

API 密钥

把密钥粘贴到弹出窗口的 API 密钥 字段中。在偏好设置中,面板会随着输入实时保存;在机器的设置中,密钥用 存储 保存。生命周期:

  • 在虚拟机中: 代理惯用的变量(ANTHROPIC_API_KEY、OPENAI_API_KEY、XAI_API_KEY、…)存放着符合提供方格式的伪造值(sk-ant-api03-brm-…、sk-brm-…、xai-brm-…、sk-kimi-brm-…)。
  • 在传输途中: 只有在发往该提供方主机(anthropic.com、openai.com、x.ai、moonshot.ai、…)的请求中,才会换成真实密钥。
  • 静态存储: 密钥和模型设置的其余部分一样,加密保存在 models.enc 中(参见机密在宿主机上的存放位置)。

在 模型 中设置的密钥不会出现在凭据或护栏面板中,因此没有 使用前询问 行。(早期版本遗留、仍存放在工作区本身的代理密钥则会出现在那里,也可以设置批准。导入 env 文件已不再创建这类密钥:它会把代理密钥放进模型设置。)

在 CLI 中,bromure-cli workspaces create --auth token|subscription|bedrock|local 和 bromure-cli vm run --auth token|subscription|bedrock|local 仍然用于选择工作区主代理的认证模式。

订阅:Claude、ChatGPT、Grok 和 Kimi

如果你有的是订阅而不是 API 密钥,请改为登录。订阅只适用于 Anthropic (Claude)、OpenAI(ChatGPT,由 Codex 使用)、xAI (Grok) 和 Moonshot (Kimi);z.ai、Amazon Bedrock、OpenRouter 和自定义服务器只接受密钥,omp 则只支持 API 密钥。订阅只驱动它自己的代理:Claude 登录运行 Claude Code,ChatGPT 登录运行 Codex,依此类推。

无论以哪种方式登录,结果都一样:真实的 OAuth 令牌只存在于宿主机上,而客户机用一把假密钥运行——Claude 是一个假的 ANTHROPIC_API_KEY,Codex 是一个预先填入、内含到期日极远的假 JWT 的 ~/.codex/auth.json(这样客户端永远不会尝试刷新它),Grok 和 Kimi 则是在它们各自凭据文件中的替身令牌。代理服务器会识别出这个假值,并在传输途中注入有效的 Authorization: Bearer 访问令牌。

从偏好设置 › 模型登录

提供方的弹出窗口会显示三种状态之一:

状态弹出窗口显示的内容
未登录Sign in with 提供方、“在临时虚拟机中交互式登录——无需 API 密钥。”,然后在 API 密钥 字段上方显示“或粘贴 API 密钥”。
已登录一行绿色的“已登录”并附上登录日期,以及 重新登录… 和 登出…。
已过期一个橙色的 登录已过期 面板——“提供方 拒绝了已保存的登录(…)。在你重新登录之前,会话无法使用它。”——附有 重新登录 和 登出…。

Sign in with 提供方 会运行注册流程:

  1. 标题为 通过 提供方 注册 的说明会告诉你接下来会发生什么。点按 继续。(如果 Bromure 代理服务器没有在运行,注册会被拒绝。)
  2. 一台用完即弃的注册虚拟机会启动——临时、隔离,没有工作区文件夹、没有已保存的机密,也没有凭据替换映射。代理自己的登录命令会在其中运行。
  3. 你 Mac 的默认浏览器会打开提供方的登录页面。照常登录即可。
  4. 得到的令牌会在宿主机上捕获、加密并保存;用完即弃的虚拟机会关机并删除。

从偏好设置开始的登录始终由所有机器共享。登出… 会询问“要登出 提供方 吗?”——“使用此登录的工作区将停止工作,直到你重新登录。”——并删除已保存的登录。在无法起作用的地方,登出… 会被隐藏。

从机器的模型面板登录:共享范围

同样的弹出窗口也会出现在机器自己的 模型 面板中。在那里开始的登录最后会询问一个问题:与每个工作区共享?:

按钮效果
每个工作区把此登录保存为共享登录,并且移除每台机器对该提供方的专属登录,让每台机器真正使用新的登录。
仅此工作区只为这台机器保存此登录。

范围之所以重要,是因为机器会先读取自己的登录,只有在没有时才退而使用共享登录。曾经为自己登录过的机器会一直使用那个登录,即使之后有更新的共享登录也一样,直到你选择 每个工作区 或让那台机器登出为止。发起登录的远程客户端也会收到同样的问题;如果没人回答,登录就只属于那台机器。

从聊天登录

你不必先去偏好设置。当会话中的代理需要登录时,聊天会显示一张标题为 登录 提供方 的卡片——“Bromure 在此 Mac 上为你登录,并让你的 提供方 账户远离机器 — 代理只会看到一个替身密钥。”——附有 登录 提供方… 按钮,而侧边栏中该会话的行会显示 需要登录。当代理已保存的登录被拒绝时,红色错误卡片也会提供同样的按钮。

点按它就能在不使用用完即弃虚拟机的情况下登录:

  1. 会话自己的终端会运行代理的登录命令,提供方的登录页面则在你 Mac 的浏览器中打开(“正在打开浏览器以登录…”)。
  2. 当代理用授权码交换令牌时,代理服务器会自己回应这次交换:真实令牌会直接进入宿主机的存储。Claude Code 和 Codex 会被告知凭据留在 Mac 上;Grok 和 Kimi 会收到替身令牌,由它们的 CLI 写入各自的凭据文件。
  3. 代理用替身值重新启动(“已登录。正在重新启动 …”)。

从聊天登录会替换机器原本读取的登录:如果机器有自己的登录就替换它,否则替换共享登录。如果 5 分钟内没有任何登录到达代理服务器,卡片会显示“Bromure 未能及时收到 提供方 登录。您可以重试。”每台机器一次只能进行一个登录。

omp 没有可以登录的账户;它的卡片显示“omp 需要一个模型提供方”,并改为提供 机器设置…。

警告: 不要为了修复已过期的登录而在虚拟机内手动运行 /login(或代理的登录命令)。请使用卡片或 偏好设置 › 模型,让令牌由宿主机捕获,而不是留在虚拟机中。

Kimi 登录国际区域

Kimi Code 的 CLI 默认使用中国大陆区域,而该区域会拒绝其他地区的账户。Bromure 会在注册虚拟机和每个会话中设置 CLI 的区域变量,让 Kimi 登录国际区域(auth.kimi.ai,API 位于 api.kimi.ai)。在旧的 auth.kimi.com 区域捕获的 Kimi 登录仍会被识别。

令牌托管:一个授权,一个刷新者

令牌刷新完全在宿主机侧进行,而每个登录都由唯一的所有者刷新:

  • 每个槽位一个授权。 共享登录和每台机器自己的登录是不同的槽位。每个槽位一次只运行一次刷新,而读取该槽位的每台机器都使用其结果。客户机永远不会持有刷新令牌。
  • 刷新时机。 宿主机会在到期前约 5 分钟,向提供方的令牌端点刷新(Claude 为 platform.claude.com、Codex 为 auth.openai.com、Grok 为 auth.x.ai、Kimi 为 auth.kimi.ai)。刚注册的登录会以已过期的状态保存,因此第一次使用就能证明刷新路径有效。
  • 自动化的克隆机器共享授权。 为自动化克隆的机器会指向其基础机器的登录,而不是拷贝一份。
  • 你 Mac 上 CLI 自己的登录不会导入。 与宿主机上的 CLI 共享授权,会导致每当其中一方刷新时,另一方就被登出。
  • 当没有可用的令牌时,对于 Claude 请求,代理服务器会自己回应代理,而不是转发假密钥:临时故障会以可重试的 529 返回,被拒绝的登录则以 401 返回,提示你从 Bromure 重新登录。此时弹出窗口会显示 登录已过期。

服务凭据

AWS

AWS 得到了所有提供商中最深入的处理,因为 AWS 请求不是通过 bearer 令牌进行身份验证的——它们是被签名的(SigV4)。在工作区编辑器中打开 凭据 → AWS;一个分段控件在 静态密钥 和 SSO / Identity Center 之间选择。

静态密钥与宿主机重签名器

粘贴你的 访问密钥 ID 和 机密访问密钥(外加一个可选的 STS 会话令牌 和一个 默认区域)。生命周期:

  • 在 VM 中: ~/.aws/config 指向一个 credential_process 助手,它通过 vsock 端口 8445 提供真实的访问密钥 ID 与一个 40 字符的伪造机密访问密钥配对,并省略会话令牌。每个 AWS SDK、aws CLI、terraform 和 boto3 都会原生识别它;无需针对特定工具进行设置。
  • 客户机做什么: 用伪造的机密对其请求签名,生成一个语法上有效但密码学上注定失败的 SigV4 签名。
  • 在传输途中: 宿主机的 AWS 重新签名器会检测发往任何分区 AWS 的请求,无论使用 IPv4 还是双栈名称(*.amazonaws.com、*.api.aws、*.amazonaws.com.cn、*.api.amazonwebservices.com.cn、European Sovereign Cloud 和 ISO 分区的域名;包括 GovCloud、区域、FIPS 和 bucket 形式的 S3 主机),去掉客户机的签名,在有会话令牌时注入真实的 X-Amz-Security-Token,并在请求离开你的 Mac 之前用真实的秘密重新签名。AWS 护栏覆盖相同的主机,下文对 VM 创建的凭据的改写也覆盖这些主机,另加 public.ecr.aws。每次成功的重新签名都会发出一个带有遮蔽访问密钥的 credential.aws_sign 审计事件,并在安全时间线中显示为 凭据使用 行。

这在最强意义上是失败即关闭的:真实机密密钥以任何形式都绝不存在于 VM 中,而绕过代理服务器的请求会被 AWS 以 InvalidSignatureException 拒绝。

有三种请求样式不受支持,会向客户机返回一个明确的错误而不是无声的失败:分块流式 S3 上传(STREAMING-AWS4-HMAC-SHA256-PAYLOAD,以 501 应答)、SigV4A 非对称签名,以及预签名的查询字符串 URL(它们把签名嵌入在重签名器无法替换的位置)。

VM 创建的凭据

有些调用会签发新的凭据:aws sts assume-role / get-session-token / get-federation-token、aws iam create-access-key、IAM Identity Center 的角色凭据、Cognito 的 GetCredentialsForIdentity、aws ecr get-login-password,以及 DigitalOcean 上的 doctl registry login、doctl kubernetes cluster kubeconfig save(及其凭据调用)和 doctl spaces keys create。代理服务器会扣下这类调用的响应,在 VM 看到之前把其中的每个机密都替换为伪造值。临时 AWS 密钥保留其真实的访问密钥 ID,配以伪造的机密和会话令牌,这样重新签名器就能分辨客户机是用哪个密钥签的名。镜像仓库或集群的令牌会变成一个伪造值,只在该镜像仓库或集群上才会被换回真实值。

真实值会加密保存在工作区的配置中,因此 VM 存下的伪造值(在 ~/.aws、~/.docker/config.json 或 kubeconfig 中)在重启后依然有效。签发的 AWS 密钥会用它自己的机密和会话令牌重新签名。一旦过期,用它签名的请求会被拒绝,而不是改用工作区自己的密钥重新签名——那样会以另一个身份执行这些请求。过期的凭据会在过期 30 天后被丢弃。

代理服务器无法完整改写的响应绝不会被转发:客户机会改为收到 502。设置由 VM 自己选择的机密的调用,因为没有任何伪造值可以替代,在任何护栏模式下都会被拒绝:iam:CreateLoginProfile、UpdateLoginProfile、CreateServiceSpecificCredential 和 ResetServiceSpecificCredential。AWS 许可提示会写明它将要签名的调用(例如 sts:AssumeRole),每个签发的凭据都会产生一个 credential.minted 事件。

SSO / IAM Identity Center

如果你的组织使用 IAM Identity Center,请选择 SSO / Identity Center 而不是粘贴长期有效的密钥:

  1. 点击 授予对 ~/.aws 的访问权限 并批准文件夹访问提示(一个安全作用域的授权;该文件夹在宿主机上读取,绝不会挂载到 VM 中)。
  2. 从 SSO 配置文件 选择器中选择你的配置文件。应用会发现 ~/.aws/config 中带有 sso_start_url、sso_account_id 和 sso_role_name 的 [profile …] 部分,并解析 [sso-session …] 引用;账户 ID 和角色以只读方式显示。
  3. 在会话启动时,宿主机从 SSO 令牌缓存(~/.aws/sso/cache)解析临时角色凭据。如果缓存的令牌已过期,你的浏览器会为 aws sso login 打开——在宿主机上运行,来自 /usr/local/bin/aws。

解析出的临时密钥馈入与静态密钥相同的重签名器;VM 仍然从不看到机密。凭据在宿主机上会在到期前大约 5 分钟自动刷新。

Bedrock

Amazon Bedrock 是供所有代理使用的模型提供方,而不是某一个代理的认证模式。在 偏好设置 › 模型(或机器的 模型 面板)的 Amazon Bedrock 弹出窗口中开启 使用 Amazon Bedrock,然后为每个代理选择 Bedrock 模型 ID。Claude Code 原生在 Bedrock 上运行;其他代理则通过 Bedrock 兼容 OpenAI 的 API 使用它。由于 Bedrock 端点是 *.amazonaws.com 主机,请求会通过同一条重新签名路径,用每台机器自己的 AWS 凭据(凭据 → AWS,静态或 SSO)签名——或者,如果你在弹出窗口的 Bedrock API 密钥(可选——否则由 AWS 凭据签名) 字段中粘贴了一把密钥,就用该密钥签名,而虚拟机只会看到伪造值 bedrock-brm-…。弹出窗口还接受 AWS 区域;留空即使用每台机器的 AWS 区域。参见模型与提供方。

Git HTTPS 令牌(GitHub、GitLab、Bitbucket、自托管)

用于 git-over-HTTPS 的个人访问令牌位于 GitHub 令牌 / GitLab 令牌 / Bitbucket 令牌 下(统称 HTTPS 令牌)。每个条目需要一个主机、一个用户名和令牌;自托管的 GitLab 或 Gitea 实例通过设置主机字段即可工作。生命周期:

  • 在 VM 中: 一个伪造值被写入 ~/.git-credentials 以及 gh/glab 配置;GH_TOKEN 和 GITLAB_TOKEN 被导出,以便 CLI 自动进行身份验证。伪造形状匹配每个厂商的验证器(GitHub 用 ghp_ + 36,GitLab 用 glpat- + 20,其他用 brm_…),因此 gh 和 glab 中的前缀和长度检查会通过。
  • 在传输线路上: 在发往该条目 git 主机的请求上替换为真实令牌。
  • 审批: 每个条目在护栏窗格中都有自己的 使用前询问 行。

如果你只需要通过 SSH 进行 git push,你可能根本不需要 HTTPS 令牌——参见下文 SSH 密钥。

通用 API 密钥(其他 API 密钥 / 手动令牌规则)

对于应用不自动处理的任何 API,在 其他 API 密钥 下添加一个条目(手动令牌规则,也以 MITM 令牌替换 的形式呈现)。点击 添加令牌 并提供:

字段含义
名称该条目的标签。
值真实机密(在宿主机上加密存储)。
环境变量名伪造值在 VM 内部导出所用的变量。在你的代码中引用它。
主机过滤器(可选)替换的主机作用域。

有两种边缘情况是有意为之的:

  • 空的环境变量名: 不导出任何东西;你从会话的欢迎横幅中复制伪造值,并将其放在你的工具所需的任何位置。
  • 空白的主机过滤器: 真实值会在任何主机上注入,无需询问。这是一个明确的始终开启的选择——对于有许多区域性主机名的 API 很有用——但这意味着凭据的作用域不再保护它。要门控一个无作用域的机密,请在护栏窗格中为它开启 使用前询问(或者干脆给它一个主机过滤器)。

Anthropic、OpenAI、GitHub、GitLab、DigitalOcean 和 Kubernetes 在这里从不需要手动条目。

1Password 机密引用(op://)

与其粘贴一个真实机密,一个 其他 API 密钥 的值可以是一个 1Password 机密引用——op://vault/item/field,或者 op inject 和 .env.op 文件所使用的花括号形式 {{ op://vault/item/field }}。磁盘上只会存储引用本身;机密本身绝不会被写入宿主机或 VM 的任何地方。编辑器识别该引用,将其明文显示(它不是机密),并注明它通过 1Password 解析。

在每次工作区启动时,Bromure 用 1Password CLI(op read)在宿主机侧解析该引用,从引用字符串铸造一个伪造值(因此即使机密轮换,伪造值也保持稳定),并只将该伪造值导出到 VM 中。然后 MITM 代理服务器在传输线路上把伪造值替换为解析出的值,与它对粘贴的机密所做的完全一样——而且它每 2 分钟重新解析一次,因此在 1Password 中轮换该项目会在几分钟内生效,无需重启。

这需要安装并已登录 op CLI——通过 1Password 应用进行生物识别解锁,或在终端中执行 op signin。如果找不到 op,编辑器会显示一个 获取 1Password CLI 链接,工作区在启动时会呈现安装说明;如果解析失败(未登录,或项目不存在),Bromure 会呈现该错误,以便你修复并重启工作区。

导入 .env 或 .env.op 文件(凭据面板中的 导入 env 文件…)时,会自动识别 op:// 值——无论是 ANTHROPIC_API_KEY 这类已识别的名称,还是 STRIPE_KEY 这类任意名称——并把每一个保存为存放该引用的手动令牌。

DigitalOcean

在 凭据 → DigitalOcean 下粘贴一个个人访问令牌(在浏览器中打开 DigitalOcean 令牌页面 链接会带你到令牌生成页面)。伪造值(dop_v1_ + 十六进制,64 个字符)被导出为 DIGITALOCEAN_ACCESS_TOKEN 并写入 ~/.config/doctl/config.yaml,因此不需要 doctl auth init。替换涵盖发往 digitalocean.com 的请求,外加一个用于 docker login / doctl registry login 针对 registry.digitalocean.com 所用的 base64 Basic-auth 数据块的第二个条目,因此注册表的推送和拉取也能解析。

Linear

在 凭据 → Linear 下粘贴个人 API 密钥(链接:在浏览器中打开 Linear API 设置;密钥可在 linear.app → Settings → API 获取)。伪造值(lin_api_ + 40)会以 LINEAR_API_KEY 导出,Linear SDK、MCP 服务器和 CLI 工具都会自动读取;替换严格限定于 linear.app(GraphQL 位于 api.linear.app,MCP 位于 mcp.linear.app)。工作区上的 Linear 密钥也是 Linear issue 自动化触发器的前提条件——参见自动化。

Twilio

添加一个 Twilio API key 凭据,把 SID 填入 Account SID (AC…) or API Key SID (SK…),把机密填入 Auth Token / API Key secret(两者都来自 console.twilio.com)。Twilio 使用 HTTP Basic 认证,其中 SID 是一种身份——会出现在请求 URL 中——只有令牌是机密。生命周期:

  • 在虚拟机中: TWILIO_ACCOUNT_SID 存放真实的 SID,TWILIO_AUTH_TOKEN 则存放伪造值 brm-twilio-…,让 Twilio SDK 和 CLI 无需配置即可读取。
  • 在传输途中: 在发往 twilio.com 的请求中,代理服务器会把单独的伪造令牌,以及预先用 base64 编码的 SID:令牌 Basic 认证块,都换成真实值。
  • 批准: 通过护栏面板中的 使用前询问。

导入 env 文件… 能识别 TWILIO_ACCOUNT_SID/TWILIO_API_KEY_SID 和 TWILIO_AUTH_TOKEN/TWILIO_API_SECRET,并把它们组合成一个 Twilio 凭据。

MCP 服务器 bearer 令牌

在 MCP 窗格中配置的 HTTP 传输 MCP 服务器得到相同的处理:真实的 bearer 令牌留在宿主机上,一个 brm-mcp_… 伪造值被注入到代理读取的 MCP 配置中,代理服务器在传输线路上替换它,作用域限定为该服务器的主机。只有已启用且带有非空 bearer 令牌的 HTTP 传输服务器才会收到替换条目。

一个额外的便利:对于带有 brm-mcp_ 条目的主机,代理服务器以 404 应答 OAuth/OIDC 发现路径(.well-known 授权服务器、受保护资源和 OpenID 配置端点)。Claude Code 于是将该服务器视为已预先身份验证,而不是尝试自己的 OAuth 流程——那个流程反正在 VM 内部永远无法完成。

容器注册表(Docker Hub、GHCR 等)

凭据 → 容器注册表 管理 docker pull/push 的 HTTP Basic 身份验证。预设有 Docker Hub(docker.io)、GitHub Container Registry(ghcr.io)和 GitLab Container Registry(registry.gitlab.com);任何其他注册表都可以按主机添加。生命周期:

  • 在 VM 中: ~/.docker/config.json 包含一个伪造的 auth 数据块——你的用户名与一个派生的 brm-docker-… 密码配对的 base64——因此 Docker 相信它已登录。
  • 在传输线路上: 代理服务器在匹配的注册表主机上替换为真实的 base64 数据块。distribution-spec 的令牌交换也得到处理:为已知的 auth realm 添加了替换条目(Docker Hub 针对 auth.docker.io 进行身份验证,DigitalOcean 的注册表针对 api.digitalocean.com)。
  • 导入: 点击 导入 config.json… 从宿主机上现有的 ~/.docker/config.json 拉取条目。委托给 credsStore/credHelpers 的条目会被跳过——它们的密码存放在操作系统钥匙串中,而不是文件里——导入摘要会报告跳过了多少个以及原因。
  • 审批: 按注册表,通过护栏窗格中的 使用前询问。移除此注册表 会删除一个条目。

Kubernetes 上下文

凭据 → Kubernetes 将 kubeconfig 上下文转变为经代理服务器中介的集群访问。点击 导入 kubeconfig 将现有的 kubeconfig 解析为每个上下文一行(当前上下文在前,自动检测身份验证类型),或点击 添加上下文 手动输入服务器 URL、凭据、命名空间和集群 CA。在任何情况下,VM 都会收到一个合成的 ~/.kube/config:客户机中的 kubectl 与代理服务器(通过 Bromure CA 信任)通信,而绝不直接与 API 服务器通信。

按身份验证类型:

  • Bearer 令牌 上下文在 VM 中获得一个 brm-k8s-… 占位符,在传输线路上替换为真实令牌。
  • 客户端证书 上下文在 VM 中获得一个一次性的自签名证书和密钥;真实的证书和密钥在宿主机上注册为一个 SecIdentity,用于上游 mTLS。
  • Exec 插件 上下文根本不会在 VM 中运行插件。exec 插件轮询器每隔刷新间隔(默认 600 秒,下限 60)在宿主机上运行该命令,解析 ExecCredential JSON,并将新鲜的令牌馈入替换映射。刷新会保留条目的许可状态。

如果 kubeconfig 提供了集群自己的 CA,它会被转发,以便代理服务器可以验证上游 API 服务器。导入的 kubeconfig 中的文件路径字段(CA、证书、密钥)在导入时会被急切读取——之后磁盘上这些文件的更改不会被采纳。每个上下文在护栏窗格中都有自己的 使用前询问 行,在那里写入策略还可以在任何字节被转发之前于宿主机侧剥离破坏性动词(kubectl delete、AWS Delete*/Terminate*、docker push、git push)——这是与凭据替换分开的一层。

HTTP 数据库(MongoDB、ClickHouse、Elasticsearch)

凭据 → 数据库(MongoDB / ClickHouse / Elasticsearch 部分)涵盖讲 HTTPS 的数据库端点——Mongo Data API、ClickHouse 的 HTTP 接口、Elastic。每个端点需要一个引擎、主机、机密、用户名、身份验证类型,以及一个或多个环境变量名(以逗号分隔),brm-db-… 伪造值在这些名称下导出;从你的代码或连接字符串中引用这些变量。

数据库凭据是唯一一类替换会同时扫描请求体以及请求头和查询参数的家族,因为连接机密经常随 JSON 或 SQL 载荷一起传输。代理服务器在请求体替换后修补 Content-Length;其他流量的无关 multipart 或二进制请求体绝不会被触碰(所有其他替换都是请求头范围的)。Basic-auth 端点的 base64 用户名和机密数据块也会被替换。按端点的 使用前询问 和写入策略在护栏窗格中设置。

SSH 密钥

SSH 完全无需任何令牌即可处理:VM 的 SSH_AUTH_SOCK 由一个通过 vsock(端口 8444)的 ssh-agent 桥接支撑。客户机可以列出身份并请求签名,但私钥字节只存放在宿主机上,从物理上无法从 VM 内部读取或提取。存在两个密钥来源,都在 凭据 → SSH 密钥 下:

  • 按工作区的默认密钥。 一个共享的默认 ed25519 密钥对在应用启动时生成(存储在 Application Support 中的 default-ssh/ 下),并复制到每个新工作区的代理目录中。该窗格显示工作区的公钥,以便你把它粘贴到你的 git 主机中(对于 GitHub:github.com/settings/keys)。你也可以用 CLI 的 bromure-cli workspaces ssh-keygen <workspace-id|name> 铸造一个新鲜的密钥,它会打印新的公钥。
  • 导入的密钥。 在 导入的 SSH 密钥 下点击 导入… / 导入文件… 并将应用指向一个现有的私钥文件——支持 RSA、ed25519 和 ECDSA,包括加密的密钥。加密的密钥在导入时会提示输入一次其口令;该口令存储在 macOS 钥匙串中(服务 io.bromure.agentic-coding.ssh-key-passphrases),并在启动时通过 SSH_ASKPASS 提供,绝不记录。导入密钥的签名流经应用为自己生成的一个私有 ssh-agent 进程(在临时目录下的套接字上运行 ssh-agent -D)——与你系统上的其他任何东西分开。
  • 主机代理中的密钥。 私钥无法离开其设备的密钥——通过 gpg-agent、Secretive、1Password 使用的 YubiKey 或其他安全密钥——改用 从主机代理… 添加。选择代理的套接字(留空 = 应用自己的 SSH_AUTH_SOCK;对于从 Finder 打开的应用,这是 macOS 的代理,而不是你的 shell 导出的那个;gpg-agent 请使用 ~/.gnupg/S.gpg-agent.ssh),点击 加载,然后勾选工作区可以使用的密钥。不会复制任何东西:VM 只能看到勾选的密钥——而且只在代理持有它们时,因此拔掉的密钥不会被提供——它们的签名请求会转发给该代理,所以触摸或 PIN 提示会照常出现在你的 Mac 上(请求最多等待两分钟)。代理的其他密钥对 VM 保持不可见,要求用其中某把签名的请求会被拒绝。

对于每个导入的密钥,在护栏窗格中开启 使用前询问 会使每个 VM 内的签名请求都提示征求许可。每个签名——无论默认密钥还是导入密钥——都会发出一个 credential.ssh_sign 审计事件,携带密钥的 SHA256 指纹以及它是托管密钥、导入密钥还是主机代理密钥。

注意: 你的 macOS 登录 ssh-agent(launchd 的那个)——或任何其他主机代理——被有意绝不整体暴露给 VM。只有按工作区的密钥、你明确导入的密钥,以及你逐个选中的主机代理密钥才能从会话中访问。

按次使用审批与授权时长

本章中的任何凭据都可以被标记为 使用前询问——护栏窗格中的一个按凭据复选框(在控件本身上标注为 使用前需要审批),默认关闭,在 UI 中描述为:"在会话中首次使用此凭据时弹出一个确认对话框。"

当一个被门控的凭据在会话中首次被使用时,代理服务器会保持住请求并显示一个标题为 允许"工作区名称"使用凭据? 的许可对话框(填入你工作区的名称和凭据的标签),提供四个按钮:

按钮授权
允许 5 分钟有时限;凭据在 5 分钟内无需进一步提示即可流通。
允许 1 小时有时限,1 小时。
在本次会话中始终允许直到机器的虚拟机关机为止。
不允许请求被拒绝;该拒绝会被记住 5 分钟,因此代理的重试风暴不会产生对话框风暴。

值得了解的行为:

  • 合并。 需要同一凭据的并发请求会合并到一个对话框上——一个话痨的代理同时发出十二个并行 API 调用只会产生一个提示,而这十二个都会遵循你的决定。
  • 拒绝优先。 一个实时的拒绝会在参考任何较早的允许之前短路。
  • 设计上即为临时。 授权和拒绝只保存在内存中,并会在虚拟机关机时撤销。“会话的剩余时间”绝不会延续到虚拟机重启之后,也不会有任何内容在应用的两次运行之间保留。
  • 无头会话。 在 SSH 或无头会话中,提示会出现在机器的 tmux 中,而不是图形化警告——参见远程访问。

对于 AWS,该门控适用于每次宿主机侧的签名调用;对于 SSH 密钥,适用于签名请求;对于其他所有一切,适用于会话的首次传输替换。

提示: 许可门控是按凭据的,而不是按主机的。如果你想让一个无作用域的手动令牌保持受控,审批就是为此设计的机制。

凭据审批窗口

窗口 → 凭据审批… 打开一个实时视图,显示当前应用运行期间做出的每个许可决定:有时限的允许(5 分钟 / 1 小时 / 本会话剩余时间)和被记住的拒绝。每一行显示工作区名称和剩余时间,并提供 撤销;全部撤销(⌘⌫)一次性清除所有内容。该列表每 2 秒自动刷新,并随着授权到期自然缩短。

由于决定只存在于内存中,因此在授权到期后、虚拟机关机后(会话范围的授权),以及应用退出后,窗口都是空的。它是面向当下的控制面板,而不是审计日志——要查看历史,请使用安全时间线和追踪。

入侵检测器

伪造值身兼两职:除了替代机密之外,它们还是绊线。一个伪造令牌恰好只有一个合法的目标家族——它所铸造的主机作用域。sk-ant-api03-brm-… 出现在发往 pastebin.example 的请求中是没有任何正当理由的。因此代理服务器扫描每个出站请求——请求头和请求体,通过一个 Aho-Corasick 自动机,足够廉价,可以在所有请求上运行——查找任何发往其作用域之外的伪造值。

当它发现一个时,会将该请求视为企图外泄凭据:

  1. 该请求被 以 HTTP 451 阻止。没有一个字节被转发到目标。
  2. 虚拟机会立即暂停。如果机器原本在后台运行,会先被带到屏幕上,其冻结的画面会染成红色。
  3. 一个严重警告会出现,标题为 此环境可能已被入侵:“Bromure 检测到一次从“机器”向未获授权的主机泄露会话凭据的外发尝试。虚拟机已暂停。”在 检测到的泄露: 下,每次泄露列出一行——令牌预览(例如 sk-a…f9q3)、凭据名称、它原本签发给的主机,以及它被发往的主机。
  4. 这次检测会在安全时间线中记录为红色的 凭据中转 行,在已注册的安装上还会记录为 credential.exfiltration 事件。

警告提供四个按钮:

按钮效果
关机(默认)停止虚拟机,并把机器标记为已被入侵。
阻止只拦下这一个请求(它已收到 451),并恢复虚拟机。不会记住任何内容:如果代理再试一次,检测器会再次触发,警告也会再次打开。
允许仅在本次会话的剩余时间内信任所观察到的主机,并恢复虚拟机。此后凭据会被替换并发往该主机(及其子域名),发往它的请求也不再被标记。这个决定会记录为绿色的 凭据中转 行“allowed by user for this session”,在已注册的安装上还会记录为 credential.exfiltration_allowed。允许列表会在虚拟机关机时清空。
保存以供调查要求选择一个文件夹,导出 disk.img(虚拟机系统磁盘的副本)、home.tar.gz(机器的主目录)以及每个共享文件夹的 shares/<名称>.tar.gz,然后关闭虚拟机并把机器标记为已被入侵。虚拟机的 RAM 状态会被丢弃。

只有 关机 响应回车键;阻止、允许 和 保存以供调查 都没有键盘对应,因此要恢复一台可能具有敌意的虚拟机——更不用说把凭据发给它——始终需要明确点按。一次只显示一个警告;警告打开期间重复的检测会被丢弃(每一次仍会被阻止)。

提示: 允许 是为了正当的跨主机配置而存在——例如某个工具有意把 OpenAI 格式的密钥发往另一个提供方兼容 OpenAI 的端点。如果你不认识该目的地,就不要允许。

如果机器正由远程客户端镜像,问题会以待处理提示的形式出现在客户端上,并提供 关机、阻止 和 允许(保存以供调查需要本地的文件夹选择器,因此只在 Mac 本身上提供)。只有受影响的虚拟机会保持暂停;宿主机会继续为其他所有机器提供服务。无人回应的提示会在 3 分钟后关闭虚拟机。

被标记为已被入侵的机器,在你处理之前会拒绝启动。启动它时会显示 “To continue, the VM disk image and the persistent home folder must be wiped. Your tokens, ssh keys, and workspace settings are preserved.”,并提供 清除并启动 和 取消(回车键不会确认清除)。请留意随附的警告:共享文件夹不会被清除,因此如果入侵是通过共享文件夹中的软件包或文件而来,它可能仍在那里——恢复工作前请先检查这些文件夹。

对攻陷警报的推荐响应:打开追踪检查器(⇧⌘I)或运行 bromure-cli trace leaks 查看违规的主机和请求,判断是项目依赖还是提示注入的指令负有责任(参见提示注入和供应链),然后擦除并重新启动。

作用域细节:

  • 无作用域的伪造值是豁免的。 一个带有空白主机过滤器的手动令牌按设计是"任何主机",因此无法触发检测器;伪造的订阅占位符同样被排除。
  • 第一方同族被容忍。 匹配镜像替换的作用域策略,但有一处放宽:与凭据提供商同处一个已注册域名下的主机(例如 anthropic.com 下的 Claude 或 Codex 基础设施)使用家族匹配,因此一个合法的 api.anthropic.com 令牌出现在 mcp-tools.anthropic.com 上不算误报。其他一切都是严格的。
  • 看起来真实的泄露也会被标记。 独立于伪造绊线,代理服务器会标记出站流量中未替换的、看起来真实的机密——带有已知前缀(sk-ant-、ghp_、AKIA 等)的 Bearer 或 x-api-key 值,或 20 个字符及以上的不透明令牌。这些在追踪检查器和 bromure-cli trace leaks 中显示为泄露警告;它们通常意味着有真实机密被手动粘贴进了 VM,而传输边界的存在正是为了让这变得没有必要。

检测器本身始终开启。你可以按机器关闭的是中断——参见下一节。

应急手段

有些主机和客户端在完整拦截下无法工作:宿主机不信任的私有 CA 服务器、会固定其服务器证书的客户端,或是一再触发入侵警告的正当配置。护栏面板底部的三个按机器设置,能在这些情况下放宽边界而不关闭它。三者都会即时生效,无需重启。

设置默认作用
允许逐请求的不安全绕过 (X-bromure-insecure)开启当发往自签名或私有 CA 主机的请求未通过证书验证时,代理可以带上请求头 X-bromure-insecure: yes 重试,以跳过该上游的证书验证。拦截、追踪和防泄露保护仍然开启,而 Bromure 不会在这类请求中注入任何真实凭据——发出去的只有客户机的伪造值。每次使用都会在安全时间线中记录为 上游 TLS 行:“allowed — certificate validation skipped (X-bromure-insecure); no credentials injected”。默认开启,因为它只在客户机发送该请求头时才起作用;关闭它即可彻底禁止该请求头。
停用透明拦截关闭停止把虚拟机的 HTTP/HTTPS 强制转向 Bromure 的网络层转向。原始套接字和固定证书的客户端会因此直接连到真实网络和真实的上游证书。代理服务器本身仍保留:HTTP(S)_PROXY 依然设置,因此遵循代理设置的工具(apt、git、pip、curl、node…)以及代理自己的 API 调用仍会经过 Bromure,并保留凭据替换、追踪和护栏。忽略代理设置的流量则不再受出站规则约束。
凭据外泄时不弹出警报关闭抑制入侵警告和虚拟机暂停。正在泄露的请求仍会以 451 阻止,也仍会记录在安全时间线中(“blocked — exfiltration attempt (alerts off, VM not paused)”);消失的只有中断。

警告: 这些设置都是以部分保护换取兼容性。请优先选择范围最窄的:针对单个不受信任的证书使用逐请求的请求头,针对单个受信任的目的地使用入侵警告中的 允许,而整台机器的开关只用于别无他法的机器。

机密在宿主机上的存储位置

所有敏感内容都在一个每次安装独立的 256 位主密钥下以 AES-GCM 静态加密——即机密保管库。主密钥存放在 macOS 数据保护钥匙串 中,作用域限定为应用的签名身份,可访问性为 kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly 且 iCloud 同步已禁用。它从不提示、从不同步,也绝不离开 Mac。如果钥匙串不可达(未签名或未预配的构建),应用会回退到存放在密文旁边的一个 mode-0600 密钥文件——较弱,因为此时密钥和密文共享一个磁盘,但它保持静态加密正常运作;一个完全预配的发行版使用钥匙串。

实际影响:

  • 备份和副本是密文。 一个 Time Machine 备份或一个复制的 Application Support 文件夹只包含加密的数据块;没有这台 Mac 的钥匙串条目就无法解密它们(除非使用了文件回退密钥并一并复制了)。
  • 擦除钥匙串条目会轮换密钥。 现有的加密数据块变得不可读,你需要重新输入凭据。profile.json 中的非敏感元数据不受影响。
  • 没有任何东西被同步到任何地方。 应用本身不会上传、同步或备份任何凭据、令牌存储或密钥材料。

磁盘上的位置,除另有说明外均在 ~/Library/Application Support/BromureAC/ 下:

位置内容
ca/cert.pem、ca/key.pemBromure Agentic Coding Root CA(密钥 mode 0600)。删除该目录以轮换。
fake-salt.bin伪造派生背后的每次安装独立 32 字节 HKDF 盐(0600)。删除它会轮换这台 Mac 上的每个伪造值。
claude-subscription.enc、codex-subscription.enc、grok-subscription.enc、kimi-subscription.enc用 AES-GCM 加密的订阅存储:共享登录加上每台机器自己的登录,0600。
models.enc偏好设置 › 模型 的全局模型设置,包括提供方的 API 密钥,用保险库密钥加密。
pii/<workspace-id>.key个人数据保护替身值背后、每台机器专属的密钥(0600)。
secrets-master.key0600 的回退主密钥——仅当数据保护钥匙串不可达时才存在。
default-ssh/id_ed25519.raw、default-ssh/id_ed25519.pub共享的默认 SSH 密钥对,会拷贝到新机器中。
profiles/<id>/ssh/为每台机器签发的 SSH 密钥(代理目录)。
钥匙串:io.bromure.agentic-coding.master-keyAES-256 保管库主密钥(账户 v1),数据保护钥匙串。
钥匙串:io.bromure.agentic-coding.ssh-key-passphrases导入的 SSH 密钥口令,每个配置文件/密钥文件一项。

用于导入的宿主机侧读取——~/.aws/config、~/.aws/sso/cache/*.json、~/.docker/config.json、kubeconfig 文件——仅在宿主机上发生;这些文件都绝不会挂载到 VM 中。加密的追踪请求体(参见追踪)使用相同的保管库密钥。

自行验证边界

传输边界的设计是可核查的,而不是靠信任。从任何会话内部的 shell:

1. 环境持有伪造值。

echo "$ANTHROPIC_API_KEY"
# sk-ant-api03-brm-…            ← a fake, not your key

env | grep -E 'TOKEN|KEY' 
# every value is brm_/ghp_/glpat_/dop_v1_/lin_api_-shaped placeholder

2. 配置文件持有伪造值。

cat ~/.git-credentials          # fake tokens per git host
cat ~/.docker/config.json       # fake base64 auth blobs
grep -A2 credential_process ~/.aws/config   # helper, not a secret key

3. 然而,一切都能工作。

aws sts get-caller-identity     # succeeds — the host resigned the request
gh api user                     # succeeds — the fake was swapped on the wire

4. VM 内部的 TLS 终止于代理服务器。

openssl s_client -connect api.anthropic.com:443 -brief 2>&1 | head
# issuer: the Bromure Agentic Coding Root CA — not a public CA

5. SSH 密钥不存在,但签名有效。

ssh-add -L                      # lists public keys served by the vsock agent
ls ~/.ssh/id_*                  # no private key files to find

6. 在宿主机上观察替换的发生。 打开安全时间线并按 凭据中转 筛选:每次替换都会显示为类似 sk-a…f9q3 → api.anthropic.com — swapped in … 的一行。如果已为该机器开启追踪,你还可以运行:

bromure-cli trace summary        # per-request swap reports and leak warnings
bromure-cli trace leaks          # only the suspicious ones

或打开追踪检查器(⇧⌘I),在其中被替换的请求会被标注为 绝不发送到 VM——由代理服务器替换。

如果你曾在 VM 内部发现一个真实凭据,它只可能通过两种方式到达那里:你(或代理,在你的指示下)手动把它粘贴进去,或者它通过共享文件夹到达。替换机制从不将真实值写入客户机——而入侵检测器把传输线路上看起来真实的机密视为泄露,正是因为它们本不应该存在于那里。

快速参考

客户机-宿主机边界上的 vsock 端口:

端口用途
8443HTTPS MITM 代理服务器——客户机的全部出口。
8444SSH_AUTH_SOCK 背后的 ssh-agent 桥接。
8445AWS credential_process 助手。
8446注册虚拟机使用的 Claude 令牌通道——它与本地推理桥接共用此端口(两者在不同的流程中建立;参见模型与提供方)。
8447注册虚拟机使用的 Codex 令牌通道(访问、刷新和 ID 令牌)。

两条令牌通道都是单向的:宿主机只能把伪造值写入虚拟机,而虚拟机只能把真实值发给宿主机。不存在任何能让虚拟机把真实令牌要回去的请求。

相关的 CLI 命令(完整参考见 CLI、API 与 MCP):

命令用途
bromure-cli workspaces create --auth token|subscription|bedrock|local以其主代理的认证模式创建工作区。
bromure-cli vm run --auth token|subscription|bedrock|local启动虚拟机,并为临时创建的工作区选择认证模式。
bromure-cli workspaces ssh-keygen <workspace>在宿主机侧铸造一个新鲜的工作区 SSH 密钥并打印公钥。
bromure-cli trace summary [workspace]汇总被追踪的流量,包括替换和泄露警告。
bromure-cli trace leaks [workspace]显示带有潜在凭据泄露的被追踪请求。