IAM 教程:使用 IAM 角色委托跨 AWS 账户的访问权限
本教程将指导您如何使用角色来委派对您拥有的不同 AWS 账户(称为目标和原始)中资源的访问权限。您将与另一账户中的用户共享一个账户中的资源。通过以这种方式设置跨账户存取,您不需要在每个账户中创建单个 IAM 用户。此外,用户不必从一个账户注销并登录另一个账户,即可访问不同 AWS 账户 中的资源。配置角色后,您将了解如何从 AWS Management Console、AWS CLI 和 API 中使用角色。
在本教程中,目标账户管理不同应用程序和团队访问的应用程序数据。在每个账户中,您将应用程序信息存储在 Amazon S3 存储桶中。您可以在原始账户中管理 IAM 用户,其中有两个 IAM 用户角色:开发人员和分析师。开发人员和分析师使用原始账户生成由多个微服务共享的数据。两个角色都拥有在原始账户中工作的权限,可访问该账户中的资源。开发人员必须不时更新目标账户中的共享数据。开发人员将此数据存储在名为 amzn-s3-demo-bucket-shared-container
的 Amazon S3 存储桶中。
在本教程结束时,您将拥有以下内容:
-
原始账户(受信任账户)中能够担任目标账户中特定角色的用户。
-
目标账户(可信账户)中能够访问特定 Amazon S3 存储桶的角色。
-
目标账户中的
amzn-s3-demo-bucket-shared-container
存储桶。
开发人员可以在 AWS Management Console 中使用该角色访问目标账户中的 amzn-s3-demo-bucket-shared-container
存储桶。他们还可以使用通过该角色提供的临时凭证进行了身份验证的 API 调用来访问该存储桶。分析师同样尝试使用该角色,但会失败。
此工作流程具有三个基本步骤:
- 在目标账户中创建角色
-
首先,您使用 AWS Management Console 在目标账户(ID 号 999999999999)和原始账户(ID 号 111111111111)之间建立信任。可通过创建名为 UpdateData 的 IAM 角色 角色开始。当您创建角色时,将原始账户定义为受信任实体,并指定一个权限策略,允许受信任用户更新
amzn-s3-demo-bucket-shared-container
存储桶。 - 向角色授予访问权限
-
在本节中,您将修改角色策略,以拒绝分析师访问
UpdateData
角色。这种情况下,因为分析师有 PowerUser 访问权限,您必须显式拒绝使用该角色的能力。 - 通过切换角色测试访问权限
-
最后,以开发人员的身份使用
UpdateData
角色更新目标账户中的amzn-s3-demo-bucket-shared-container
存储桶。您可以了解如何通过 AWS 控制台、AWS CLI 和 API 访问角色。
注意事项
在使用 IAM 角色跨 AWS 账户 委派资源访问权限之前,务必考虑以下几点:
-
以 AWS 账户根用户 身份登录后无法切换至角色。
-
IAM 角色和基于资源的策略仅在单个分区内跨账户委派访问权限。例如,假定您在标准
aws
分区的美国西部(加利福尼亚北部)中有一个账户。您在aws-cn
分区的中国(北京)中也有一个账户。您不能使用中国(北京)的账户中 Amazon S3 基于资源的策略,来允许标准aws
账户中用户的访问权限。 -
您可以使用 AWS IAM Identity Center 通过安全断言标记语言(SAML)为外部 AWS 账户(AWS Organizations 之外的账户)单点登录(SSO)提供便利。有关详细信息,请参阅 Integrate external AWS 账户 into AWS IAM Identity Center for central access management with independent billing using SAML 2.0
-
您可以将角色与 Amazon EC2 实例或 AWS Lambda 函数等 AWS 资源关联。有关详细信息,请参阅创建向 AWS 服务委派权限的角色。
-
如果您想让一个应用程序担任另一个 AWS 账户 中的角色,则可以使用 AWS SDK 跨账户担任角色。有关更多信息,请参阅《AWS SDKs and Tools Reference Guide》中的 Authentication and access。
-
使用 AWS Management Console 切换角色仅适用于不需要
ExternalId
的账户。例如,假定您将您账户的访问权限授予第三方,并在权限策略的Condition
元素中要求ExternalId
。在此情况下,第三方只能通过使用 AWS API 或命令行工具访问您的账户。第三方不能使用控制台,因为它必须提供ExternalId
值。有关此方案的更多信息,请参阅 AWS 安全博客中的 访问第三方拥有的 AWS 账户 和 How to enable cross account access to the AWS Management Console。
先决条件
本教程假定您已准备好以下各项:
-
您可以使用的两个独立 AWS 账户,一个代表原始账户,一个代表目标账户。
-
原始账户中的用户和角色的创建和配置方式如下:
职位 用户 权限 开发人员 David 两个用户均可以登录和使用原始账户中的 AWS Management Console。 分析师 Jane -
您不需要在目标账户中创建任何用户。
-
在目标账户中创建的 Amazon S3 存储桶。在本教程中,您可以将其称为
amzn-s3-demo-bucket-shared-container
,但由于 S3 存储桶名称必须全局唯一,您必须使用具有其他名称的存储桶。
在目标账户中创建角色
您可以允许一个 AWS 账户 中的用户访问其他 AWS 账户 中的资源。在本教程中,我们将通过创建一个角色来实现这一点,该角色定义可以访问它的人员以及它向切换到它的用户授予的权限。
在教程的这一步中,您将在目标账户中创建角色,并将原始账户指定为受信任实体。此外,限制更改角色的权限,只有 amzn-s3-demo-bucket-shared-container
存储桶的读写权限。任何人只要获得使用该角色的权限,就能对 shared-container
存储桶进行读写。
在创建角色之前,您需要原始 AWS 账户 的账户 ID。每个 AWS 账户 均拥有向其分配的唯一账户 ID 标识符。
获取原始 AWS 账户 ID
-
以原始账户管理员身份登录 AWS Management Console 并在 https://console.aws.amazon.com/iam/
上打开 IAM 控制台。 -
在 IAM 控制台中,在右上角的导航栏上选择您的用户名。它通常类似于:
username
@account_ID_number_or_alias
。对于此场景,您可以将账户 ID 111111111111 用于原始账户。但是,如果您在测试环境中使用此方案,则应使用有效的账户 ID。
在目标账户中创建可供原始账户使用的角色
-
以目标账户管理员身份登录 AWS Management Console 并打开 IAM 控制台。
-
创建角色之前,准备好定义角色所需权限的托管策略。您可在以后的步骤中将此策略附加到角色。
您想要设置针对
amzn-s3-demo-bucket-shared-container
存储桶的读写权限。尽管 AWS 提供了一些 Amazon S3 托管策略,但这些策略并未提供对单个 Amazon S3 存储桶的读写访问权限。您可以创建自己的自定义策略。在导航窗格中选择策略,然后选择创建策略。
-
选择 JSON 选项卡,然后复制以下 JSON 策略文档中的文本。将该文本粘贴到 JSON 文本框中,并将资源 ARN (
arn:aws:s3:::shared-container
) 替换为与您的 Amazon S3 存储桶对应的真实资源 ARN。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": "
arn:aws:s3:::amzn-s3-demo-bucket-shared-container
" }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-shared-container/*
" } ] }ListAllMyBuckets
操作会授予列出已通过身份验证的请求发出者所拥有的全部存储桶的权限。ListBucket
权限允许用户浏览amzn-s3-demo-bucket-shared-container
存储桶中的对象。GetObject
、PutObject
、DeleteObject
权限允许用户查看、更新和删除amzn-s3-demo-bucket-shared-container
存储桶中的内容。注意
您可以随时在可视化和 JSON 编辑器选项卡之间切换。不过,如果您进行更改或在可视化编辑器中选择下一步,IAM 可能会调整您的策略结构以针对可视化编辑器进行优化。有关更多信息,请参阅 调整策略结构。
-
在查看并创建页面上,键入
read-write-app-bucket
作为策略名称。查看您的策略授予的权限,然后选择创建策略以保存您的工作。新策略会显示在托管策略列表中。
-
在导航窗格中,选择角色,然后选择创建角色。
-
选择 AWS 账户 角色类型。
-
对于账户 ID,键入原始账户 ID。
本教程使用原始账户的示例账户 ID
111111111111
。您应使用有效的账户 ID。如果使用无效的账户 ID,如111111111111
,IAM 不会让您创建新角色。现在,您不必要求外部 ID 或要求用户拥有多重身份验证 (MFA) 就可以担任该角色。将这些选项保持未选中状态。有关更多信息,请参阅 IAM 中的 AWS 多重身份验证。
-
选择 Next: Permissions 设置将与角色关联的权限。
-
选中您之前创建的策略旁边的复选框。
提示
对于 Filter,选择 Customer managed 对列表进行筛选,使其只包含您创建的策略。这会隐藏 AWS 创建的策略,更容易找到您所需要的策略。
然后选择下一步。
-
(可选)以键值对形式附加标签来向角色添加元数据。有关在 IAM 中使用标签的更多信息,请参阅 AWS Identity and Access Management 资源的标签。
-
(可选)对于 Description(描述),输入新角色的描述。
-
检查角色后,选择 Create role。
UpdateData
角色显示在角色列表中。
现在,您必须获取该角色的 Amazon Resource Name (ARN),这是角色的唯一标识。当您修改原始账户中的开发人员角色时,可指定目标账户中的角色 ARN 以授予或拒绝权限。
获取 UpdateData 的 ARN
-
在 IAM 控制台的导航窗格中,选择角色。
-
在角色列表中,选择
UpdateData
角色。 -
在详细信息窗格的 Summary (摘要) 部分中,复制 Role ARN (角色 ARN) 值。
目标账户的账户 ID 是 999999999999,因此角色 ARN 是
arn:aws:iam::999999999999:role/UpdateData
。确保为目标账户提供真实的 AWS 账户 ID。
此时,您已经在目标账户和原始账户之间建立了信任。您通过在目标账户中创建一个角色来将原始账户标识为受信的主体,从而实现这一点。您还可以定义切换到 UpdateData
角色的用户可执行哪些操作。
接下来,修改开发人员角色的权限。
向角色授予访问权限
此时,分析师和开发人员都拥有允许其管理原始账户中数据的权限。使用以下必要步骤添加权限以允许切换到角色。
修改开发人员角色以允许其切换到 UpdateData 角色
-
以原始账户中的管理员身份登录,打开 IAM 控制台。
-
选择组,然后选择开发人员。
-
请选择 Permissions(权限)选项卡,然后选择 Add permissions(添加权限),接着选择 Create inline policy(创建内联策略)。
-
选择 JSON 选项卡。
-
添加以下策略语句,允许对目标账户中的
UpdateData
角色执行AssumeRole
操作。请确保将Resource
元素中的DESTINATION-ACCOUNT-ID
更改为目标账户的实际 AWS 账户 ID。{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::
DESTINATION-ACCOUNT-ID
:role/UpdateData" } }Allow
效果显式允许开发人员组访问目标账户中的UpdateData
角色。尝试访问该角色的任何开发人员都会成功。 -
选择查看策略。
-
键入名称,例如
allow-assume-S3-role-in-destination
。 -
选择创建策略。
在大多数环境中,可能不需要执行以下步骤。但是,如果您使用 PowerUserAccess,则某些组可能已能够切换角色。以下过程介绍如何向分析师组添加 "Deny"
权限,以确保其无法担任角色。如果您的环境中不需要此过程,建议不要添加该权限。"Deny"
权限会让整个权限体系更为复杂、难以管理和理解。仅当您没有更好的选择时才使用 "Deny"
权限。
修改分析师角色以拒绝担任 UpdateData
角色的权限
-
选择角色,然后选择分析师。
-
请选择 Permissions(权限)选项卡,然后选择 Add permissions(添加权限),接着选择 Create inline policy(创建内联策略)。
-
选择 JSON 选项卡。
-
添加以下策略语句以拒绝对
AssumeRole
角色执行的UpdateData
操作。请确保将Resource
元素中的DESTINATION-ACCOUNT-ID
更改为目标账户的实际 AWS 账户 ID。{ "Version": "2012-10-17", "Statement": { "Effect": "Deny", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::
DESTINATION-ACCOUNT-ID
:role/UpdateData" } }Deny
效果显式拒绝分析师组访问目标账户中的UpdateData
角色。任何尝试访问该角色的分析师都会收到一条拒绝访问信息。 -
选择查看策略。
-
键入名称,例如
deny-assume-S3-role-in-destination
。 -
选择创建策略。
开发人员角色现在有使用目标账户中 UpdateData
角色的应权限。禁止分析师角色使用 UpdateData
角色。
接下来,您将了解开发人员 David 如何能访问目标账户中的 amzn-s3-demo-bucket-shared-container
存储桶。David 可以从 AWS Management Console、AWS CLI 或 AWS API 访问存储桶。
通过切换角色测试访问权限
完成本教程的前两个步骤后,您将具有一个可以授予对目标账户中资源的访问权限的角色。您还将在原始账户中有一个角色,并且用户可以使用该角色。此步骤讨论如何对从 AWS Management Console、AWS CLI 和 AWS API 切换到该角色进行测试。
要获取有关在使用 IAM 角色时可能遇到的常见问题的帮助,请参阅排查 IAM 角色问题。
切换角色(控制台)
如果 David 需要在 AWS Management Console 中更新目标账户中的数据,则他可以使用切换角色来进行更新。他指定账户 ID 或别名以及角色名称,他的权限会立即切换为该角色允许的权限。然后,他可以通过控制台使用 amzn-s3-demo-bucket-shared-container
存储桶,但是无法使用目标中的其他任何资源。当 David 使用该角色时,他无法使用其在原始账户中的高级用户权限。这是因为,一次仅一组权限能够生效。
David 可以使用 IAM 提供的两种方法进入 Switch Role(切换角色)页:
-
David 收到其管理员提供的一个链接,该链接指向一个预定义的“Switch Role”(切换角色)配置。该链接在 Create role 向导最后一页上或在跨账户角色的 Role Summary 页面上提供给管理员。选择该链接将引导 David 进入已填写 Account ID(账户 ID)和 Role name(角色姓名)字段的 Switch Role(切换角色)页面。David 只需选择 Switch Role(切换角色)。
-
管理员不会通过电子邮件发送该链接,而是发送账户 ID 号和角色名称值。要切换角色,David 必须手动输入这些值。以下步骤对此进行说明。
要代入角色
-
David 使用其常规用户以原始账户登录到 AWS Management Console。
-
他们选择管理员通过电子邮件向其发送的链接。该会将 David 跳转至 Switch Role(切换角色)页面,其中已填写了账户 ID 或别名和角色名称信息。
—或者—
David 在导航栏上选择其姓名 [Identity(身份)菜单],然后选择 Switch Roles(切换角色)。
如果这是 David 首次通过这种方式尝试访问“Switch Role (切换角色)”页面,则他会首先登录初始 Switch Role (切换角色) 页面。此页面提供有关切换角色如何使用户可以跨 AWS 账户 管理资源的其他信息。David 必须选择此页面上的 Switch Role(切换角色)才能完成此过程的其余步骤。
-
接下来,为了访问该角色,David 必须手动键入目标账户 ID 号(
999999999999
)和角色名称(UpdateData
)。此外,David 还想监控当前 IAM 中处于活动状态的角色及相关权限。为了跟踪此信息,他在 Display Name(显示名称)文本框中键入
Destination
,并选择红色选项,然后选择 Switch Role(切换角色)。 -
David 现在可以通过 Amazon S3 控制台使用 Amazon S3 存储桶,或使用
UpdateData
角色有权限的其他任何资源。 -
完成后,David 可返回其原始权限。为此,他们可以选择导航栏上的目标角色显示名称,然后选择返回 David @ 111111111111。
-
当 David 下次要切换角色并在导航栏中选择身份菜单时,他将看到目标条目仍在上次的位置。他可以选择该条目立即切换角色,无需重新输入账户 ID 和角色名称。
切换角色 (AWS CLI)
如果 David 需要在目标环境中的命令行上工作,他可以使用 AWS CLIaws sts
assume-role
命令并传递角色 ARN 以获取该角色的临时安全凭证。然后,他在环境变量中配置这些凭证,使后续的 AWS CLI 命令能够使用该角色的权限执行。当 David 使用该角色时,他不能同时使用他在原始账户中的高级用户权限,因为同一时间只有一组权限有效。
请注意,所有访问密钥和令牌都只是示例,不能原样照用。请用您的实际环境的适当值替换。
要代入角色
-
David 打开命令提示符窗口,运行以下命令确认 AWS CLI 客户端正在工作:
aws help
注意
David 的默认环境使用他通过
David
命令创建的默认配置文件中的aws configure
用户凭证。有关更多信息,请参阅《AWS Command Line Interface 用户指南》中的配置 AWS Command Line Interface。 -
他通过运行以下命令开始角色切换过程,以切换到目标账户中的
UpdateData
角色。他从创建该角色的管理员处获得了角色 ARN。该命令还需要您提供一个会话名称,您可以选择任何文本作为该名称。aws sts assume-role --role-arn "arn:aws:iam::999999999999:role/UpdateData" --role-session-name "David-ProdUpdate"
然后 David 在输出中看到以下内容:
{ "Credentials": { "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEeYjs1M2FUIgIJx9tQqNMBEXAMPLE CvSRyh0FW7jEXAMPLEW+vE/7s1HRpXviG7b+qYf4nD00EXAMPLEmj4wxS04L/uZEXAMPLECihzFB5lTYLto9dyBgSDy EXAMPLE9/g7QRUhZp4bqbEXAMPLENwGPyOj59pFA4lNKCIkVgkREXAMPLEjlzxQ7y52gekeVEXAMPLEDiB9ST3Uuysg sKdEXAMPLE1TVastU1A0SKFEXAMPLEiywCC/Cs8EXAMPLEpZgOs+6hz4AP4KEXAMPLERbASP+4eZScEXAMPLEsnf87e NhyDHq6ikBQ==", "Expiration": "2014-12-11T23:08:07Z", "AccessKeyId": "AKIAIOSFODNN7EXAMPLE" } }
-
David 在输出的“Credentials”(凭证)部分中看到了他们所需要的三个部分。
-
AccessKeyId
-
SecretAccessKey
-
SessionToken
David 需要配置 AWS CLI 环境,以在后续的调用中使用这些参数。有关各种凭证配置方法的信息,请参阅配置 AWS Command Line Interface。您不能使用
aws configure
命令,因为它不支持捕获会话令牌。但是,您可手动将信息输入到配置文件中。由于这些是到期时间相对较短的临时凭证,将它们添加到您当前的命令行会话环境中是最简单的。 -
-
为了将三个值添加到环境,David 将上一步的输出剪切并粘贴到以下命令中。您可能希望剪切并粘贴到简单文本编辑器中,以解决会话令牌输出中的换行问题。即使此处为清晰起见,将输出显示为换行格式,在添加时也必须是单个长字符串形式。
以下示例显示了 Windows 环境中的命令,其中“set”是创建环境变量的命令。在 Linux 或 MacOS 计算机上,您将改用“export”命令。该示例的其余部分对于三种环境均有效。
有关使用适用于 Windows Powershell 的工具的详细信息,请参阅 切换到 IAM 角色(Tools for Windows PowerShell)
set AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE set AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY set AWS_SESSION_TOKEN=AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEeYjs1M2FUIgIJx9tQqNMBEXAMPLECvS Ryh0FW7jEXAMPLEW+vE/7s1HRpXviG7b+qYf4nD00EXAMPLEmj4wxS04L/uZEXAMPLECihzFB5lTYLto9dyBgSDyEXA MPLEKEY9/g7QRUhZp4bqbEXAMPLENwGPyOj59pFA4lNKCIkVgkREXAMPLEjlzxQ7y52gekeVEXAMPLEDiB9ST3UusKd EXAMPLE1TVastU1A0SKFEXAMPLEiywCC/Cs8EXAMPLEpZgOs+6hz4AP4KEXAMPLERbASP+4eZScEXAMPLENhykxiHen DHq6ikBQ==
此时,以下所有命令都在这些凭证确定的角色的权限下运行。对 David 而言就是
UpdateData
角色。重要
您可以将常用的配置设置和凭证保存在由 AWS CLI 维护的文件中。有关更多信息,请参阅《AWS Command Line Interface User Guide》中的 Using existing configuration and credentials files。
-
运行该命令访问目标账户中的资源。在此示例中,David 使用以下命令列出其 S3 存储桶的内容。
aws s3 ls s3://shared-container
因为 Amazon S3 存储桶名称通常是唯一的,所以无需指定拥有存储桶的账户 ID。要访问其他 AWS 服务的资源,请参阅该服务的 AWS CLI 文档,了解引用其资源所需使用的命令和语法。
使用 AssumeRole (AWS API)
当 David 需要通过代码来更新目标账户时,他执行 AssumeRole
调用来担任 UpdateData
角色。该调用返回临时凭证,他可以使用这些凭证访问目标账户中的 amzn-s3-demo-bucket-shared-container
存储桶。使用这些凭证,David 可以调用 API 以更新 amzn-s3-demo-bucket-shared-container
存储桶。但是,即使他在原始账户中拥有高级用户权限,也无法通过调用 API 来访问目标账户中的任何其他资源。
要代入角色
-
David 把
AssumeRole
视为应用程序的一个段调用。他们必须指定UpdateData
ARN:arn:aws:iam::999999999999:role/UpdateData
。AssumeRole
调用返回的结果包含临时凭证以及AccessKeyId
和SecretAccessKey
。它还包括一个Expiration
时间,该时间指示凭证何时到期(届时您必须请求新的凭证)。当您使用 AWS SDK 设置角色链时,许多凭证提供者会在凭证过期之前自动刷新凭证。 -
David 使用那些临时证书调用
s3:PutObject
升级amzn-s3-demo-bucket-shared-container
存储段。他们会将凭证作为AuthParams
参数传递给 API 调用。由于临时角色凭证只有amzn-s3-demo-bucket-shared-container
存储桶的读写权限,因此对目标账户的任何其他操作都会被拒绝。
有关代码示例 (使用 Python),请参阅切换到 IAM 角色(AWS API)。
其他 资源
以下资源可帮助您了解有关本教程中主题的更多信息:
-
有关 IAM 用户的更多信息,请参阅 IAM 身份 。
-
有关 Amazon S3 存储桶的更多信息,请参阅 Amazon Simple Storage Service 用户指南中的创建存储桶。
-
要了解您信任区域之外的账户(受信任的企业或账户)中的主体是否有权承担您的角色,请参阅什么是 IAM Access Analyzer?。
Summary
您已经完成跨账户 API 访问教程。您创建了一个角色与另一个账户之间建立信任关系,并规定了受信任实体可以执行哪些操作。然后,您修改了角色策略以控制哪些 IAM 用户可以访问该角色。最终,原始账户的开发人员可以使用临时凭证升级目标账户中的 amzn-s3-demo-bucket-shared-container
存储桶。