代码仓库设置成了私有。

数据库密码写在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管理清单

  1. 代码和默认配置中只保留占位符
  2. Secret不进入Git、JAR和镜像层
  3. 使用独立凭据区分开发、测试和生产
  4. 权限遵循最小化原则
  5. 配置存储启用传输与静态加密
  6. 日志、指标和错误页面不输出Secret
  7. 定期轮换,并验证应用支持平滑更新
  8. CI阶段扫描密钥和高风险配置
  9. 访问Secret有审计记录
  10. 准备泄露后的吊销与应急流程

写在最后

application.yml适合描述配置结构和安全的默认值,不适合承载生产密码。

真正可靠的做法,是让代码、配置和Secret分别进入不同的管理链路,并让凭据可以独立轮换和吊销。

如果你们仓库里还有明文连接串,第一步不是“找时间重构”,而是先确认它是否仍然有效、出现过哪些副本。

你们现在使用环境变量、Kubernetes Secret、Vault,还是配置中心加密?欢迎分享踩过的坑。

扫码领红包

微信赞赏支付宝扫码领红包

发表回复

后才能评论