代码仓库设置成了私有。
数据库密码写在
application-prod.yml里。团队觉得只要不把仓库公开,就足够安全。
直到一次排查中,配置文件被打进JAR、上传到测试群,还进入了构建缓存和备份。
密码没有出现在公开GitHub,却已经复制到了很多无法追踪的位置。
一、为什么私有仓库也不该保存生产密码?
Secret一旦进入Git历史,就不只是当前文件里的一行文本。
它可能出现在:
历史提交开发者电脑CI日志与构建缓存JAR和镜像层制品仓库备份聊天文件错误截图
后来删除这一行,不能自动清除所有副本。
配置外置的目的,不只是区分环境,也包括把代码生命周期与凭据生命周期分开。
二、Spring Boot本身支持外部配置
Spring Boot可以从多种来源读取配置:
外部properties/yaml环境变量命令行参数挂载的配置树配置中心或Secret管理系统
代码中保留占位符:
spring:datasource:username: {DB_PASSWORD}
但环境变量也不是天然安全。它可能被进程信息、诊断命令、错误输出或平台界面读取。具体方案要结合平台威胁模型选择。
三、在Kubernetes中怎么做?
可以使用Secret,并通过文件或环境变量提供给容器。
需要明确:
Base64只是编码,不是加密。
Kubernetes官方也指出,Secret默认可能以未加密形式存储在etcd中,应配置静态加密、最小权限RBAC并限制get/list/watch权限。
更稳妥的原则包括:
只有需要的Pod和容器能访问不同环境和命名空间隔离Secret不写入镜像不在日志中输出定期轮换启用审计
对于更高要求的环境,可以使用外部Secret存储和CSI驱动,让凭据保留在专业密钥系统中。
四、一个容易忽略的泄露点:Actuator和配置日志
即使Secret没有写进Git,也可能在运行时被暴露:
启动时打印完整配置异常日志打印连接串Actuator端点暴露环境信息线程栈或heap dump包含凭据排查时截图未脱敏
生产环境应限制管理端点的网络范围和访问权限,敏感配置永远不要依赖“字段名刚好被自动脱敏”来保证安全。
五、发生泄露后,删除提交够不够?
不够。
正确顺序通常是:
立即吊销或轮换凭据→ 确认影响系统和访问日志→ 清理代码与制品→ 必要时重写Git历史→ 通知所有副本持有人重新同步→ 补充扫描和防护规则
最重要的是先让旧密码失效。只删除代码,泄露出去的密码仍然可以使用。
六、生产Secret管理清单
-
代码和默认配置中只保留占位符 -
Secret不进入Git、JAR和镜像层 -
使用独立凭据区分开发、测试和生产 -
权限遵循最小化原则 -
配置存储启用传输与静态加密 -
日志、指标和错误页面不输出Secret -
定期轮换,并验证应用支持平滑更新 -
CI阶段扫描密钥和高风险配置 -
访问Secret有审计记录 -
准备泄露后的吊销与应急流程
写在最后
application.yml适合描述配置结构和安全的默认值,不适合承载生产密码。
真正可靠的做法,是让代码、配置和Secret分别进入不同的管理链路,并让凭据可以独立轮换和吊销。
如果你们仓库里还有明文连接串,第一步不是“找时间重构”,而是先确认它是否仍然有效、出现过哪些副本。
你们现在使用环境变量、Kubernetes Secret、Vault,还是配置中心加密?欢迎分享踩过的坑。
扫码领红包
微信赞赏
支付宝扫码领红包
