用SourceIdentity实现角色扮演溯源与权限控制

本文将详细介绍SourceIdentity的核心概念、配置方法、访问控制策略、典型应用场景及故障排除方法。

什么是SourceIdentity

SourceIdentity是您在通过调用OpenAPI扮演RAM角色以获取临时安全令牌(STS Token)时,为当前会话设置的源身份标识。

使用SourceIdentity的意义主要在于:

  • 在角色链等复杂场景下进行身份溯源

    角色链指 RAM 身份(或角色SSO)通过角色扮演获得了角色会话后又再次通过 API 扮演其他角色的场景(例如:用户A → 角色B → 角色C)。角色链中的RAM角色可以属于同一个阿里云账号,也可以属于不同账号(跨账号)。

    在角色扮演场景下,可以设置 RoleSessionName 用于审计源身份。然而,在角色链场景下RoleSessionName 可能在多次角色扮演过程中被修改,导致无法准确获取到最初操作发起者的身份信息。

    SourceIdentity一旦在角色链的起点设置,该值将在角色会话中持续存在且不可更改。这确保了即使经过多次角色扮演,最初发起操作的身份依然可以被日志所追溯。

    您可在角色链示例中了解SourceIdentity在角色链中的具体应用场景。

  • 对高权限角色进行精细化权限控制

    管理员可以通过 SourceIdentity 的值或存在性配置精细授权,特别是当使用共享角色(同一角色被多个身份共同使用)执行操作时。

    例如,管理员通过在权限策略中使用条件控制关键字的方式,来强制要求源身份在扮演角色时必须设置符合要求的SourceIdentity值,以此限制只有特定的源身份才能扮演某个高权限角色,或者访问某些核心资源。

设置SourceIdentity的方法

您可以通过以下三种API接口,在调用STS进行角色扮演时设置SourceIdentity

使用AssumeRole接口

在调用AssumeRole API时,通过SourceIdentity参数直接指定源身份信息。例如,设置为Alice。适用于常规角色扮演场景,即一个RAM用户或RAM角色扮演另一个角色。

调用成功后,SourceIdentity会作为独立一级字段在响应中返回。示例如下:

{
  "RequestId": "6894B13B-6D71-4EF5-88FA-F3278173****",
  "AssumedRoleUser": {
    "AssumedRoleId": "34458433936495****:alice",
    "Arn": "acs:ram::123456789012****:role/alice"
  },
  "Credentials": {
    "SecurityToken": "********",
    "Expiration": "2015-04-09T11:52:19Z",
    "AccessKeySecret": "wyLTSmsyPGP1ohvvw8xYgB29dlGI8KMiH2pK****",
    "AccessKeyId": "STS.L4aBSCSJVMuKg5U1****"
  },
  "SourceIdentity": "Alice"
}

具体调用方法,请参见AssumeRole - 获取扮演角色的临时身份凭证

使用AssumeRoleWithSAML接口

用于SAML角色SSO场景中,SourceIdentity的值由身份提供商(IdP)在SAML断言(SAML Assertion)中提供。

您需要在IdP中配置一个SAML属性,并将其映射到用户的身份标识(如用户名)。该属性的名称必须为 https://www.aliyun.com/SAML-Role/Attributes/SourceIdentity

配置完成后,在由IdP所颁发的SAML响应中会包含如下SAML断言(假设将用户的UPN前缀映射为SourceIdentity值):

<Attribute Name="https://www.aliyun.com/SAML-Role/Attributes/SourceIdentity">      
  <AttributeValue>upn_prefix</AttributeValue>
</Attribute>

调用成功后的返回结果同使用AssumeRole接口的场景。具体调用方法,请参见AssumeRoleWithSAML - SAML角色SSO时获取扮演角色的临时身份凭证

使用AssumeRoleWithOIDC接口

OIDC角色SSO场景中,SourceIdentity的值由IdPID token(又称OIDC令牌)中作为claim提供。

您需要在IdP中配置一个自定义ID token claim,并将其映射到用户的身份标识(如用户名)。该claim的名称必须为https://www.aliyun.com/source_identity。例如:

配置完成后,在由IdP所颁发的ID token中会包含如下claim(假设将用户的UPN前缀映射为SourceIdentity值):

{
  "https://www.aliyun.com/source_identity": "upn_prefix"
}

调用成功后的返回结果同使用AssumeRole接口的场景。具体调用方法,请参见AssumeRoleWithOIDC - OIDC角色SSO时获取扮演角色的临时身份凭证

格式要求

  • 长度为2~64个字符。

  • 可包含英文字母、数字以及特殊字符:=,.@-_

  • 不能使用阿里云保留的前缀,如acs:aliyun:alibabacloud:

权限设置与条件控制

您可以结合使用身份权限策略和角色信任策略,对SourceIdentity的使用进行精确控制。

权限操作

名称

类型

使用范围

功能

sts:SetSourceIdentity

权限操作

  • 身份权限策略

  • 角色信任策略

授予在扮演角色时设置SourceIdentity的权限。

权限操作配置示例

要允许一个身份(RAM用户或角色)在调用AssumeRole时设置SourceIdentity,您必须同时在扮演者的身份权限策略和目标角色的角色信任策略中授予sts:SetSourceIdentity操作权限,也即在Action块中增加sts:SetSourceIdentity

  • 身份权限策略示例(授予扮演者):

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "sts:AssumeRole",
            "sts:SetSourceIdentity"
          ],
          "Resource": "acs:ram::ACCOUNT_ID:role/TARGET_ROLE"
        }
      ]
    }
  • 角色信任策略示例(配置于被扮演的角色):

    {
      "Statement": [
        {
          "Action": [
            "sts:AssumeRole",
            "sts:SetSourceIdentity"
          ],
          "Effect": "Allow",
          "Principal": {
            "RAM": [
              "acs:ram::ACCOUNT_ID:root"
            ]
          }
        }
      ],
      "Version": "1"
    }

角色SSO场景下的权限操作配置示例

在通过调用AssumeRoleWithSAMLAssumeRoleWithOIDC接口进行角色扮演的场景下,您仅需在目标角色的角色信任策略中授予sts:SetSourceIdentity操作权限。例如(以SAML角色SSO为例):

{
  "Statement": [
    {
      "Action": [
        "sts:AssumeRole",
        "sts:SetSourceIdentity"
      ],
      "Condition": {
        "StringEquals": {
          "saml:recipient": [
            "https://signin.aliyun.com/saml-role/sso"
          ]
        }
      },
      "Effect": "Allow",
      "Principal": {
        "Federated": [
          "acs:ram::ACCOUNT_ID:saml-provider/PROVIDER_NAME"
        ]
      }
    }
  ],
  "Version": "1"
}
重要

如果您在IdP中配置了SourceIdentity属性,则所有与该IdP关联的角色,其信任策略中都必须包含sts:SetSourceIdentity操作。否则,用户通过SSO登录时会因缺少权限而失败。

条件关键字

名称

类型

使用范围

功能

sts:SourceIdentity

条件关键字

  • 身份权限策略

  • 角色信任策略

关联一个或多个SourceIdentity值。用于匹配角色扮演请求中的SourceIdentity值,以此判断是否允许请求者设置某个SourceIdentity值。

acs:SourceIdentity

条件关键字(全局)

  • 身份权限策略

关联一个或多个SourceIdentity值。用于匹配角色会话中已存在的SourceIdentity值,以此判断在访问云资源/云服务时,当前会话是否包含特定的SourceIdentity值。

说明

当前,acs:SourceIdentity条件关键字仅在STS服务的策略评估中生效。

sts:SourceIdentityacs:SourceIdentity条件关键字的区别是:

  • sts:SourceIdentity匹配的是角色扮演请求中的SourceIdentity属性。

  • acs:SourceIdentity匹配的是在角色扮演成功后,存在于角色会话(包括STS token)中的SourceIdentity属性。

如果是首次进行角色扮演,应在策略(包括身份权限策略和角色信任策略)中配置sts:SourceIdentity条件关键字。由于此时还没有产生有效的角色会话,因此使用acs:SourceIdentity条件关键字将导致角色扮演失败。

条件控制示例

通过在策略的Condition块中使用sts:SourceIdentity条件关键字,您可以强制要求扮演角色时必须传入符合特定要求的SourceIdentity值。可以在以下两类策略(任一或全部)中配置条件:

  • 在身份权限策略中设置条件:限制该身份在扮演特定角色时,必须设置符合规定的SourceIdentity值。

  • 在角色信任策略中设置条件:限制任何身份在扮演该角色时,都必须设置符合规定的SourceIdentity值。

请注意,在策略的Action块中也必须添加sts:SetSourceIdentity操作权限,否则将无法实现条件控制功能。

说明

您无法通过RAM控制台的切换身份功能扮演强制要求设置SourceIdentity的角色,因为控制台不支持输入该参数。

假设有一个名为prod-role的生产环境高权限RAM角色。管理员需要实现以下控制:

  1. 只有RAM用户AliceBob可以扮演prod-role

  2. 扮演prod-role时,必须设置SourceIdentity,且值必须与扮演者用户名匹配(例如,Alice扮演时可以设置值为alicealice@exampledomain.com)。

步骤1:配置prod-role的角色信任策略

该策略确保只有AliceBob可以扮演此角色,并且请求中必须包含值为alicebobSourceIdentity

{
  "Statement": [
    {
      "Action": [
        "sts:AssumeRole",
        "sts:SetSourceIdentity"
      ],
      "Condition": {
        "StringLike": {
          "sts:SourceIdentity": [
            "alice*",
            "bob*"
          ]
        }
      },
      "Effect": "Allow",
      "Principal": {
        "RAM": [
          "acs:ram::ACCOUNT_ID:user/alice",
          "acs:ram::ACCOUNT_ID:user/bob"
        ]
      }
    }
  ],
  "Version": "1"
}

步骤2:为用户AliceBob配置身份权限策略

以下策略分别授予AliceBob扮演prod-role的权限,并强制他们在请求中设置与各自用户名匹配的SourceIdentity

  • Alice的身份权限策略

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "sts:AssumeRole",
            "sts:SetSourceIdentity"
          ],
          "Resource": "acs:ram::ACCOUNT_ID:role/prod-role",
          "Condition": {
            "StringLike": {
              "sts:SourceIdentity": [
                "alice*"
              ]
            }
          }
        }
      ]
    }
  • Bob的身份权限策略

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "sts:AssumeRole",
            "sts:SetSourceIdentity"
          ],
          "Resource": "acs:ram::ACCOUNT_ID:role/prod-role",
          "Condition": {
            "StringLike": {
              "sts:SourceIdentity": [
                "bob*"
              ]
            }
          }
        }
      ]
    }

角色SSO场景下的条件控制示例

假设dev-role角色只允许通过SAML角色SSO方式扮演,并且仅限于员工号为employeeid-aliceemployeeid-bob的用户。IdP会将用户的员工号作为SourceIdentity的值加入SAML断言。

dev-role的信任策略配置如下:

{
  "Statement": [
    {
      "Action": [
        "sts:AssumeRole",
        "sts:SetSourceIdentity"
      ],
      "Condition": {
        "StringEquals": {
          "saml:recipient": [
            "https://signin.aliyun.com/saml-role/sso"
          ],
          "sts:SourceIdentity": [
            "employeeid-alice",
            "employeeid-bob"
          ]
        }
      },
      "Effect": "Allow",
      "Principal": {
        "Federated": [
          "acs:ram::ACCOUNT_ID:saml-provider/PROVIDER_NAME"
        ]
      }
    }
  ],
  "Version": "1"
}

条件控制使用建议

  • 先测试,后生产:请勿直接在生产环境中启用SourceIdentity的强制策略(包括配置了sts:SourceIdentity条件关键字的身份权限策略角色信任策略)。建议先使用测试角色和策略进行充分验证,确认无误后,再逐步应用于生产环境。

  • 提前沟通:在启用强制策略前,请务必提前告知相关用户SourceIdentity的使用方法和允许设置的值,以避免影响正常业务。

角色链示例

场景描述

一个CI/CD自动化工具(如Jenkins)使用RAM角色automation-role运行。该角色允许被开发者(如AliceBob)扮演。

开发者(如Alice)通过该工具将某应用部署到生产环境的OSS Bucket。部署操作需要扮演一个更高权限的角色deploy-role,该角色拥有OSS Bucket的写入权限。

Alice、Bob以及automation-role属于阿里云账号A,deploy-role属于阿里云账号B。

业务需求与工作流程

只允许当原始调用者是Alice时,automation-role才能成功扮演deploy-role。来自其他用户(如Bob)的调用请求应该被拒绝。

工作流程如下:

  1. Alice调用AssumeRole接口扮演automation-role,并在请求中设置SourceIdentityalice

  2. automation-role获得临时安全令牌(STS token)后,再调用AssumeRole接口扮演deploy-role。此时,SourceIdentity的值会被自动传递。

  3. deploy-role的信任策略会检查传入的SourceIdentity是否为alice,如验证通过则允许扮演。

策略配置步骤

步骤1: 修改deploy-role的信任策略

只信任来自账号A下的角色automation-role的扮演请求,并且要求SourceIdentity的值必须是alice

{
  "Statement": [
    {
      "Action": [
        "sts:AssumeRole",
        "sts:SetSourceIdentity"
      ],
      "Condition": {
        "StringEquals": {
          "acs:SourceIdentity": [
            "alice"
          ]
        }
      },
      "Effect": "Allow",
      "Principal": {
        "RAM": [
          "acs:ram::ACCOUNT_A_ID:role/automation-role"
        ]
      }
    }
  ],
  "Version": "1"
}
说明

在上述角色信任策略中,使用的是条件关键字acs:SourceIdentity而非sts:SourceIdentity。这确保deploy-role角色只接受来自automation-role角色,且角色会话中SourceIdentity已被设置为alice的访问请求。

步骤2: 修改automation-role的权限与信任策略

  • 身份权限策略:允许角色automation-role扮演账号B下的角色deploy-role

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "sts:AssumeRole",
            "sts:SetSourceIdentity"
          ],
          "Resource": "acs:ram::ACCOUNT_B_ID:role/deploy-role"
        }
      ]
    }
  • 信任策略:允许AliceBob扮演automation-role

    {
      "Statement": [
        {
          "Action": [
            "sts:AssumeRole",
            "sts:SetSourceIdentity"
          ],
          "Effect": "Allow",
          "Principal": {
            "RAM": [
              "acs:ram::ACCOUNT_A_ID:user/alice",
              "acs:ram::ACCOUNT_A_ID:user/bob"
            ]
          }
        }
      ],
      "Version": "1"
    }

步骤3:修改AliceBob的身份权限策略

允许他们扮演角色automation-role,并强制设置与用户名完全匹配的SourceIdentity值。

  • Alice的身份权限策略

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "sts:AssumeRole",
            "sts:SetSourceIdentity"
          ],
          "Resource": "acs:ram::ACCOUNT_A_ID:role/automation-role",
          "Condition": {
            "StringEquals": {
              "sts:SourceIdentity": [
                "alice"
              ]
            }
          }
        }
      ]
    }
  • Bob的身份权限策略

    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "sts:AssumeRole",
            "sts:SetSourceIdentity"
          ],
          "Resource": "acs:ram::ACCOUNT_A_ID:role/automation-role",
          "Condition": {
            "StringEquals": {
              "sts:SourceIdentity": [
                "bob"
              ]
            }
          }
        }
      ]
    }

在操作审计中查看SourceIdentity

您可以在操作审计(ActionTrail)的审计日志中找到SourceIdentity字段,用于身份溯源。

  • AssumeRole*事件日志中: SourceIdentity出现在responseElementsrequestParameters字段下。

    {
      "eventId": "9BCD28D0-7FDB-5BF2-9302-CDA6CCC5****",
      "eventVersion": 1,
      "responseElements": {
        "SourceIdentity": "alice",
        "RequestId": "9BCD28D0-7FDB-5BF2-9302-CDA6CCC5****",
        ...
      },
      ...
      "requestParameters": {
        "SourceIdentity": "alice",
        "X-Acs-Request-Id": "9BCD28D0-7FDB-5BF2-9302-CDA6CCC5****",
        ...
      },
      "serviceName": "Sts",
      "eventName": "AssumeRole",
      ...
    }
    
  • 在访问云资源的事件日志中: SourceIdentity出现在userIdentity.sessionContext字段下。

    {
      "eventId": "46B5B0A1-19F7-5A56-BE2C-0BCFE5F8****",
      "userIdentity": {
        "sessionContext": {
          "sourceIdentity": "alice",
          ...
        },
        "type": "assumed-role",
        ...
      },
      "serviceName": "Ecs",
      "eventName": "DescribeInstances",
      ...
    }

常见故障排除

配置SourceIdentity时最常见的问题是权限不足。以下是两种典型的错误场景及其排查方法。

场景一:身份权限策略导致的问题

报错信息

{
  "RequestId": "AC9DDEC1-3E1F-50B8-A2D1-BAA155FD****",
  "Code": "NoPermission",
  "Message": "You are not authorized to do this action. You should be authorized by RAM.",
  "AccessDeniedDetail": {
    "PolicyType": "AccountLevelIdentityBasedPolicy",
    "AuthAction": "sts:SetSourceIdentity",
    ...
  }
}

原因分析

  • "PolicyType": "AccountLevelIdentityBasedPolicy" 表明错误源于调用者的身份权限策略

  • "AuthAction": "sts:SetSourceIdentity" 表明缺少sts:SetSourceIdentity操作的权限。

解决方案: 联系管理员检查调用者的身份权限策略,确保:

  1. 策略中包含了"Action": "sts:SetSourceIdentity"

  2. 策略的Resource范围包含了您尝试扮演的目标角色。

  3. 如果策略中包含Condition,请确认请求中的SourceIdentity值符合条件。

场景二:角色信任策略导致的问题

报错信息

{
  "RequestId": "ECC91EE1-0EB0-5E79-B3F5-E54FD8B9****",
  "Code": "NoPermission",
  "Message": "You are not authorized to do this action. You should be authorized by RAM.",
  "AccessDeniedDetail": {
    "PolicyType": "AssumeRolePolicy",
    "AuthAction": "sts:SetSourceIdentity",
    ...
  }
}

原因分析

  • "PolicyType": "AssumeRolePolicy" 表明错误源于目标角色的角色信任策略

  • "AuthAction": "sts:SetSourceIdentity" 表明目标角色不信任sts:SetSourceIdentity这个操作。

解决方案: 联系管理员检查目标角色的角色信任策略,确保:

  1. 策略中包含了"Action": "sts:SetSourceIdentity"

  2. 如果策略中包含Condition,请确认请求中的SourceIdentity值符合条件。

一般排查建议

  1. 缩小范围:如果在设置SourceIdentity时遇到权限问题,可先尝试移除SourceIdentity参数并再次扮演角色。如果此时操作成功,则问题基本可以定位在SourceIdentity相关的权限配置上。

  2. 分析报错:仔细阅读报错信息中的AccessDeniedDetail部分,尤其是PolicyType字段,它可以帮助您快速定位问题源于身份权限策略还是角色信任策略。

  3. 使用诊断工具:如果您只有RequestId,可以使用OpenAPI问题诊断工具。输入RequestId后,系统会返回详细的诊断信息,帮助您定位权限问题。例如:

    image

  4. 对比策略与请求:定位到具体策略后,请仔细核对策略中的ResourceCondition等设置,确保其与API请求中的目标角色ARNSourceIdentity值等参数匹配。

更多权限问题排错方法,请参见:如何排查无权限的访问错误