近年来,大模型应用普遍需要同时对接多家模型服务,每接入一家就要保管一把“钥匙”(API 密钥)。某周下载量数千万级的开源大模型代理组件在七个月内两度遭遇供应链投毒,攻击目标直指其集中托管的全组织模型密钥与各类云凭证。“钥匙串该放在哪里、被偷了怎么办”由此成为行业必须回答的问题。本文围绕这一主题展开定义式解析。
一、概念定义:什么是大模型的“钥匙串”
“大模型的钥匙串”是对一类通用能力的形象说法:把组织内访问各家模型服务所需的全部凭据(模型服务的 API 密钥、云平台访问凭证、容器集群令牌等),从业务应用中剥离出来,集中交由一个独立接入层统一保管与使用。这个接入层通常称为大模型网关或 LLM 代理。
可以从三个视角理解它:
- 技术视角:一套覆盖“存储—注入—隔离—审计—轮换”全生命周期的凭据管理机制;
- 业务视角:把“每人一把钥匙”收敛为“全局一套钥匙串”,配额、成本、调用记录可以统一核算;
- 使用视角:业务代码里看不到任何厂商密钥,只持有一个面向内部的访问凭证。
它要解决的是密钥管理的四类顽疾:硬编码与散落导致泄露面扩大、轮换需要改动多处、内部越权滥用难以约束、泄露后无法快速止损与追溯。
二、背景与价值:为什么“钥匙串”会成为攻击目标
以一次典型事件为背景(以下均为中立化复盘):某开源大模型代理组件先后在 3 月与 10 月遭遇两次供应链投毒,间隔约七个月。两次攻击窃取的目标高度一致——云平台凭证、远程登录私钥、容器集群令牌,以及该组件替使用方集中托管的全组织模型密钥。有安全研究机构观察到,恶意版本发布后不到五小时,攻击者已开始用窃得的云凭证枚举云上模型服务资源。
第二次事件的攻击链可拆为四步,其“走完正规流程”的特征尤其值得警惕:
- 获取钥匙:攻击者拿到多名维护者的命令行工具访问令牌,据分析可能与一个对公网开放的内部部署实例的日志泄露有关;
- 改写发布流程:先尝试修改发布流水线被分支保护拦截,几秒后用高权限令牌强行覆盖保护;改过的流水线不再从官方源码库取代码,而是从一个名称仅差一个连字符的仿冒仓库构建;随后用第二个账号的凭证“通过”了发布审批,完成后再用第三个账号删除流水线运行记录;
- 只毒制品,不毒源码:源码完全干净,恶意改动藏在构建配置里——多了一行打包声明,使数个文件在依赖安装时被写入运行环境的扩展目录。其中一个是解释器启动钩子,任何脚本、包管理命令、开发工具启动时都会自动执行,即使用户从未显式引用被投毒的组件;另一个负责解压并运行数十 KB 的窃密程序;还有一个将恶意进程与终端会话分离、转入后台驻留;
- 快速变现:利用窃得凭证直接操作云上资源。
由此得出两个关键结论:
- 集中托管是把双刃剑:密钥集中确实便于管理,但也让“钥匙串”本身成为高价值单点,托管机制必须同时回答“被偷了怎么办”;
- 流程正确不等于内容安全:审批没有被绕过,而是被盗来的凭证“合法”通过;源码是干净的,有毒的只是构建产物。防御思路必须从“防人作恶”升级为“假设入侵必然发生,如何让恶意代码进来之后什么也拿不到”。
三、核心组成:一套完整的“钥匙串”包含哪些能力
- 密钥集中存储与加密:凭据静态加密存储、与普通配置隔离、按版本管理,支持导入、更新与吊销;
- 受控注入:业务请求到达网关后,网关按路由规则动态附加对应上游密钥再转发;业务侧只见内部凭证,真实密钥只出现在网关进程内存中;
- 隔离执行环境(插件沙箱):网关的扩展能力(鉴权、限流、请求改写等插件)运行在受限沙箱中,默认没有文件系统访问、读不到环境变量、出网需显式授权。业界常见做法是基于 Wasm 等字节码技术实现此类沙箱,使恶意插件即使被加载也“无物可偷”;
- 不可变发布:网关自身及其扩展以内容固定的制品形式发布,通过内容摘要与签名校验分发,不依赖 latest 这类可变标签,制品一旦构建完成即不可被替换;
- 审计与应急:全量调用日志、密钥使用记录、异常告警,以及泄露后分钟级的轮换与吊销流程。
四、工作原理:从请求链路看攻击面如何收缩
正常链路可用如下示意代码表达:
# 业务侧:不含任何模型厂商密钥client = GatewayClient(endpoint="https://gw.internal", token=INTERNAL_TOKEN)resp = client.chat(model="model-a", messages=[...])# 网关侧(示意)route = pick_route(model) # 选择上游模型服务key = vault.get(route.provider) # 密钥只在网关内出现audit.log(user, route, token_usage)forward(route, req, auth=key) # 附加真实密钥后转发
对照前述攻击链,各机制逐层收缩攻击面:
- 沙箱隔离:解释器钩子这类“安装即执行”的手法之所以致命,是因为恶意代码继承了宿主进程的全部权限;扩展改为在沙箱中运行后,恶意代码读不到环境变量中的密钥、翻不了文件系统里的配置;
- 不可变发布:投毒改的是构建产物,且借助可变标签让用户拉到被替换的镜像。以内容摘要锁定版本、以签名校验来源,可使“产物被悄悄换掉”与“标签漂移”两类手法同时失效;
- 凭证分级:业务侧持有的是可独立吊销的内部凭证,上游厂商密钥不出网关,单一应用失陷不会导致全组织密钥外泄;
- 最小权限与审计:发布令牌分级、短时效、可追溯,敏感操作双人复核,流水线日志防篡改,显著提高“盗一个令牌走完全流程”的难度。
五、典型场景
- 多模型统一接入:一个入口对接多家模型服务,统一鉴权、限流与重试,业务无需感知上游差异;
- 企业内多团队共享:密钥不落入个人代码仓库与开发机,配额按团队分配与回收;
- 合规与成本核算:谁在何时调用了哪家哪个模型、消耗多少,可审计、可计费;
- 轮换与应急响应:某家密钥疑似泄露时,仅在网关处更换一处即可全局生效;
- 灰度与故障切换:上游异常时按路由策略切换模型或密钥池,保障业务连续性。
在云上落地时,可结合云平台提供的密钥管理、日志审计、监控告警、身份认证等通用能力协同建设(包括百度智能云在内的主流云平台均提供此类基础能力)。
六、相关概念区别
- 网关密钥托管 vs 环境变量/配置文件:后者密钥仍在应用进程可达范围内,任何能读取环境变量的代码(包括被投毒的依赖)都可窃取;托管后密钥对业务进程不可见;
- 网关托管 vs 密钥管理服务(KMS):KMS 提供存储、加解密与访问控制等底层能力;“钥匙串”是面向模型接入场景的上层方案,通常以 KMS 作为存储底座,再叠加注入、路由、沙箱与审计;
- 沙箱插件 vs 进程内插件:进程内插件与网关同权限,一旦被投毒即可读取全部配置;沙箱插件按能力最小授权;
- 不可变制品 vs 可变标签:可变标签指向谁由发布方随时决定;不可变制品以内容摘要寻址,“所见即所验”;
- 大模型网关 vs 传统 API 网关:后者面向通用接口治理,前者还需理解模型协议语义,如 token 计量、多模型路由、密钥池与配额管理。
七、使用注意事项
- 集中不等于安全:托管会把风险聚拢,必须叠加最小权限、令牌分级、短时效与双人复核;
- 供应链校验:锁定依赖版本与内容摘要、校验签名、避免盲目跟随可变标签;构建流水线从可信源码地址取源,警惕名称高度相似的仿冒仓库;
- 扩展治理:第三方或自定义插件一律放入沙箱按需授权,禁止默认访问文件系统与环境变量;
- 凭证卫生:不要把生产密钥写入流水线日志;对公网暴露的内部服务要警惕日志中残留的敏感令牌——前述事件中维护者令牌即疑似由此泄露;
- 泄露预案:预设密钥轮换与吊销流程,确保分钟级生效;日志集中保存且防篡改,支持事后回溯;
- 可用性与性能:网关成为所有模型流量的关键路径,需高可用部署、容量规划与降级策略。
八、总结
回到最初的问题:大模型的“钥匙串”该放在哪里?答案是一个组合:放在独立于业务的接入层集中托管,让业务侧只见内部凭证;用沙箱把能碰到钥匙串的代码关进最小权限的笼子;用不可变发布保证拿到手的制品就是验证过的制品。集中托管解决“不散落”,沙箱与不可变发布解决“被偷了也拿不到、换不掉”。对多模型、多团队、强合规的组织而言,这套机制收益最大;规模较小的团队至少也应从规范的环境变量管理、依赖摘要锁定与插件最小权限做起。两次间隔仅七个月的投毒事件已经证明:投毒不是会不会发生的问题,而是何时发生、发生之后你准备让它拿到什么的问题。