企业应用中的密钥与 API 密钥管理:存放、轮换与凭据泄露检测
本文目录
一个支付服务的 API 密钥被存放在配置文件中,这个文件被复制进代码仓库,有一天仓库被分享给新的承包商,或者更糟,被不小心设为公开。几个小时内,扫描互联网的人就发现了这个密钥并加以利用。这样的场景并不罕见。应用密钥(如数据库密码、API 密钥、访问令牌和证书)泄露,是最常见也最容易预防的安全事件原因之一。
软件开发中的“密钥”(secret)指任何能授予系统访问权限、且不应被公众知道的值。现代企业应用会使用数十个密钥:数据库连接、支付服务、邮件和消息、文件存储、AI 服务、与 ERP 和电商平台的集成,以及用于签署登录会话的密钥。集成越多,需要保护的密钥就越多。
本文介绍如何以适合中小企业的务实纪律来管理密钥:存放在哪里、如何分离环境、如何轮换、如何发现泄露,以及发生事件时怎么做。开始并不需要昂贵的工具,需要的是一致的习惯和规则。
摘要
- 绝不要把密钥存放在源代码、Git 历史、截图或聊天群中
- 按环境(开发、测试、生产)和按服务分离密钥,并赋予尽可能小的权限
- 存放在专门设计的地方,即密钥管理器或托管平台上的加密环境变量,而不是普通文件
- 定期轮换密钥,并在有人离开团队或怀疑泄露时立即轮换
- 部署自动扫描以发现意外提交的密钥,并为泄露事件准备书面流程

哪些属于密钥
许多团队只把密码当作密钥,实际上清单要长得多。以下是企业应用中常见的类型:
- 数据库密码和连接字符串
- 支付、物流、地图、邮件、消息和 AI 服务的 API 密钥
- 第三方集成(包括 ERP、电商平台和会计系统)的访问令牌和刷新令牌
- Webhook 签名密钥和会话令牌签名密钥
- 证书和私钥,包括用于服务器访问的 SSH 密钥
- 云账号和服务账号凭据
- 共享账号的密码,如托管面板、域名注册商和公司社交媒体账号
请注意,客户端侧的值(如地图或分析的公钥)本来就设计为在浏览器中可见,不属于密钥。但看起来像这样的密钥常常有与之配对的私密版本。请查阅各服务的文档加以区分,并在服务支持时把公钥限制在特定域名上。
最常导致泄露的错误
大多数泄露并非来自复杂的黑客攻击,而是日常松散的习惯。
密钥在代码或 Git 历史中
为图快而把密钥直接写在代码里,是泄露的头号来源。即使之后从代码中删除,密钥仍然留在 Git 历史中,所以任何能访问仓库的人都能找到。因此只删除文件是不够的;曾经提交过的密钥必须视为已泄露并轮换。
被上传的配置文件
.env 之类的文件或生产配置文件,常常被意外提交,或被包含在发送给供应商的压缩包中。务必从第一天起就把这类文件加入忽略列表,并提供不含真实值的示例文件作为文档。
通过聊天和邮件分享
通过聊天群或邮件发送密码很容易,但消息会长期保存在许多设备和备份中。对于不可避免的情况,请使用团队密码管理器或一次性密钥分享工具。
截图和日志
出现在支持工单截图、屏幕录制或应用日志中的密钥常被遗忘。确保日志不会打印授权头、令牌或包含凭据的整个请求体。安全的日志实践见企业应用的可观测性、日志与错误处理。
一个密钥通吃
在开发、测试和生产中使用同一个密钥,或所有服务共用一个管理员账号,会扩大泄露的影响。一台丢失的开发人员笔记本,可能意味着对生产数据的完全访问。
存放密钥的正确位置
原则很简单:密钥不与代码存放在一起,而是在应用运行时注入。
- 托管或 CI/CD 平台上的环境变量:最简单的方式,对许多应用已经足够。值由平台加密存储,不会进入仓库
- 密钥管理器:专门的服务,负责存储、控制访问、记录谁读取过,并支持自动轮换。适合密钥和人员数量增加时
- 团队密码管理器:用于面板和注册商账号等人类凭据,具备按文件夹的访问权限和审计记录
- 硬件安全模块或云密钥服务:用于高度敏感的加密和签名密钥
不要自己搭建方案,比如装满密码的电子表格,或标题为“访问”的共享文档。这些工具没有合格的访问控制,不记录谁访问过,而且很容易被复制。

分离环境与限制访问
应用三种一致的分离。第一,环境分离:开发、测试和生产使用不同的密钥。非生产环境应使用第三方服务的沙盒账号以及虚构或匿名化的数据,这与网站和应用的个人数据保护一致。
第二,按服务分离:每个应用或模块使用自己的凭据,仅具备所需的权限。只需读取数据的密钥不应能写入或删除。这种最小权限原则与设计用户访问权限中讨论的相同,只不过主体是应用而不是人。
第三,人员分离:并非每位团队成员都需要看到生产密钥。把范围限制在真正运营系统的人员,用多因素认证加以保护,并为持有访问权限的账号考虑通行密钥与无密码登录。对于跨应用访问,SSO 与身份管理可减少流通的密码数量。
轮换:在出问题之前和之后更换密钥
从不更换的密钥会给任何获得它的人无限的时间。轮换指定期以及在特定事件发生时更换密钥的值。
- 定期:设定计划,例如重要密钥每季度一次,短期令牌则更频繁
- 人员离开时:曾接触密钥的员工、承包商或供应商停止工作后,轮换他们知道的密钥
- 怀疑泄露时:立即轮换,不要等待滥用的证据
- 更换供应商时:项目易手,如[挽救停滞的软件项目并更换供应商](/blog/menyelamatkan-proyek-software-yang-macet-dan-pindah-vendor)中所述,必须包括凭据交接及之后的轮换
为避免轮换导致停机,应将应用设计为在过渡期内暂时支持两个有效值(例如旧密钥和新密钥),然后撤销旧的。在测试环境中先演练轮换流程,免得紧急时才第一次用。借助自动化测试与 CI/CD,可以把“更换密钥后应用仍能运行”的检查设为例行步骤。
尽早发现泄露
预防永远不会完美,所以要部署检测。
- 在仓库以及每次提交或合并请求上运行密钥扫描器,拒绝包含已知密钥模式的变更
- 定期扫描仓库历史,找出曾经提交过的旧密钥
- 当服务提供商发现密钥被公开或从异常位置使用时发出警报
- 使用情况监控:API 调用激增、异常账单或来自境外地区的访问,往往是最早的迹象
- 把密钥限制在特定 IP 地址、域名或权限范围,使泄露的密钥难以被他人使用
使用监控也与成本相关。泄露的 AI 或云服务密钥可能一夜之间产生巨额账单,如控制 AI 成本和企业云成本控制所述。请在服务账号上设置预算上限和提醒。
集成、Webhook 和 AI 智能体中的密钥
第三方集成增加了攻击面。对于 Webhook,用共享密钥验证每个传入请求的签名,使他人无法伪造通知,参见企业 Webhook 与实时集成。对于您自己提供的 API,为每个客户签发范围有限、可逐一撤销的密钥,如企业 API 设计所述。对于支付网关,遵循提供商的安全指南,绝不要把密钥放进客户端代码;参见支付网关集成。
通过模型上下文协议等协议调用业务系统的 AI 智能体和连接器,同样需要凭据。给智能体单独的、权限狭窄的凭据,不要把密钥放进提示词或模型上下文,并留意通过模型输出造成的数据泄露,见AI 应用安全:提示注入与数据泄露。
密钥泄露时的计划
在事件发生之前准备书面流程,因为人在慌乱时会漏掉步骤。建议的顺序:
- 立即撤销或轮换泄露的密钥,甚至在调查完成之前
- 确定范围:密钥自何时起暴露、谁或什么可以使用它、它能访问什么
- 检查访问日志和账单,查找未授权的使用
- 清理泄露源头,例如从仓库中删除、必要时重写历史,并修复流程上的原因
- 按法律和合同义务通知受影响的各方,尤其是涉及个人数据时
- 记录经验教训并改进流程
这一流程是企业网络安全事件响应计划的一部分,而恢复数据的能力则在于企业数据备份策略。更广泛的基础见企业应用的基本安全。
当开发由供应商或外部团队完成时
外部开发增加了薄弱点,因为许多人接触凭据。在合同和工作习惯中加以安排:生产凭据由您持有,或通过共享密钥管理器管理;供应商获得临时且有限的访问权限;所有云账号、域名和仓库都登记在贵公司名下,而不是开发人员的个人名下。项目结束时撤销访问并轮换。这些要点是对在印尼外包软件开发和软件开发合同要点中建议的补充。
本周即可开始的步骤
不必等待大项目。一周内做完以下五件事:列出所有使用中的密钥及其存放位置;把写在代码或普通文件中的一切迁移到环境变量或密钥管理器;在仓库上部署密钥扫描器;在所有持有访问权限的账号上启用多因素认证;轮换曾通过聊天或邮件分享过的密钥。这五步已经可以堵住大部分最常见的风险。
常见问题
把密钥存放在服务器上的 .env 文件中安全吗?
比放在代码里好,前提是该文件不在仓库中、文件权限受到限制且服务器受到保护。不过,平台上的密钥管理器或加密环境变量提供更好的访问控制、审计和轮换,尤其是在团队扩大时。
API 密钥已经被提交了,从代码中删除就够了吗?
不够。密钥仍留在历史中。应视为已泄露:轮换该密钥,然后清理代码。重写 Git 历史可以帮助减少暴露,但不能代替轮换。
密钥应多久轮换一次?
没有统一的数字。对重要密钥,每季度或每半年是合理的起点,并且在人员离开或怀疑泄露等触发事件发生时必须轮换。轮换越自动化,您就越能频繁地进行。
小企业真的需要密钥管理器吗?
起初不一定。托管平台上的加密环境变量加上团队密码管理器通常已经足够。当服务、环境和有权访问的人数多到使手动管理难以审计时,再考虑专用密钥管理器。
结论
管理密钥是一种习惯,而不是一款产品。不要把密钥放进代码,存放在专门设计的地方,按环境和服务分离,限制谁能看到,定期轮换,并建立检测和书面应急流程。践行这种纪律的企业,以远低于一次密钥泄露影响的成本,堵住了最常见的事件路径之一。
为您推荐
与此主题相关的阅读
免费清单:如何选择软件公司
签约前评估供应商的 24 个要点,可保存为 PDF。