身份与访问管理(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这事儿,说白了就是「谁可以做什么」。想清楚这两个问题,剩下的都是技术细节。你想想看,是不是这个理?