身份与访问管理(IAM):RBAC与ABAC策略设计、服务账户与密钥管理、联合身份与SSO集成
说到PaaS平台的访问控制,我脑子里第一个蹦出来的词就是「混乱」。
为什么?因为PaaS不像传统机房,你锁好门就行。PaaS上跑着几十个微服务、几百个容器、上千个API调用。谁该访问什么?怎么授权?密钥怎么管?这些问题不搞清楚,安全就是一句空话。
今天咱们就聊聊IAM这块硬骨头。我个人习惯把IAM拆成三个层面:策略设计、密钥管理、身份联合。一个一个来。
RBAC与ABAC策略设计
先说说RBAC,也就是基于角色的访问控制。这个大家应该不陌生。
RBAC的核心思想很简单:把权限打包成角色,再把角色分配给用户。比如「开发者」角色可以部署应用,「运维」角色可以查看日志,「管理员」角色可以修改配置。
我在项目中遇到过一个问题:某团队有50个微服务,每个服务都需要不同的权限。如果用RBAC,你得定义50个角色,每个角色绑定一堆权限。结果就是角色数量爆炸,管理成本直线上升。
这时候ABAC就派上用场了。ABAC是基于属性的访问控制,它不看「你是谁」,而是看「你的属性是什么」。
RBAC vs ABAC 对比
| 维度 | RBAC | ABAC |
|---|---|---|
| 授权依据 | 角色 | 属性(用户、资源、环境) |
| 灵活性 | 中等,角色变更需重新分配 | 高,策略可动态调整 |
| 管理复杂度 | 角色数量多时容易失控 | 策略规则多时容易混乱 |
| 适用场景 | 组织架构稳定、权限粒度粗 | 多租户、动态环境、细粒度控制 |
说白了,RBAC适合「人」的管理,ABAC适合「机器」和「数据」的管理。我建议的做法是:RBAC做粗粒度控制,ABAC做细粒度补充。
举个例子:
# RBAC策略示例
{
"roles": {
"developer": {
"permissions": ["deploy", "view_logs", "restart"]
},
"viewer": {
"permissions": ["view_logs"]
}
}
}
# ABAC策略示例
{
"rules": [
{
"effect": "Allow",
"condition": {
"user.department": "payment",
"resource.type": "transaction",
"environment.time": "09:00-18:00"
}
}
]
}
看到区别了吗?RBAC是「开发者可以部署」,ABAC是「支付部门的员工在上班时间可以访问交易数据」。粒度完全不同。
我的经验:别一上来就搞ABAC。先问自己三个问题:权限粒度需要多细?策略变更频率多高?团队有没有能力维护策略引擎?如果答案都是「高」,再考虑ABAC。否则,RBAC加几个自定义属性就够用了。
服务账户与密钥管理
好,策略设计完了,接下来是密钥管理。这块我踩过不少坑。
PaaS平台上,服务之间要通信,就得有身份凭证。这个凭证就是服务账户和密钥。但问题来了:密钥放哪儿?
我曾经见过一个团队,把数据库密码直接写在代码里,还上传到了GitHub。结果呢?被爬虫扫到,数据库被拖库,数据全丢了。嗯,这种事儿真不少见。
密钥管理的几个原则:
- 不要硬编码:密钥永远不要出现在代码、配置文件、环境变量里。
- 定期轮换:密钥要有过期时间,到期自动换。
- 最小权限:每个服务账户只给它需要的权限,别给「超级管理员」。
- 审计追踪:谁在什么时候用了哪个密钥,都要有日志。
具体怎么做?我推荐使用专门的密钥管理服务,比如KMS、Vault这类工具。
# 使用Vault动态生成数据库凭证
vault write database/creds/my-role \
ttl=1h
# 返回结果
{
"data": {
"username": "v-token-db-abc123",
"password": "A1b2C3d4E5f6"
}
}
你看,每次请求都生成一个临时凭证,1小时后自动失效。就算泄露了,影响范围也有限。
注意:服务账户和人的账户要分开管理。人的账户可以用密码+多因素认证,服务账户只能用密钥或证书。千万别混用,否则审计的时候你根本分不清是人还是机器在操作。
还有一个容易被忽略的点:密钥的存储位置。我建议把密钥放在独立的密钥管理服务里,应用通过API获取。不要放在容器镜像里,也不要放在Kubernetes的Secret里(除非你加密了etcd)。
联合身份与SSO集成
最后聊聊联合身份和SSO。说白了,就是让用户用一个账号登录多个系统。
PaaS平台通常不是孤立的,它要和企业的AD、LDAP、Okta、Azure AD等身份源对接。这时候就需要联合身份。
联合身份的核心协议是SAML和OIDC。我个人更倾向于OIDC,因为它基于OAuth 2.0,更轻量,更适合现代应用。
举个例子,用OIDC实现SSO:
# 用户访问PaaS平台
GET /login
# 平台重定向到身份提供商
302 Location: https://idp.example.com/authorize?
response_type=code&
client_id=paas-client&
redirect_uri=https://paas.example.com/callback&
scope=openid profile email
# 用户登录后,身份提供商返回授权码
GET /callback?code=abc123
# 平台用授权码换取ID Token和Access Token
POST /token
{
"grant_type": "authorization_code",
"code": "abc123",
"client_id": "paas-client",
"client_secret": "secret"
}
# 返回
{
"access_token": "eyJ...",
"id_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600
}
流程看着复杂,但实际用起来很顺畅。用户只需要登录一次,就能访问所有集成了SSO的应用。
避坑指南:我曾经遇到过一个案例,SSO集成后,用户登录成功了,但权限没同步过来。原因是身份提供商只传了用户ID,没传角色信息。解决方案是在ID Token里加上自定义claims,或者通过SCIM协议同步用户和角色。
联合身份还有一个好处:支持多租户。比如你的PaaS平台要给多个客户用,每个客户有自己的身份源。通过联合身份,你可以让客户用自己的AD登录,而不需要在你这边再创建一套账号体系。
嗯,这里要注意:联合身份不是银弹。它解决了「登录」的问题,但没解决「授权」的问题。用户登录后能做什么,还得靠前面说的RBAC或ABAC来控制。
总结一下我的思路:
- 策略设计:RBAC打底,ABAC补充,别过度设计。
- 密钥管理:用专门的密钥服务,动态生成,定期轮换。
- 身份联合:用OIDC做SSO,别忘了同步权限。
IAM这事儿,说白了就是「谁可以做什么」。想清楚这两个问题,剩下的都是技术细节。你想想看,是不是这个理?