密钥类型与分类:别让它们混在一起
各位好。今天聊聊管道里那些“钥匙”到底分几类。
我见过不少团队,把所有密码、令牌、密钥统称为“敏感信息”,扔到一个变量文件里。结果呢?出事的时候根本分不清哪个泄露的是,哪个是数据库密码。排查起来,简直灾难。
先从最常见的说起:
,说白了就是一段字符串。你用它告诉服务端:“嘿,是我,让我进去。” 很多SaaS平台、开放接口都用这招。
特点:
- 通常是一串随机字符,长度16-64位
- 本身不含用户身份信息,就是个标识+密文
- 容易被硬编码在代码里——我见过有人直接写在GitHub公开仓库的配置文件里,嗯,后果可想而知
访问令牌:比更“智能”一点
Access ,通常包含用户或应用的权限信息。JWT(JSON Web )就是个典型例子。它里面能存角色、过期时间、签名,后端解码就能知道你是谁、能干什么。
跟比,区别在于:
| 特性 | 访问令牌(如JWT) | |
|---|---|---|
| 是否自包含用户信息 | 否(需要查库) | 是(payload里直接带) |
| 过期机制 | 通常无内置过期 | 有(exp字段) |
| 泄露后危害 | 持续可用直到轮换 | 可在有效期内任意使用 |
| 典型使用场景 | 服务端与服务端通信 | 用户认证、API授权 |
这里我要提醒一点:JWT虽然自带过期,但如果你把刷新令牌(Refresh )也暴露在CI/CD管道里,等同无限钥匙。我曾经遇到过,一个同事把refresh_写在了构建日志里,因为调试时偷偷打印了……结果被爬虫扫到,整个用户系统差点被拖库。
SSH密钥:管道里最常见的“门禁卡”
SSH密钥分公钥和私钥。私钥绝不能离开你本地机器——但CI/CD管道里,你往往需要用私钥去拉代码、部署服务器。
常见陷阱:
- 把私钥拷贝到Docker镜像里。镜像一旦被推送到公共仓库,私钥就公开了。
- 给私钥设空密码。我见过不少为了方便,直接`ssh-keygen -f id_rsa -N ""`,万一被拿到,等于裸奔。
数据库密码:低频但高风险的“定时炸弹”
数据库密码可能是最容易被忽略的。我遇到过一家公司,他们在Jenkins的构建配置里直接明文写死了MySQL root密码。后来Jenkins被攻破,数据库直接被删库,恢复备份花了两天。
数据库密码的特点:
- 通常很长,且包含特殊字符
- 一旦泄露,攻击者可以直接操作数据
- 轮换麻烦——你需要同时更新应用配置、CI/CD变量、数据库运维脚本
我个人习惯:数据库密码不要跟放在同一个变量组里。分开管理,这样即使泄露了一类,另一类还能保命。
云服务凭据:AWS Access Key、Azure SP等
云厂商的凭据通常是“访问密钥ID + 秘密访问密钥”的组合。比如AWS的AKIA开头的Access Key。
典型风险:
- 凭据权限过大。很多人图省事直接给管理员权限。我记得有个项目,CI/CD用的凭据竟然绑定了“*”权限,一旦泄露,整个云账号都能被接管。
- 不支持旋转。有些凭据是长期有效的,而云厂商推荐使用临时凭据(比如STS、IAM Roles Anywhere)。
一张图看清密钥家族
小结一下:分类是为了分治
你想想看,如果把所有钥匙都塞进同一个保险柜,一旦有人拿到这个保险柜的密码,所有东西都完蛋。分类管理,就能做到“泄露一种,隔离其他”。
我个人做法是:在CI/CD变量管理里,给每类密钥单独一个前缀或命名空间。比如 _*、DB_PASS_*、SSH_PRIV_*。审计的时候一眼就能看出哪个变量属于哪类,轮换也方便。
1. 分类存储,不同密钥用不同加密策略
2. 最小权限:给管道里的密钥只赋予它真正需要的权限
3. 定期轮换:30天、数据库密码90天、云凭据建议用临时方案
4. 审计日志:每次管道使用密钥都要留下痕迹