如何在代码中安全管理API密钥和机密

Security2026-09-15TryQuickToolBox

你提交代码,推送到GitHub,然后继续工作。几天后,你发现你的API密钥从公共仓库中被抓取,并用于累积数千美元的云账单。这不是罕见的边缘情况;这是现代开发中最常见且代价高昂的安全错误之一。源代码中的硬编码机密是给攻击者的礼物,而且避免它们出奇地容易。

为什么硬编码机密如此危险

当你直接在代码中嵌入API密钥、数据库密码或私有令牌时,你就失去了对谁可以看到它的控制。源代码会传播:它被克隆、分叉、复制到Docker镜像中、粘贴到聊天应用中,有时还会被意外发布。一旦机密进入版本控制,它就会永远存在于Git历史中,即使你在后续提交中删除了它。

攻击者会主动扫描公共仓库中看起来像密钥的模式。自动化机器人可以在几分钟内找到并利用泄露的密钥。即使在私有仓库中,硬编码机密也违反了最小权限原则:每个具有读取权限的开发人员自动获得生产凭证。

规则#1:永远不要硬编码机密

这听起来很明显,但它是基础。第一步是从源文件中移除任何机密。这不仅包括像sk_live_...这样的明显字符串,还包括连接字符串、私钥和webhook签名机密。

相反,你的代码应该在运行时从环境中读取机密。以下是一个简单的Python示例:

import os

api_key = os.environ.get("PAYMENT_API_KEY")
if not api_key:
    raise RuntimeError("PAYMENT_API_KEY is not set")

在Node.js中,你会使用process.env.PAYMENT_API_KEY。在Go中,使用os.Getenv("PAYMENT_API_KEY")。模式是通用的:代码期望机密从外部提供。

安全使用环境变量

环境变量是一个很大的改进,但它们不是银弹。它们可能通过错误报告、调试日志或进程列表泄露。遵循以下实践:

对于本地开发,像python-dotenv或Node.js的dotenv这样的库可以轻松加载.env文件,而无需硬编码任何内容。只需记住:该文件绝不能提交。

用于生产的集中式机密管理器

环境变量适用于小型项目,但当你拥有许多服务、多个环境以及审计需求时,它们会变得难以管理。专用的机密管理器通过加密存储机密、使用细粒度策略控制访问以及提供审计跟踪来解决这些问题。

流行的选项包括:

你的应用程序在启动时或按需从管理器获取机密,通常使用SDK。这将机密存储与代码解耦,并允许你在不重新部署的情况下轮换凭证。

CI/CD管道中的机密

你的构建和部署管道也需要机密,例如注册表密码或部署令牌。大多数CI系统(GitHub Actions、GitLab CI、CircleCI)提供加密的机密存储。使用这些功能,而不是将机密放在管道配置文件中。

例如,在GitHub Actions中,你在仓库设置中定义机密,并像这样引用它们:

steps:
  - name: Deploy
    run: ./deploy.sh
    env:
      API_TOKEN: ${{ secrets.DEPLOY_API_TOKEN }}

小心来自分叉的拉取请求:默认情况下,机密不会传递给由分叉PR触发的工作流,这是好的。永远不要在日志中回显机密;如果你的CI系统支持,请屏蔽它们。

定期轮换机密

即使存储完美,机密也可能通过其他渠道泄露:被入侵的笔记本电脑、配置错误的日志服务或离职员工。轮换限制了暴露窗口。

根据敏感性设置轮换计划。高价值密钥(支付网关、管理API)可能每30-90天轮换一次。较低风险的密钥可以较少轮换。尽可能自动化轮换:AWS Secrets Manager和Vault可以自动轮换数据库凭证。

轮换时,确保你的应用程序在过渡期间能够处理多个有效机密。一个常见的模式是在短时间内接受旧机密和新机密,然后停用旧机密。

检测和防止泄露

预防胜于治疗,但检测是你的安全网。使用预提交钩子在提交之前扫描机密。像git-secrets、trufflehog或gitleaks这样的工具可以捕获意外提交。

还要在Git托管平台(GitHub、GitLab、Bitbucket都提供此功能)上启用机密扫描。如果机密确实泄露了,立即撤销并轮换。删除提交是不够的;一旦机密触及远程仓库,就假设它已被泄露。

机密存储方法比较

方法 最适合 风险
环境变量 小型应用、本地开发 通过日志、进程检查泄露
.env文件 本地开发 意外提交、无加密
机密管理器 生产、团队 复杂性、增加依赖
CI/CD机密存储 构建和部署管道 仅限于管道范围

常见问题

我可以将机密存储在私有仓库中吗?

不可以。私有仓库仍然有许多具有读取权限的用户和集成。机密可能通过分叉、CI日志或被入侵的账户泄露。始终使用环境变量或机密管理器,即使对于私有代码也是如此。

如果我不小心提交了机密,该怎么办?

立即撤销并轮换机密。仅仅删除提交或重写历史是不够的,因为机密可能已经被缓存或克隆。将其视为已泄露并替换它。

环境变量对生产环境足够安全吗?

它们比硬编码更好,但对于大规模生产来说并不理想。环境变量可能在崩溃转储、调试端点或进程列表中暴露。对于生产环境,使用具有访问控制和审计的专用机密管理器。

当你需要快速格式化或验证包含非敏感设置的JSON配置文件时,JSON Formatter可以帮助你在它们破坏部署之前发现语法错误。记住:永远不要将实际的机密粘贴到在线工具中。