AI API Key 怎么安全保存?开发、生产与泄露应急清单
简答:AI API Key 应按密码或长期凭证管理:不要放进前端、移动应用、公开仓库、日志或 URL;开发环境使用环境变量,生产环境使用 Secret Manager、平台 Secret 或短期身份凭证。发现泄露时,按“撤销 → 新建 → 更新部署 → 查用量 → 清理来源”的顺序处理,先让旧 Key 失效,再清理代码和历史记录。
定义:AI API Key 是用于验证调用方身份、关联项目配额或计费的凭证,持有者通常可以直接发起 API 请求,因此不能当作普通配置文本处理。
先看 5 分钟速查卡:Key 泄露后怎么处理
本站为第三方指南,非任何 AI 服务官方,以其官网为准。假如你刚把 Key 提交到仓库、粘贴到第三方工具或发现异常调用,不要先花时间清理 Git 历史,先让凭证失效。
- 撤销:在对应平台删除、停用或撤销疑似泄露的旧 Key。
- 新建:按项目、环境和用途创建新的独立凭证。
- 更新部署:更新 Secret Manager、CI/CD、容器、Serverless、后端和第三方工具中的配置。
- 查用量:检查调用日志、配额、费用、模型、时间段和来源 IP,记录异常范围。
- 清理来源:从源码、提交记录、Issue、日志、截图和普通配置中移除旧值,再复盘泄露入口。
OpenAI 官方建议怀疑 Key 泄露时立即轮换,并检查用量;GitHub 也建议发现 Secret Scanning 告警后立即轮换受影响凭证,而不是只删除文件。可查看 OpenAI API Key 安全最佳实践 和 GitHub Secret Scanning 文档。
| 场景 | 推荐做法 | 应避免 |
|---|---|---|
| 本地开发 | 环境变量或本地 .env,并加入 .gitignore | 把真实 Key 写入源码、截图或示例配置 |
| 自动化测试 | 单独的测试 Key,放入 CI/CD 加密 Secret | 复用生产 Key,或写进工作流 YAML |
| 生产后端 | Secret Manager、平台 Secret 或短期身份凭证 | 把长期 Key 写进镜像、Dockerfile 或部署脚本 |
| 浏览器、移动端、桌面端 | 由后端代理调用,客户端只拿业务所需的短期会话凭证 | 把供应商 Key 打包进 JavaScript、APK、IPA 或安装包 |
| 第三方工具或 API 网关 | 用途单一、限额、可独立撤销的加密 Secret | 直接填入生产主 Key、普通备注或共享文档 |
开发环境:环境变量、.env 与 PowerShell 正确写法
开发环境的目标是让代码可以共享,但凭证不进入代码。环境变量名可按平台区分,例如 OPENAI_API_KEY、GEMINI_API_KEY 和 ANTHROPIC_API_KEY。验证时只判断变量是否存在,不打印完整值。
Bash 或 macOS/Linux
read -s OPENAI_API_KEY
export OPENAI_API_KEY
test -n "$OPENAI_API_KEY" && echo "OPENAI_API_KEY is set"PowerShell
不要把 Read-Host -AsSecureString 的返回对象直接赋给环境变量,否则可能写入 System.Security.SecureString,导致后续认证失败。简单场景可以使用普通隐藏输入方式;PowerShell 7 可使用 -MaskInput。
$env:OPENAI_API_KEY = Read-Host "Enter API key" -MaskInput
if ($env:OPENAI_API_KEY) {
Write-Output "OPENAI_API_KEY is set"
}如果当前 PowerShell 版本不支持 -MaskInput,可使用普通 Read-Host,但输入内容可能在屏幕上显示:
$env:OPENAI_API_KEY = Read-Host "Enter API key"
if ($env:OPENAI_API_KEY) {
Write-Output "OPENAI_API_KEY is set"
}通过 $env: 设置的变量只对当前 PowerShell 会话生效。重新打开终端后需要重新设置,或改用操作系统凭据存储、云端 Secret 或其他密钥管理方案。
.env 与 Git
printf '\n.env\n.env.*\n!.env.example\n' >> .gitignore
git status --short上面的 Bash 命令使用单引号包住 !,可避免交互式 Bash 的历史展开导致 event not found。如果 .env 已经被 Git 跟踪,仅修改 .gitignore 不会将它从索引中移除:
git rm --cached .env
git commit -m "Stop tracking local environment file"这只会停止跟踪当前文件,不会让历史提交中的 Key 自动失效。若真实 Key 曾进入仓库,应先撤销或轮换,再处理历史记录。Claude 官方也建议本地使用 .env 时加入忽略规则,云环境优先使用加密 Secret。
Node.js 与 Python:读取环境变量但不打印 Key
应用代码只需要读取环境变量,不需要把 Key 写入源文件。下面两个示例只输出“是否存在”,适合做启动检查或最小认证验证。
Node.js
const key = process.env.OPENAI_API_KEY;
if (!key) {
throw new Error("OPENAI_API_KEY is not set");
}
console.log("OPENAI_API_KEY is set");Python
import os
key = os.environ.get("OPENAI_API_KEY")
if not key:
raise RuntimeError("OPENAI_API_KEY is not set")
print("OPENAI_API_KEY is set")不要把 process.env、os.environ、完整请求头、完整 URL 或异常对象直接写入日志。若使用第三方 SDK,优先让 SDK 从环境变量读取凭证,并检查调试模式是否会记录请求头。
生产环境:Secret Manager、短期令牌与工作负载身份怎么选
生产环境应把“应用代码”和“凭证存储”分开。Secret Manager 适合保存平台仍要求使用的 API Key;OAuth 适合代表用户访问授权资源;短期令牌适合缩短凭证有效期;工作负载身份适合云端任务或 CI/CD 通过受信任身份换取短期访问令牌。
| 方式 | 适用场景 | 主要注意点 |
|---|---|---|
| API Key | 服务端调用、兼容接口、简单集成 | 按项目和环境隔离,设置权限、来源、IP、配额或有效期 |
| OAuth | 应用代表用户访问用户授权资源 | 不要用用户密码或长期主 Key 代替授权流程 |
| 短期令牌 | 临时任务、客户端会话或受限调用 | 限制有效期、权限和可调用资源 |
| 工作负载身份 | 云任务、CI/CD、跨云工作负载 | 使用受信任身份换取短期凭证,避免长期保存服务账号密钥 |
| Secret Manager | 生产应用仍必须使用长期 API Key | 限制读取权限,避免在镜像、构建日志和部署文件中展开原值 |
OpenAI 官方明确建议:为支持的工作负载使用 Workload Identity Federation,使用具有必要权限的专用服务账号换取短期访问令牌;同一文档也建议设置 Key 过期时间和轮换流程。生产部署时应以对应平台当前文档和账号能力为准,不能假设所有模型或账户都支持相同认证方式。
Docker 运行时应从当前环境继承变量,而不是把值展开到命令行参数中:
docker run --rm -e OPENAI_API_KEY your-image:latest也可以使用本地受保护的环境文件:
docker run --rm --env-file .env your-image:latest生产环境不建议把 .env 直接打包进镜像;应使用编排平台的 Secret 注入能力或云端 Secret Manager。
前端、日志、URL 和第三方工具:四个隐蔽泄露点
浏览器、移动应用和桌面客户端都属于用户可观察环境。只要长期 Key 被打包、下发或放入请求,使用者就可能读取它。因此,前端通常应调用自己的后端,由后端保存供应商凭证并完成 API 请求。
- 前端源码和构建包:压缩、混淆或隐藏变量名不能改变 Key 已经下发到客户端这一事实。
- URL 查询参数:不要使用
?key=真实Key。URL 可能进入浏览器历史、反向代理日志、监控系统、错误报告和复制粘贴记录。 - 日志和错误堆栈:过滤
Authorization、x-api-key、x-goog-api-key等请求头,不记录完整请求 URL、环境变量和完整异常对象。 - 第三方工具和网关:先确认 Secret 是否加密存储、谁能读取、是否写入日志、是否支持删除和轮换。
Gemini API 官方参考示例使用 x-goog-api-key 请求头传递 Key,并要求 API 请求包含该请求头;相比把 Key 放在 URL 查询参数中,请求头更适合避免凭证进入 URL 日志。可查看 Gemini API reference 和 Google Cloud API Key 最佳实践。
如果使用 OpenAI 兼容中转或 API 网关,应分别管理上游供应商 Key与网关 Key,不要在多个工具中复用同一个生产主凭证;同时确认网关的日志、存储、团队权限、删除和轮换策略。Claude 官方也提醒,将 Key 上传到第三方工具、云平台或 CI/CD 平台,等于让该工具的开发者有机会接触账户凭证,因此应使用加密 Secret 字段。
OpenAI、Gemini 与 Claude:平台差异速查
| 平台 | 截至核查日可确认的重点 | 实际操作 |
|---|---|---|
| OpenAI | 官方建议团队成员使用独立 Key;项目 Key 可设置过期时间;支持的工作负载可使用 Workload Identity Federation;不要部署到浏览器或移动应用 | 按成员、项目、环境和用途拆分 Key,设置有效期,替换验证成功后撤销旧 Key |
| Gemini API | 截至2026年10月23日,官方页面称 Gemini API 正从标准 API Key 向授权 API Key 过渡;自2026年5月28日起,Google AI Studio 新建 Key 默认是授权 Key;无明确限制的标准 Key 会被拒绝,已设置明确限制的标准 Key 仍可用 | 检查现有 Key 类型和限制,优先按官方 API 参考使用 x-goog-api-key 请求头,并关注官方迁移说明 |
| Claude API | 官方建议不要共享 Key,使用环境变量或云端 Secret,并监控 Logs、Usage 和支出或速率限制 | 为开发、测试、生产和不同工具创建独立 Key,发现疑似泄露立即删除或轮换 |
Gemini 的认证类型属于时效性信息,以上状态对应 Gemini API keys 官方页面截至2026年10月23日的内容;后续以该页面为准。OpenAI 的 Key 有效期、工作负载身份和轮换要求见 OpenAI API key safety,Claude 的第三方工具和加密 Secret 建议见 Claude API key best practices。
扫描与阻断:GitHub Secret Scanning、Gitleaks 和 pre-commit
扫描应覆盖当前文件和 Git 历史,阻断应尽量发生在提交或推送之前。GitHub Secret Scanning 可以检查仓库 Git 历史及多个协作内容区域;Push Protection 可在支持的场景下阻止包含 Secret 的推送。启用后仍不能把它当作唯一防线,因为检测范围和支持的 Secret 类型存在限制。
Gitleaks 本地扫描
# 扫描当前目录文件
gitleaks dir .
# 扫描 Git 历史
gitleaks git .Gitleaks 官方 README 说明,较新的版本优先使用 gitleaks dir 和 gitleaks git;detect 和 protect 在 v8.19.0 起已被弃用但仍可能保留。dir 主要扫描文件,git 用于扫描仓库历史。
pre-commit 配置
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.24.2
hooks:
- id: gitleaks示例中的版本号只是配置格式示例,使用前应根据 Gitleaks 官方仓库现有标签调整。安装并启用 pre-commit 后,提交前会执行扫描;CI 仍应再次扫描,避免绕过本地钩子。
GitHub Actions 最小示例
name: secret-check
on:
push:
pull_request:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}该 Action 的当前版本、权限要求、组织账号配置和是否需要额外许可证,应以 Gitleaks Action 官方仓库为准。GitHub Actions 的 Key 应创建为仓库级、环境级或组织级 Secret,再在工作流中引用,具体步骤见 GitHub Actions 使用 Secret 文档。
日志脱敏与第三方接入的最小规则
日志脱敏不是只替换某一个字段,而是要阻止凭证进入请求、错误和调试链路。可以先建立统一的过滤字段:
const SENSITIVE_HEADERS = new Set([
"authorization",
"x-api-key",
"x-goog-api-key",
"proxy-authorization"
]);
function redactHeaders(headers) {
return Object.fromEntries(
Object.entries(headers).map(([name, value]) => [
name,
SENSITIVE_HEADERS.has(name.toLowerCase()) ? "[REDACTED]" : value
])
);
}- 不要记录完整请求 URL、认证头、环境变量值和完整错误堆栈。
- 可以记录请求 ID、模型名、状态码、耗时和用量摘要。
- 需要区分不同 Key 时,使用人工别名或不可逆哈希后的标识,不记录原值。
- 第三方 IDE、Agent、MCP 服务、桌面客户端或 API 网关使用 Key 时,先确认加密存储、访问者、日志策略、删除机制和轮换入口。
- 如果一个工具同时连接多个平台,应为每个平台和每个环境使用独立变量,不要把多个 Key 放在同一段普通文本中。
泄露后排错:认证错误不一定都是 401
不同平台的错误码并不完全一致。不要看到非 401 就认定 Key 没问题,也不要把一个平台的错误码规则套到另一个平台。Gemini 官方排错资料中,无效 Key 可能表现为 HTTP 400 及 API_KEY_INVALID;具体仍应以实际平台返回和对应文档为准。
| 现象 | 优先检查 | 处理方式 |
|---|---|---|
| 400 | 请求体、模型名、认证头、参数格式 | 先用官方最小请求验证,再逐项恢复业务参数 |
| 401 | Key 是否为空、撤销、过期或传错环境变量 | 确认变量存在,重新生成并更新部署,不打印完整 Key |
| 403 | 项目权限、来源限制、IP 限制、API 范围或账户状态 | 检查控制台权限和限制,不要直接放宽全部限制 |
| 404 | Base URL、路径、版本或模型名称 | 核对供应商或网关文档,确认兼容接口实际支持的路径 |
| unsupported_parameter | 当前模型或接口不支持某个参数 | 删除不兼容参数,核对该平台的模型能力说明 |
| 429 | 限速、配额、余额或支出上限 | 检查用量和限额,使用有上限的退避,不要无限重试 |
| 超时或流式中断 | 网络、代理、客户端超时和服务端流式处理 | 先用非流式最小请求确认认证正常,再单独排查连接设置 |
Gemini 认证和错误处理可参考 Gemini API troubleshooting。如果使用兼容网关,还要分别检查网关 Key、上游 Key、Base URL 和网关自身的错误映射。
一份可执行的长期安全清单
- 现在:搜索源码、配置、日志和文档中的硬编码 Key;检查
.env是否被 Git 跟踪;确认前端没有供应商长期 Key。 - 开发阶段:使用环境变量或本地 Secret,提供不含真实值的
.env.example,启用 pre-commit 和 Gitleaks。 - 测试阶段:使用独立测试 Key,设置较小权限和限额,CI 通过 GitHub Actions Secret 注入。
- 生产阶段:使用 Secret Manager、平台 Secret 或工作负载身份;不要把 Key 写进 Dockerfile、镜像、构建日志或公开配置。
- 上线前:检查来源限制、IP 允许列表、API 范围、速率限制、配额和支出上限;验证日志已经过滤认证头和 URL 参数。
- 持续维护:建立过期提醒、双 Key 滚动轮换、用量审计和泄露应急流程。
最小安全原则是:让每个 Key 只服务一个明确用途,只拥有必要权限,只在必要环境出现,并且能够快速撤销。
常见问题
AI API Key 泄露后,第一步是删除代码还是换 Key?
第一步应立即撤销、停用或删除受影响的 Key,使它失效;然后生成新 Key、更新所有部署位置,再清理代码、提交历史、日志和第三方配置。只删除代码而不撤销凭证,不能阻止已经获得 Key 的人继续调用。
可以把 AI API Key 放在前端、浏览器或移动应用里吗?
不建议把长期供应商 Key 放在前端、浏览器、移动应用或桌面客户端中,因为这些运行环境中的代码和请求可能被用户检查。更安全的边界是由后端保存 Key,客户端只调用自己的后端接口;如果平台支持短期、受限凭证,可按官方方案使用。
开发环境一定要使用 .env 文件吗?
不一定。环境变量、操作系统凭据存储、本地 Secret 工具、云端开发 Secret 都可以。若使用 .env,应加入 .gitignore,确认没有被 Git 跟踪,并提供不含真实值的 .env.example;生产环境不应把 .env 打包进镜像。
Gemini、OpenAI 和 Claude 的 Key 能共用吗?
不能把一个平台的 Key 当作另一个平台的认证凭证。应为不同平台、项目、环境和工具分别保存变量和 Secret,并使用各平台自己的认证头、权限、限制和轮换流程。Gemini 的标准 Key 与授权 Key 状态还会随官方政策变化,应以官方页面截至核查日的说明为准。
如何判断 Key 是否已经进入 Git 历史?
可以先执行 <code>git log --all -- .env</code>,再使用 Gitleaks 的 <code>gitleaks git .</code> 扫描历史,并查看 GitHub Secret Scanning 告警。如果发现真实 Key,先撤销或轮换,再处理历史记录;不要只依靠删除当前文件。
第三方 AI 工具或 OpenAI 兼容网关需要填写 API Key,应该怎么做?
先确认工具或网关是否使用加密 Secret 存储、谁能查看或读取、是否会写入日志、是否支持删除和轮换,再创建一个用途单一、权限和额度受限的独立 Key。使用中转或网关时,应分别管理网关 Key 和上游供应商 Key,不要直接填入生产主 Key。
相关阅读
参考资料
- OpenAI:Best practices for API key safety
- Google AI for Developers:Using Gemini API keys
- Google AI for Developers:Gemini API reference
- Google AI for Developers:Gemini API troubleshooting
- Google Cloud:Best practices for managing API keys(docs.cloud.google.com)
- Claude Help Center:API key best practices(support.claude.com)
- GitHub Docs:Secret scanning
- GitHub Docs:Push protection
- Gitleaks:Secret scanning tool
- Gitleaks Action:GitHub Actions 官方仓库