OpenCode 泄露事件:用 Synthorai 可信 IP 阻断泄露的 API 密钥

目录
  1. OpenCode Console 泄露事件经过
  2. 泄露的是哪类密钥,哪些措施能起作用?
  3. Synthorai 如何保护平台密钥和 BYOK 密钥?
  4. 可信 IP 如何阻断泄露密钥的使用?
  5. 消费上限如何控制密钥被盗后的损失?
  6. 这些措施无法阻止什么?
  7. BYOK 密钥应在供应商侧设置什么?
  8. OpenCode 可以配合 Synthorai 使用吗?
  9. 常见问题

2026 年 10 月 17 日,OpenCode 通知用户,入侵者访问了其托管服务 OpenCode Console 背后的一个旧系统,保存在其中的第三方供应商密钥“可能已泄露”。随后,有用户反映,自己的 OpenAI、Anthropic 和 Google 账户产生了数百美元到 $1,700 的费用。供应商密钥就是从 OpenAI 或 Anthropic 等供应商处获取的 API 密钥。将它存入托管工具,让工具代你调用供应商,这种方式称为 BYOK(bring your own key,自带密钥)。密钥泄露后会造成多大损失,取决于两件事:它能从哪里使用,以及在被阻止之前能花掉多少钱。

TL;DR

  • OpenCode 表示,Console 泄露事件影响了 1.4% 的 Console 用户;保存在本地 OpenCode CLI 中的密钥不受影响。
  • 网关的 IP 规则和消费上限只能管到经过网关的流量,因此供应商密钥一旦泄露,需要靠供应商侧的硬性限额兜底。
  • 开启“新 IP 需审批”后,Synthorai 会拒绝来自未经该密钥批准的地址的调用,返回 HTTP 403 和 ip_not_trusted。
  • 每个 Synthorai 密钥都可以设置消费上限、每分钟请求数和 token 数上限,以及到期时间。

OpenCode Console 泄露事件经过

OpenCode 在发给受影响用户的邮件中称,未经授权的第三方访问了“一个正在下线的旧系统”,这些用户保存在 Console 工作区中的供应商密钥可能已被读取。OpenCode 给出的最早可能泄露时间是 10 月 17 日 00:30 UTC。根据 OpenCode 的公开消息、供应商员工的帖子和媒体报道,事件经过如下:

时间(UTC)事件
10 月 17 日,约 06:00据一名用户描述,其密钥开始产生费用:OpenAI 为 $281,Anthropic 为 $168
10 月 17 日,上午OpenCode 向受影响用户发送邮件,要求在各供应商处撤销密钥,并检查近期用量
10 月 17 日,18:08OpenCode 在 X 上发文:此次泄露“与大规模蒸馏攻击有关”,影响了 1.4% 的 Console 用户
10 月 17 日,晚间Anthropic 撤销了其认为受影响的 Claude API 密钥;Google 封禁了泄露的密钥
10 月 19 日OpenAI 表示,已与 OpenCode 合作为受影响客户恢复服务,并退还攻击消耗的额度

蒸馏攻击是指大规模收集一个模型的回答,用于训练另一个模型。盗用密钥是此类行动支付调用费用的一种方式。OpenCode 尚未解释此次入侵与蒸馏之间的关系。联合创始人 Dax Raad 表示,此次事件涉及的是“OpenCode Console,而非 OpenCode 本身”,通过本地 CLI 添加的密钥从不会发送到公司。截至 10 月 21 日,OpenCode 尚未公布根本原因、存储的密钥是否加密、1.4% 对应的受影响账户数量、赔偿政策或事后复盘(The Hacker News、BleepingComputer)。

泄露的是哪类密钥,哪些措施能起作用?

此次泄露的是供应商密钥。攻击者拿到这类密钥后,会直接调用供应商,而不是经过存储密钥的工具。这也限制了 LLM 网关能发挥的作用。网关位于你的代码和模型供应商之间,负责转发请求,因此只能看到并限制经过它的流量。需要区分以下两类密钥:

密钥可能泄露的位置可阻断滥用或控制损失的措施
你持有的网关密钥(Synthorai 的格式为 sk-syn-...)代码、CI 日志、笔记本电脑、配置文件网关的 IP 规则、消费上限、速率限制、到期时间
保存在托管服务中的供应商密钥(BYOK)服务自身的系统,例如此次 OpenCode 事件只能依靠供应商:撤销密钥,以及供应商的消费上限

接下来两节介绍的可信 IP 和消费上限保护的是第一类密钥。对于第二类密钥,最后一道防线是在 OpenAI、Anthropic 或 Google 设置的硬性限额;后文会列出这些设置。

Synthorai 如何保护平台密钥和 BYOK 密钥?

添加到 BYOK 密钥库的供应商密钥,使用标准认证加密算法 AES-256-GCM 加密存储。保存后,任何 API、MCP 工具或控制台页面都不会再返回完整密钥,控制台只显示最后四个字符。网关仅在处理使用该密钥的请求时,在内存中解密密钥;只有工作区所有者可以添加、轮换或删除密钥。Synthorai 为自身服务容量使用的供应商密钥也采用相同的存储方式,任何控制台页面或 API 都不会显示这些密钥,管理员控制台也不例外。加密可以保护数据库副本,但运行中的服务一旦被攻破,攻击者仍可能接触到正在使用的密钥。因此,下文介绍的供应商侧限额仍是 BYOK 密钥的最后一道防线。

Synthorai 发给你的 API 密钥只以哈希形式存储。哈希是单向指纹,无法从中还原密钥。完整密钥只在创建时显示一次;此后无论通过控制台、管理 API 还是 MCP 服务器读取,都只返回前缀。推理密钥只能调用模型,不能执行其他操作:管理 API 不接受这类密钥,因此被盗的推理密钥无法读取日志、用量或其他密钥 (API keys, admin keys)。

可信 IP 如何阻断泄露密钥的使用?

可信 IP会拒绝来自未经该密钥批准的地址的 API 调用。因此,即使有人从 CI 日志或笔记本电脑中复制了密钥,从其他地址使用时也只会收到错误,而不是模型回答。所有者或管理员可在“设置 › 安全”中开启“新 IP 需审批”。弹窗会列出过去七天内各密钥的调用来源地址,默认全部勾选为批准。确认前请检查列表,取消勾选不认识的地址:如果密钥已经泄露并被使用,攻击者的地址也会出现在列表中。

设置中的安全选项卡:已开启“审批新 IP”,可信 IP 列表显示各密钥的调用来源地址、位置、密钥和客户端、最后出现时间,以及是否受信任

此后,来自新地址的调用会返回 HTTP 403(这里的地址仅用于文档示例):

{
  "error": {
    "type": "permission_error",
    "code": "ip_not_trusted",
    "ip": "203.0.113.9",
    "message": "Requests from IP address 203.0.113.9 are held until this address is approved for the key. ...",
    "approve_url": "https://synthorai.io/console/settings?tab=security"
  }
}

密钥创建者会收到邮件,其中包含来源地址、位置、客户端和请求的模型。审批必须登录控制台后完成,因此转发邮件本身不会批准任何地址。审批可以只针对一个地址,也可以批准其所在的 /24 网段(256 个相邻的 IPv4 地址),以适应地址会变化的客户端。网关使用自身代理从连接中看到的调用方地址,客户端无法通过自行发送 X-Forwarded-For 标头来冒充其他地址(代理使用该标头传递原始客户端地址)。我们用伪造标头做过验证,拒绝响应中显示的仍是真实地址。

# From an address not yet approved for the key, with a forged header:
curl -s https://synthorai.io/v1/models \
  -H "Authorization: Bearer $SYNTHORAI_API_KEY" \
  -H "X-Forwarded-For: 203.0.113.9"
# The 403's "ip" field is the caller's real address, not 203.0.113.9.

创建密钥时也可以设置固定的 ip_allowlist,但这份列表属于密钥配置:每增加一个办公室、服务器或 VPN 出口,都需要修改密钥;忘记删除的条目则会一直放行。可信 IP 以密钥现有的调用来源地址为起点,信任新地址前先要求审批,并将所有密钥的地址集中在一个列表中,已知地址只需点击一次即可设为可信。如果密钥设置了自己的白名单,就只按该白名单判定,因此每个密钥应在这两种方式中选择一种。

信任关系按密钥隔离。如果无服务器函数和 CI runner 每次运行都从新地址发起调用,每次都会等待审批。不要信任托管 CI 供应商公布的整个地址范围:这些地址由该供应商的所有客户共享,任何人在那里运行任务都能通过检查。应让这些调用方通过固定出口访问,例如自托管 runner 或 NAT 网关,再信任该出口地址;或者为它们分配有效期短、限额低的密钥。

消费上限如何控制密钥被盗后的损失?

每个 Synthorai API 密钥都可以单独设置消费上限,即使密钥仍然泄露,也会在达到你设定的金额后停止调用。创建密钥时,可在控制台设置限额、允许使用的模型和到期时间:

创建 API 密钥弹窗:名称为 support-bot prod,允许的模型为 claude-haiku-5-5,每日重置的 50 USD 额度上限,到期时间,空 IP 白名单,以及将 BYOK 调用计入限额的开关

单密钥速率限制及以下其他设置通过管理 API 配置:

设置作用
limit_usd 和 limit_reset以美元计的消费上限,可设为不重置、每日、每周或每月重置;达到上限后,该密钥的调用会被拒绝,直到限额重置
rate_limit(rpm、tpm)该密钥每分钟的请求数和 token 数上限
allowed_models该密钥唯一允许调用的模型
ip_allowlist允许使用该密钥的固定地址或网段列表(例如 198.51.100.0/24),适用于地址范围不变的调用方
expires_at密钥失效的时间
include_byok_in_limit使用你自己的供应商密钥执行的请求是否计入限额

下面使用管理员密钥,为一个服务创建仅满足该服务需求的密钥。管理员密钥属于管理密钥,可以创建密钥并设置限制,但不能调用模型:

curl https://synthorai.io/api/v1/keys \
  -H "Authorization: Bearer sk-syn-admin-..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "support-bot prod",
    "limit_usd": 50,
    "limit_reset": "daily",
    "rate_limit": {"rpm": 60, "tpm": 200000},
    "allowed_models": ["claude-haiku-5-5"],
    "expires_at": "2027-01-31T00:00:00Z"
  }'

工作区所有者还可以为每个成员设置每日和每月消费上限。成员达到月度上限后,会收到 HTTP 402,直到下个月。这些限制只适用于经过 Synthorai 的流量。如果将 BYOK 计入限额,经网关发起的 BYOK 请求也受限制,但泄露后被直接使用的供应商密钥不在此范围内。

这些措施无法阻止什么?

可信 IP 可以阻止从新地址使用密钥,但如果密钥是在受信任的机器上使用,它就不起作用。最常见的盗用恰恰发生在这些地方:开发者笔记本电脑上的恶意软件、被攻破的 CI 任务,或被诱导替攻击者发送请求的服务器。对此,能控制损失的是密钥的消费上限、模型列表和较短的有效期。

审批由人决定,因此攻击者可以故意触发一条待审批请求,寄希望于审批者习惯性放行。审批页会显示地址、位置、客户端和模型;只有这些信息与你实际发起的调用一致时,才应批准。

每日重置的消费上限,意味着被盗密钥可以每天花到上限,直到有人发现。限额需要配合检测:每个待审批地址对应的邮件、控制台中的单密钥消费数据,以及密钥变更审计日志。怀疑密钥泄露时,在控制台删除它并创建替代密钥。要在泄露前发现密钥,可在代码托管平台中为 sk-syn- 前缀添加机密扫描规则,例如启用推送保护的 GitHub 自定义模式。

BYOK 密钥应在供应商侧设置什么?

为每个工具分配独立的供应商密钥,放在独立的项目或工作区中,并设置硬性消费上限。这样,即使某个密钥泄露,也只能花掉该项目的预算。泄露的密钥必须在供应商控制台中撤销:从存储它的工具中删除,并不会使它失效。这三家供应商都不支持对单个密钥设置限额,最小单位是项目或工作区:

供应商密钥可隔离的最小单位硬性限额
OpenAI项目每月项目消费上限,并开启“强制执行硬性限额”;可能略微超额,之后调用返回 429 project_spend_limit_exceeded
Anthropic工作区每月工作区消费上限;达到上限后调用返回 400 invalid_request_error。默认工作区无法设置该限额,因此不要将密钥放在默认工作区
Google(Gemini API)Cloud 项目结算账户分级限额会暂停所有关联项目,直到下个月;项目消费上限仍处于实验阶段,可能持续超额约 10 分钟

只发送邮件的消费提醒和预算无法阻止正在进行的攻击,但可以保留,作为硬性限额之外的第二种告警信号。Synthorai 控制台的 BYOK 页面在密钥下方提供了各供应商限额设置的链接:

BYOK 页面中的供应商密钥卡片:列有 Anthropic、Amazon Bedrock、OpenAI、Qwen Intl 和 Google Vertex AI,下方提供 Anthropic、OpenAI 和 Google Vertex AI 硬性消费上限设置的链接

OpenCode 可以配合 Synthorai 使用吗?

可以。本地 OpenCode CLI 使用的密钥保存在你的机器上,这种用法不受此次泄露影响。运行 opencode auth login https://synthorai.io 后,OpenCode 会通过浏览器和一次性验证码完成登录,并获得一个独立的 API 密钥,有效期可选 7、30 或 90 天(配置指南)。如果已开启“新 IP 需审批”,且你在同一网络中批准登录,该登录来源地址会自动成为此密钥的可信地址,其他地址的调用则需要等待审批。如果登录请求与浏览器来自不同网络,确认页会发出警告,该地址也不会自动受信任,必须等首次调用获批。如果命令不是你自己运行的,请取消请求。

OpenCode 登录确认页:终端应显示的验证码、请求来自其他网络的警告、请求地址和客户端、工作区、7、30 或 90 天的密钥有效期选项,以及取消和允许按钮

该密钥会以“OpenCode”的名称出现在 API 密钥页面,你可以在那里添加消费上限或删除密钥。笔记本电脑上的密钥仍可能被本机恶意软件窃取,因此建议选择 7 天或 30 天有效期,并保持“新 IP 需审批”开启:即使密钥被复制,也无法从其他地址使用,而且很快就会到期。

常见问题

保存在 OpenCode CLI 中的密钥是否在此次事件中泄露?

没有。OpenCode 表示,此次泄露仅涉及 OpenCode Console。通过本地 CLI 或桌面应用添加的密钥保存在用户机器上,从不会发送给 OpenCode。

从托管工具中删除供应商密钥,会撤销密钥吗?

不会。从工具中删除密钥,只会删除工具持有的副本。密钥在供应商处仍然有效,你需要在供应商控制台中撤销它,并创建新密钥。

网关的消费上限能保护已泄露的供应商密钥吗?

不能。网关的限额只统计经过网关的请求,而泄露的供应商密钥会被直接用于调用供应商,因此真正起作用的是供应商自身的消费上限。

相关文档:可信 IP、BYOK 密钥库、管理员密钥与密钥限额、OpenCode 配置。

资料查阅日期为 2026 年 10 月 21 日:包括媒体引用的 OpenCode 帖子和邮件、供应商员工的帖子,以及上文链接的供应商文档。伪造标头测试于 2026 年 10 月 21 日在 Synthorai 生产网关上进行。

← 返回博客