文章

LLM API 凭证治理生产实战:用 Workload Identity、短期令牌与最小权限减少静态 Key 暴露

本文讲解如何为生产级大模型调用建立无静态密钥的凭证体系,覆盖工作负载身份、短期令牌、最小权限、租户隔离、轮换回退、审计告警与应急撤销,降低密钥泄漏、权限扩散和异常账单风险。

大模型应用通常先从一个环境变量开始:OPENAI_API_KEY、云厂商访问密钥,或者某个模型平台的项目级 Token。原型阶段这样做很快,但进入多环境、多租户和多供应商架构后,长期静态密钥会带来三个致命问题。

为什么 LLM API Key 会成为生产系统的薄弱点

第一,凭证生命周期远长于一次推理请求。 密钥一旦出现在代码仓库、客户端、日志、CI 变量导出或故障排查包中,攻击者可能持续调用模型,直到团队发现异常并主动撤销。

第二,身份与调用主体脱节。 多个服务共享同一个 Key 后,供应商只能看到”这个 Key 调用了模型”,无法可靠区分是哪个工作负载、哪个租户或哪次发布产生的请求。

第三,密钥泄漏会直接转化为费用和可用性风险。 攻击者不需要进入核心数据库,只要拿到模型凭证,就可能消耗配额、触发账单、挤占速率限制,并造成正常业务被限流。

OpenAI 的官方安全建议明确要求不要把 API Key 部署到浏览器或移动端、不要提交到代码仓库,并建议使用 Key Management Service、监控用量、及时轮换以及配置 IP allowlist。对于支持云身份的模型服务,则应进一步减少长期密钥的存在时间。

核心原则:把”密钥”改造成”可验证的工作负载身份”

生产级凭证体系不应让每个业务服务自行保存供应商密钥,而应拆成四个层次:

  1. 工作负载身份:运行中的 Pod、VM、函数或作业拥有可验证的机器身份。
  2. 令牌交换或临时凭证:身份系统根据目标资源、作用域和策略签发短期令牌。
  3. 模型调用授权:模型平台只允许指定主体调用指定模型、区域或部署。
  4. 审计与撤销:记录主体、目标资源和授权结果,但不记录令牌本身。

可以把调用链抽象为:

Workload Identity
       |
       v
Identity Provider / STS
       |
       v
Short-lived Credential
       |
       v
LLM Endpoint with Least Privilege

这里的关键不是把静态 Key 换成另一个更复杂的静态 Secret,而是让凭证具备三个属性:短生命周期、目标受限、主体可追踪

OAuth 2.0 Token Exchange 的 RFC 8693 定义了通过 Security Token Service 交换安全令牌的标准机制。客户端可以声明目标 resource、audience 和 scope,由授权服务器签发适用于下游服务的令牌。这类机制正是跨云工作负载身份和短期访问令牌的基础。

三种生产落地模式

模式一:模型平台原生支持工作负载身份

这是优先级最高的方案,因为应用进程不需要接触长期供应商密钥。

Azure OpenAI 可使用 Microsoft Entra ID 和 Managed Identity。运行在 Azure VM、函数、容器或其他支持资源上的应用,可以通过 DefaultAzureCredential 获取 Entra Token,通过 RBAC 控制对 Azure OpenAI 资源的访问。

from azure.identity import DefaultAzureCredential, get_bearer_token_provider

credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
    credential,
    "https://ai.azure.com/.default",
)
# 将 token_provider 交给支持 Entra ID 的 Azure OpenAI 客户端。
# 应用代码不保存长期 API Key。

Amazon Bedrock 与 IAM 集成,支持身份策略、资源、条件键、ABAC 和临时凭证。运行在 EC2、ECS、EKS 或 Lambda 上的应用应使用 IAM Role,让 AWS SDK 通过默认凭证链获取动态临时凭证,而不是在配置中写入长期 Access Key。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": "arn:aws:bedrock:REGION::foundation-model/MODEL_ID"
    }
  ]
}

实际部署时应根据所用模型、推理配置和 AWS 文档确认可使用的资源 ARN,不要为了省事直接授权所有 Bedrock 操作。

Vertex AI 可通过 Google Cloud Workload Identity Federation,让 AWS、Azure、Kubernetes、GitHub Actions 或自建 OIDC 工作负载以联合身份访问 Google Cloud,而不是分发 Service Account Key。Google 的 STS 会验证外部身份并签发联合令牌,随后可获得短期 OAuth 2.0 Access Token。

模式二:供应商只支持 API Key,由凭证代理集中托管

并非所有 LLM SaaS 都提供工作负载身份或短期令牌。此时不能宣称”无密钥”,但可以把风险压缩到一个受控边界内。

推荐结构是:

Business Service -> Internal LLM Gateway -> Secret Manager / KMS -> External LLM API

业务服务只使用内部服务身份访问 LLM Gateway。Gateway 根据租户、环境和目标供应商选择凭证,并在服务端附加外部 API Key。原始 Key 不返回给业务服务,也不进入浏览器、移动端或日志。

凭证至少按以下维度隔离:

隔离维度说明
环境生产、预发布和开发环境分别使用不同凭证
租户高风险或高消费租户使用独立项目或独立 Key
工作负载类型交互请求、离线 Batch 和评测作业使用不同凭证
访问控制只允许 Gateway 身份读取指定 Secret,禁止列出全部 Secret

模式三:多云环境通过联合身份交换短期凭证

如果工作负载运行在一朵云,而模型服务位于另一朵云,不应把目标云的长期密钥复制到源云。更稳妥的做法是建立 OIDC 或其他联合信任关系:

  1. 源环境为工作负载签发可验证的身份 Token。
  2. 目标云 STS 验证 Issuer、Audience、Subject 和声明条件。
  3. STS 只签发访问特定模型资源的短期 Token。
  4. 应用通过 SDK 自动刷新,不落盘长期密钥。

Google Workload Identity Federation 明确支持 AWS、Azure、Kubernetes、GitHub、GitLab 和其他 OIDC/SAML 身份源;AWS STS 也支持 OIDC Federation 和临时安全凭证。

凭证缓存不是普通缓存

短期令牌不能每次请求都重新获取,否则身份服务会成为延迟和可用性瓶颈;但也不能像普通配置一样长期缓存。

建议为凭证缓存定义独立键:

type CredentialCacheKey = {
  provider: string;
  tenantScope: string;
  environment: "dev" | "staging" | "prod";
  audience: string;
  scopes: string[];
  principal: string;
};

缓存刷新应满足以下规则:

  • 使用 expires_at - safety_margin 作为刷新时间,而不是等到令牌真正过期。
  • 加入随机抖动,避免大批实例在同一秒刷新。
  • 使用 singleflight 或分布式锁合并同一个缓存键的刷新请求。
  • 新令牌获取失败时,仅在旧令牌仍有效且权限完全一致时短暂复用。
  • 认证失败不能无限重试,避免把权限配置错误放大成 STS 风暴。
  • 不允许跨租户复用包含租户约束的凭证。

最小权限要落到模型资源和调用动作

只做到”身份认证成功”还不够。真正的风险边界取决于身份可以调用什么。

按环境隔离

开发身份不应拥有生产模型权限。生产身份也不应读取开发团队的全部供应商凭证。云账号、项目、订阅或资源组应与环境边界一致。

按动作隔离

推理服务通常只需要模型调用权限,不需要创建模型、修改部署、管理知识库或调整 IAM。在线推理和平台管理应使用不同身份。

按模型与区域隔离

允许调用通用低成本模型,不代表可以调用高成本模型、实验模型或其他区域的端点。供应商支持资源级权限时,应把授权范围收缩到实际模型或部署。

按租户隔离

租户不能直接提交 credential_id、任意 Base URL 或供应商项目 ID。Gateway 应根据可信租户上下文映射凭证和模型策略,避免客户端通过参数切换到其他租户的凭证。

静态 Key 无法消除时,如何安全轮换

轮换不应是”覆盖环境变量然后重启所有服务”,这容易造成瞬时认证失败,也无法确认旧 Key 是否仍在被使用。

更稳妥的流程是:

  1. 创建新 Key,并保持旧 Key 暂时可用。
  2. 将新 Key 写入 Secret Manager 的新版本。
  3. 让 Gateway 支持版本化读取,并先在少量实例启用新版本。
  4. 检查认证错误、调用量和供应商账单归属。
  5. 全量切换后,观察旧 Key 是否仍有请求。
  6. 撤销旧 Key,并验证没有隐藏消费者。
  7. 将泄漏演练、应急撤销和调用方清单纳入定期检查。

静态 Key 回退必须是显式策略。当工作负载身份故障时,系统不应悄悄切换到一个权限更大的通用 Key。确需回退时,应限制持续时间、模型范围和调用预算,并产生高优先级告警。

审计日志应该记录什么

凭证治理的日志目标是回答”谁以什么身份访问了哪个模型”,而不是记录秘密。

建议记录:

字段说明
provider, model_resource, region目标模型信息
credential_sourcemanaged_identity、sts、wif、secret_manager
工作负载主体主体标识或其不可逆哈希
租户、环境、发布版本业务上下文
Token 剩余有效期区间不含 Token 内容
授权结果、错误类别策略命中原因
成本关联 IDToken 用量追踪

禁止记录:

  • Authorization Header
  • API Key、Access Token、Refresh Token
  • Secret Manager 返回值
  • 包含凭证的完整异常对象
  • 为排障临时打印的 SDK 配置

需要重点告警的事件包括:静态 Key 使用比例突然上升、某身份开始访问新模型或新区域、认证失败集中爆发、过期令牌被重复使用、同一凭证从异常网络来源出现,以及模型费用与正常基线明显偏离。

常见误区

误区一:放进 Secret Manager 就等于没有静态密钥。 Secret Manager 解决的是存储、访问控制和轮换问题,Key 本身仍是长期凭证。应继续限制读取主体、网络出口、使用范围和轮换周期。

误区二:所有服务共享一个组织级 Key 更方便。 共享 Key 会扩大爆炸半径,并破坏费用归属和调用方追踪。至少应按环境、工作负载和风险级别拆分。

误区三:令牌越短越安全,直接设置极短有效期。 过短的令牌会增加 STS 压力,并在网络抖动时制造大量认证失败。有效期、刷新余量、缓存和故障恢复必须一起设计。

误区四:认证失败就自动回退到管理员 Key。 这会把最小权限故障升级为高权限访问。回退凭证必须权限更小、预算更低、时间更短,并经过显式审批。

误区五:只关注密钥,不限制模型资源。 一个安全保存但拥有全模型、全区域和管理权限的 Key,仍然是高风险凭证。最小权限和资源边界与秘密存储同等重要。

上线检查清单

  • 浏览器、移动端和桌面客户端不包含供应商 API Key。
  • 代码仓库、镜像层、CI 日志和构建产物已完成凭证扫描。
  • Azure、AWS、Google Cloud 场景优先采用 Managed Identity、IAM Role 或 Workload Identity Federation。
  • SaaS API Key 仅由后端 Gateway 和 Secret Manager 接触。
  • 开发、预发布、生产环境的身份和凭证完全隔离。
  • 权限已限制到实际调用动作、模型和区域。
  • 短期令牌缓存包含安全余量、抖动和 singleflight。
  • 静态 Key 回退是显式、限时、限预算策略。
  • 日志不包含任何 Authorization Header 或秘密值。
  • 已建立认证错误、静态 Key 使用率和异常费用告警。
  • 轮换流程经过双 Key 切换与旧 Key 撤销演练。
  • 应急手册能够在分钟级完成凭证冻结和调用方定位。

适用场景

这套方案尤其适合:

  • 同时调用 Azure OpenAI、Bedrock、Vertex AI 和直接 SaaS API 的多供应商平台。
  • 多租户 SaaS,需要限制不同客户可用模型、预算与区域。
  • Kubernetes、Serverless 和频繁扩缩容的推理网关。
  • CI/CD、离线评测与 Batch 推理任务。
  • 对密钥泄漏、异常账单和审计追踪有严格要求的企业系统。

小型内部原型可以先使用环境变量,但只要进入真实用户、生产数据或自动付费环境,就应规划向 Secret Manager、工作负载身份和短期凭证迁移。

参考资料

  1. OpenAI, Best Practices for API Key Safety
  2. Microsoft, Azure OpenAI with Microsoft Entra ID authentication
  3. Microsoft, Managed identities for Azure resources
  4. AWS, How Amazon Bedrock works with IAM
  5. AWS, Temporary security credentials in IAM
  6. Google Cloud, Workload Identity Federation
  7. IETF RFC 8693, OAuth 2.0 Token Exchange

常见问题

所有 LLM API 都能完全不用静态密钥吗?
不能。Azure OpenAI、Amazon Bedrock、Vertex AI 等可使用云身份或临时凭证;只支持 API Key 的 SaaS 仍需通过密钥管理服务、凭证代理和严格轮换降低暴露面。
把 API Key 放进环境变量是否已经足够安全?
不够。环境变量优于硬编码,但它仍是长期秘密,可能通过错误日志、进程信息、调试包或配置导出泄漏。生产环境应优先使用工作负载身份,无法替代时再由专用密钥管理服务托管。
短期令牌应该提前多久刷新?
不要等到过期瞬间。应根据令牌有效期设置安全余量,并加入随机抖动和 singleflight 合并刷新,避免大量实例同时刷新导致认证服务抖动。