Secrets接口设计原则:最小权限、加密传输、静态加密

聊完了版本管理的目标,咱们得先打好地基。Secrets接口怎么设计,直接决定了整个系统的安全水位。

我这些年处理过不少线上事故,追根溯源,十有八九都是接口设计阶段埋下的雷。这一章我就把三个核心原则掰开揉碎了讲。

原则一:最小权限

说白了,就是谁该用、谁不该用,得管得死死的。

我在项目中遇到过一件事:有个内部工具,本来只需要读一个数据库密码,结果开发图省事,把整个Secrets存储桶的读权限都给了。后来这个工具被扫出漏洞,攻击者通过它把几百个密钥全拖走了。嗯,教训很惨痛。

最小权限落实到接口设计,你得做到以下几点:

  • 按需授权,不搞批发:每个请求只返回它需要的那个Secret。别一上来就返回整个命名空间的所有密钥。
  • 区分读写:能读就别给写。能读一个字段就别给读整个对象。
  • 时效性:访问必须有时效性。默认三天有效,不能永久有效。
  • 作用域细化:比如只允许读 production 环境下的 db_password,不允许读 staging 的。

最小权限的接口设计自查表

维度好的设计坏的设计
资源粒度GET /secrets/{id}GET /secrets/all
操作范围只读、只写分离一个接口同时读写
有效期 24h 自动过期永不过期的访问令牌
字段限制返回指定字段返回整个对象,包含敏感元数据

我个人的小习惯:在接口文档里明确标出每个端点的“最小权限模型”,让调用方一看就知道自己该有什么权限。这样能省下不少扯皮的功夫。

原则二:加密传输

这一点看起来基础,但翻车率极高。你想想看,Secret在传输过程中被别人截获,和明文写在日志里有什么区别?

加密传输,不是只在公网上做 TLS 就完事了。内部服务间通信也得加密。我曾经见过一个案例:两个微服务在同一个K8s集群里,它们之间通信用的是明文 HTTP,自以为内网安全。结果某个节点的网络被镜像了,所有Secrets被看了个精光。

我的建议很直接:

  • 全链路 TLS 1.3:不管是公网还是内网,全部强制加密。
  • 双向 mTLS:服务端和客户端都得验证书,不信任任何匿名连接。
  • 拒绝降级:客户端如果发来的请求是HTTP,直接报错,不自动重定向。宁死不降级。

你可能会问,mTLS 部署起来挺麻烦的。确实,但它值得。用 service mesh 的方案(比如 Istio)能让证书轮换自动化,省心不少。

我曾经踩过的坑:有次我给Secrets接口配了TLS,但没检查 cipher suite,默认用了旧版加密套件。安全扫描一过,直接标了个严重漏洞。后来我学乖了,每次上线前都会跑一遍 nmap --script ssl-enum-ciphers。

原则三:静态加密

传输过程安全了,那存储呢?Secret 躺在数据库里,如果硬盘被人搬走了,数据还能读出来吗?

静态加密不是可选项,是必选项。但怎么做,很讲究。

常见做法有两种:

方法原理我推荐吗?
应用层加密自己管理密钥,在写入数据库前加密,读取后解密推荐,控制力强
存储层加密靠数据库自带的加密功能(比如TDE)不推荐单独使用

为什么我不推荐只靠存储层加密?因为数据库管理员还是能看到明文。你想想看,DBA 有权限查表,如果他没有被授权读 Secret,那这个设计就有问题。

静态加密的关键点:

  • 密钥不能和密文放一起。分开存储,分开管理。
  • 使用独立的密钥管理系统(KMS)来管理加密密钥。
  • 支持密钥轮换。最好能无感轮换,老密钥解密,新密钥加密。
  • 加密粒度:每个 Secret 用不同的数据密钥(DEK)加密,主密钥(KEK)用来加密 DEK。

我个人的习惯,是采用 envelope encryption(信封加密)。

过程很简单:

  1. 客户端用主密钥加密一次生成的数据密钥。
  2. 数据密钥直接加密 Secrets 明文。
  3. 数据密钥被主密钥加密后,和密文一起存到数据库。
  4. 读取时,先解密数据密钥,再用数据密钥解密密文。

这样做的好处,是即使主密钥泄露,只要数据密钥没有同时泄露,密文也还是安全的。轮换主密钥的时候,只需要重新加密数据密钥,不用动那些大的密文块。

我曾经犯过一个低级错误:有一次我把加密密钥硬编码在配置文件里了。结果那个文件被提交到了公开的 Git 仓库。嗯,那天的回滚真是手忙脚乱。从此以后,我再也不敢把任何密钥写进代码或配置里了。用 KMS 吧,贵但值得。

到这里,三个原则我都讲完了。你可能会觉得,这些原则都是常识。但说实话,能把它们扎实落地的团队,还真不多。很多人往往只做了表面功夫,一遇到线上问题就暴露了。

我下面把这三个原则的核心关系画成一张图,方便你理解它们是怎么配合的。

Secrets接口设计三原则 Secrets接口 最小权限 按需授权 | 读写分离 加密传输 TLS 1.3 | mTLS | 拒绝降级 静态加密 信封加密 | KMS管理 三个原则相互独立又彼此补充,共同构成Secrets接口的安全防线

看完这张图,你应该能清楚,这三个原则不是孤立的。最小权限控制谁可以访问,加密传输保证路上不被偷听,静态加密保证停下来也不被翻。三个一起上,才算真正靠谱。

关于落地的最后一句:别想着一步到位。先搞定加密传输和静态加密,再逐步收紧权限。我见过太多团队一开始就想搞最小权限,结果搞了半年没搞出来,最后连TLS都没配。先跑起来,再跑稳。