通过RRSA配置ServiceAccount的RAM权限实现Pod权限隔离

基于适用于服务账户的RAM角色(RAM Roles for Service Accounts,简称RRSA)功能,您可以在集群内实现Pod维度的OpenAPI权限隔离,从而实现云资源访问权限的细粒度隔离,降低安全风险。本文介绍RRSA功能的使用方法。

背景信息

Kubernetes集群内的应用可以通过实例RAM角色策略生成的STS临时凭证访问云资源OpenAPI。阿里云容器计算服务ACS已经支持了RRSA功能,在多租户场景下,RRSA功能可以实现集群内应用Pod之间的云资源访问权限的细粒度隔离。在ACS场景下,RRSA功能可以满足使用STS临时凭证控制凭证有效期的需求。

image

从用户侧视角来看,RRSA功能的工作流程如下。

  1. 用户提交使用了服务账户令牌卷投影功能的应用Pod。

    说明

    ACS集群默认启用服务账户令牌卷投影功能。

  2. 集群将为该应用Pod创建和挂载相应的服务账户OIDC Token文件。

  3. Pod内程序使用挂载的OIDC Token文件访问STS服务的AssumeRoleWithOIDC接口,获取指定RAM角色的临时凭证。

    说明

    请提前修改RAM角色配置,允许Pod使用的服务账户使用该RAM角色。更多信息,请参见AssumeRoleWithOIDC

  4. Pod内应用程序使用获取到的临时凭证访问云资源OpenAPI。

启用RRSA功能

  1. 登录容器计算服务控制台,在左侧导航栏选择集群

  2. 集群页面,单击目标集群名称或者目标集群右侧操作列下的详情

  3. 在集群信息页面,单击基本信息页签,然后在集群信息区域单击RRSA OIDC对应的启用 RRSA

  4. 在弹出的启用 RRSA对话框,单击确定

    基本信息区域,当集群状态由更新中变为运行中后,表明该集群的RRSA特性已变更完成,RRSA OIDC右侧将显示OIDC提供商的URL链接和ARN信息。

集群开启RRSA功能后,ACS控制台将在后台执行如下操作:

  • 自动创建一个集群专用的OIDC Issuer服务。该服务由ACS托管,无需手动维护。更多信息,请参见OIDC Issuer

  • 在您的账号下创建一个使用该OIDC Issuer的OIDC身份提供商,名称为acs-rrsa-<cluster_id>,其中 <cluster_id>为您的集群ID。更多信息,请参见管理OIDC身份提供商

使用RRSA功能

集群开启RRSA功能后,您可以参考以下内容,赋予集群内应用通过RRSA功能获取访问云资源OpenAPI的临时凭证的能力。

使用示例

本示例部署的应用将使用RRSA功能扮演指定角色,获取当前账号下集群列表信息。

示例配置

  • 命名空间:rrsa-demo。

  • 服务账户:demo-sa。

  • RAM角色:demo-role-for-rrsa。

示例流程

说明

如果您希望使用已存在的RAM角色,不创建新的RAM角色,您可以为已有RAM角色新增相关权限。具体操作,请参见使用已存在的RAM角色并授权

  1. 创建一个名为demo-role-for-rrsa的RAM角色。

    1. 使用阿里云账号登录RAM控制台

    2. 在左侧导航栏,选择身份管理 > 角色,然后在角色页面,单击创建角色

    3. 创建角色面板,选择可信实体类型为身份提供商,然后单击下一步

    4. 配置角色页面,配置如下角色信息后,单击完成

      本示例配置如下。

      配置项

      描述

      角色名称

      demo-role-for-rrsa。

      备注

      选填有关该角色的备注信息。

      身份提供商类型

      OIDC

      选择身份提供商

      acs-rrsa-<cluster_id>。其中,<cluster_id>为您的集群ID。

      限制条件

      • oidc:iss:保持默认。

      • oidc:aud:选择sts.aliyuncs.com

      • oidc:sub:条件判定方式选择StringEquals,值的格式为system:serviceaccount:<namespace>:<serviceAccountName>

        • <namespace>:应用所在的命名空间。

        • <serviceAccountName>:服务账户名称。

        根据测试应用的信息,此处需要填入system:serviceaccount:rrsa-demo:demo-sa

  2. 步骤2创建的角色授予测试应用所需的AliyunCSReadOnlyAccess系统策略权限。具体操作,请参见为RAM角色授权

  3. 部署测试应用。关于测试应用的参考代码,请参见阿里云官方SDK使用RRSA OIDC Token的参考代码

    1. 使用以下内容,创建demo.yaml文件。

      展开查看示例代码

      ---
      apiVersion: v1
      kind: Namespace
      metadata:
        name: rrsa-demo
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: demo-sa
        namespace: rrsa-demo
      ---
      apiVersion: v1
      kind: Pod
      metadata:
        name: demo
        namespace: rrsa-demo
      spec:
        containers:
        - args:
          - rrsa
          - demo
          env:
          - name: ALIBABA_CLOUD_ROLE_ARN
            value: <role_arn>
          - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN
            value: <oid_provider_arn>
          - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE
            value: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens/token
          image: registry.cn-hangzhou.aliyuncs.com/acs/ack-ram-tool:1.0.0
          imagePullPolicy: Always
          name: demo
          volumeMounts:
          - mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens
            name: rrsa-oidc-token
            readOnly: true
        restartPolicy: OnFailure
        serviceAccount: demo-sa
        serviceAccountName: demo-sa
        volumes:
        - name: rrsa-oidc-token
          projected:
            defaultMode: 420
            sources:
            - serviceAccountToken:
                audience: sts.aliyuncs.com
                expirationSeconds: 3600
                path: token
      重要

      请替换应用模板示例代码中的如下字段。

      • <oid_provider_arn>:替换为当前集群的OIDC提供商ARN。该ARN可在容器计算服务控制台集群信息页面的基本信息页签获取。

      • <role_arn>需要替换为当前应用使用的RAM角色ARN。该ARN可在RAM控制台角色页面的角色详情页面获取。

      • audience:字段值需为 sts.aliyuncs.com

      • expirationSeconds:单位为秒,取值范围为[600, 43200],即10分钟~12小时。如果设置的值大于43200(12小时),实际的OIDC Token的过期时间仍为12小时。

      部署修改后的应用模板后,应用内程序可以使用容器内挂载的OIDC Token(环境变量ALIBABA_CLOUD_OIDC_TOKEN_FILE指向的文件内容)、角色的ARN(环境变量ALIBABA_CLOUD_ROLE_ARN配置的值)以及OIDC身份提供商的ARN(环境变量ALIBABA_CLOUD_OIDC_PROVIDER_ARN配置的值),调用STS的AssumeRoleWithOIDC接口,获取一个扮演指定RAM角色的临时凭证,然后使用该临时凭证访问云资源OpenAPI。应用参考代码,请参见阿里云官方SDK使用RRSA OIDC Token的参考代码。更多信息,请参见AssumeRoleWithOIDC

    2. 执行以下命令,部署测试应用。

      kubectl apply -f demo.yaml
  4. 执行以下命令,查看测试应用日志。

    kubectl -n rrsa-demo logs demo

    预期输出 ACK 集群列表信息:

    cluster id: cf***, cluster name: foo*
    cluster id: c8***, cluster name: bar*
    cluster id: c4***, cluster name: foob*
  5. 可选:移除角色被授予的AliyunCSReadOnlyAccess系统策略权限。具体操作,请参见为RAM角色移除权限

    等待30秒左右,执行以下命令,再次查看测试应用日志。

    kubectl -n rrsa-demo logs demo

    预期输出无权限的错误日志:

       StatusCode: 403
       Code: StatusForbidden
       Message: code: 403, STSToken policy Forbidden for action cs:DescribeClusters request id: E78A2E2D-***
       Data: {"accessDeniedDetail":{"AuthAction":"cs:DescribeClusters","AuthPrincipalDisplayName":"demo-role-for-rrsa:ack-ram-tool","AuthPrincipalOwnerId":"11***","AuthPrincipalType":"AssumedRoleUser","NoPermissionType":"ImplicitDeny","PolicyType":"ResourceGroupLevelIdentityBasedPolicy"},"code":"StatusForbidden","message":"STSToken policy Forbidden for action cs:DescribeClusters","requestId":"E78A2E2D-***","status":403,"statusCode":403}

使用已存在的RAM角色并授权

如果您的应用需要使用已存在的RAM角色,而非创建新的单独RAM角色,您可以修改RAM角色的信任策略,新增一条允许使用指定的服务账户的应用有权限通过扮演此RAM角色获取临时凭证的信任策略。更多信息,请参见修改RAM角色的信任策略

RAM角色信任策略中新增的Statement条目内容示例如下。

{
  "Action": "sts:AssumeRole",
  "Condition": {
    "StringEquals": {
      "oidc:aud": "sts.aliyuncs.com",
      "oidc:iss": "<oidc_issuer_url>",
      "oidc:sub": "system:serviceaccount:<namespace>:<service_account>"
    }
  },
  "Effect": "Allow",
  "Principal": {
    "Federated": [
      "<oidc_provider_arn>"
    ]
  }
}
重要

请替换Statement条目内容示例中的如下字段。

  • <oidc_issuer_url>:替换为当前集群的OIDC提供商URL。该URL可在容器计算服务控制台集群信息页面的基本信息页签获取。

  • <oidc_provider_arn>:替换为当前集群的OIDC提供商ARN。该ARN可在容器计算服务控制台集群信息页面的基本信息页签获取。

  • <namespace>:替换为应用所在的命名空间。

  • <service_account>:替换为应用使用的服务账户。

阿里云官方SDK使用RRSA OIDC Token的参考代码

目前,部分阿里云官方SDK已经内置了支持使用RRSA OIDC Token进行OpenAPI认证的功能。支持此功能的SDK版本信息和参考代码如下。

编程语言

支持认证的SDK版本

使用示例

Go

Alibaba Cloud Credentials for Go 1.2.6及以上版本

GO SDK使用示例

Java

Alibaba Cloud Credentials for Java 0.2.10及以上版本

Java SDK使用示例

Python 3

Alibaba Cloud Credentials for Python 0.3.1及以上版本

Python 3 SDK使用示例

Node.js和TypeScript

Alibaba Cloud Credentials for TypeScript/Node.js 2.2.6及以上版本

Node.js和TypeScript使用示例

相关文档