多人共用一把 key 的审计:没有独立登录时怎么把请求归到人
当团队共用一个 LLM API key 时,日志中所有请求的凭据都是同一个,无法直接区分是谁调用的。本文介绍几种实用的打标签和审计方法,包括端侧标识注入、代理层解析、请求头与元数据埋点,以及如何在不改变现有聚合服务的前提下建立可追溯的请求归属体系。
为什么共用一把 key 会让审计变得困难
在 LLM API 聚合站中,一个 API key 通常对应一个账户。当团队共用一个 key 时,服务端看到的只是同一个 key 发出的请求,无法天然区分具体是哪位成员、哪个服务或哪个脚本调用的。
这带来的问题包括:
- 出现异常用量或费用时,无法快速定位来源。
- 需要按项目或人员分摊成本时,缺少原始依据。
- 安全事件回溯时,无法确认是谁在什么时间发起了某个请求。
解决思路不是去改造聚合站的认证体系,而是在请求本身上附加可识别的信息,并在日志链路中保留下来。
方法一:在请求中注入调用者标识
最直接的方式是在每次 API 调用时,通过请求头或请求体携带一个调用者标识。
使用自定义请求头
大多数 LLM API 兼容的客户端都支持自定义 header。例如:
X-Caller-Id: alice
X-Project: chatbot-prod
X-Request-Source: backend-service-a
这些 header 会随请求一起到达聚合站。如果聚合站支持日志记录原始请求头,或者你能在中间加一层代理,就能在日志中看到这些字段。
在 prompt 或元数据中埋点
如果无法控制 header,也可以考虑在请求体中附加不影响模型的元数据字段。部分 API 支持 metadata 或 user 字段,用于传递终端用户标识。即使模型不消费这些字段,它们也可能出现在请求日志中。
注意:不要将敏感信息放入这些字段,因为它们可能被记录和存储。
方法二:通过代理层统一打标
如果团队成员直接调用聚合站,要求每个人都手动加 header 容易遗漏。更可靠的做法是在团队内部部署一个轻量代理,所有请求先经过代理,再由代理解析并附加标识。
代理层可以做到:
- 根据来源 IP、子网或认证 token 识别调用者。
- 自动注入统一的请求头。
- 记录请求日志,包含时间、调用者、模型、token 用量等。
- 将日志转发到集中式日志系统。
这样,聚合站收到的仍然是同一个 key 的请求,但代理层已经独立保存了一份带归属信息的日志。
方法三:拆分 key 但不拆分账户
如果聚合站支持一个账户下创建多个 API key,可以为每个成员或每个项目分配独立的子 key。这样服务端日志天然就能区分来源。
这种方式的优点是:
- 无需修改客户端代码。
- 归属信息由服务端保证,不依赖调用者自觉。
- 可以单独吊销某个子 key,而不影响其他人。
如果聚合站不支持子 key,可以考虑用多个账户,但那样会失去统一计费和统一管理的便利。
方法四:在应用层记录调用上下文
除了在 API 请求上打标,应用层本身也应该记录每次调用的上下文。这包括:
- 调用时间戳
- 调用者身份(来自应用自身的认证体系)
- 使用的模型名称
- 请求的用途或业务场景
- 关联的请求 ID
将应用层日志与 API 请求日志通过请求 ID 关联起来,就能在事后完整还原一次调用的来龙去脉。
日志关联与查询
打标签只是第一步,要让审计真正可用,还需要保证日志可查询。建议:
- 为每次请求生成唯一的请求 ID,并在应用日志和代理日志中都记录。
- 将日志集中存储,支持按调用者、时间范围、模型等维度检索。
- 保留足够的日志时长,以便事后回溯。
- 对日志中的敏感信息进行脱敏处理。
权衡与注意事项
- 标识的可靠性:调用者自己填写的标识不可信,适合内部协作场景,不适合安全审计。如果要求强归属,应使用代理层或子 key 方案。
- 性能影响:增加代理层会引入额外延迟,需要评估是否可接受。
- 隐私合规:记录调用者标识和请求内容时,注意遵守团队内部的隐私政策和相关法规。
- 与聚合站的兼容性:不同聚合站对自定义 header 和元数据的支持程度不同,实施前应确认日志中是否真的会保留这些字段。
总结
共用一把 API key 时,审计的关键不在于改变聚合站的认证方式,而在于在请求链路中附加可追溯的标识,并确保这些标识最终进入可查询的日志。
选择哪种方法取决于团队规模、安全要求和现有基础设施。对于小团队,约定统一的请求头可能就够了;对于需要严格归属的场景,代理层或子 key 是更可靠的方案。无论哪种方式,核心都是让每一次调用都能在事后被归到具体的人或项目。