跳至主要内容

跨 AWS 账户资源访问授权的四种方法

前言

随着部署在 AWS 上环境的演变发展,你可能需要进行跨账户资源访问授权。导致需要跨账户资源授权的原因有很多,例如为了实现跨多个 AWS 账户的集中操作、在组织内部多个团队或项目之间共享资源、或者集成第三方服务。然而,在授予跨账户资源访问权限时,需认真考虑安全性、可用性和可管理性要求。

在本文中,我们将探讨四种通过基于资源的策略来授予跨账户资源访问权限的不同方法。其中的每种方法都有其独特利弊,你需要根据你的具体要求和使用场景选择最合适的方法。

前提条件

  • 难度:中级

  • 时间:20 分钟

  • 相关产品:AWS IAM

  • 上次更新时间:2025 年 2 月 24 日

  • 所需费用:免费

概述

全部打开

AWS Identity and Access Management (IAM) 中,可通过基于身份的策略和基于资源的策略授予跨账户资源访问权限。基于身份的策略适用于 IAM 角色,而基于资源的策略适用于 Amazon Simple Storage Service (Amazon S3) 存储桶和 AWS Key Management Service (AWS KMS) 密钥等资源。如果使用基于资源的策略,你需要指定一个或多个允许访问指定资源的主体(IAM 用户或角色)。

在基于资源的策略中,指定主体的方式会对解决方案的安全性和可用性产生一些影响。本文的重点是帮助你了解这些影响,并帮助你根据使用场景做出正确选择。

假设你的一个 AWS 账户(账户 A)中有一个 S3 存储桶,而另一个 AWS 账户(账户 B)中的多个不同主体需要访问该存储桶。在此场景中,我们假设账户 B 中的主体关联的基于身份的策略授予了这些主体访问 S3 的必要权限。我们的重点是在账户 A 中编写基于资源的策略。虽然在本文中,使用的是 Amazon S3 作为示例来描述具体操作方法,但该方法适用于所有支持基于资源的策略的 AWS 服务。在下面的章节中,我们将介绍在此场景中授予跨账户访问权限的四种不同方法,并讨论每种方法的利弊。

方法 1:在基于资源的策略中通过 Principal 元素指定要授予权限的 IAM 角色

全部打开

在此示例中,我们在账户 A 中创建一个 S3 存储桶的访问授权策略,并将该策略的 Principal 元素指定为账户 B 中的特定 IAM 角色 (RoleFromAccountB) 的 ARN。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowRoleInThePrincipalElement", "Principal": { "AWS": "arn:aws:iam::111122223333:role/RoleFromAccountB" }, "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-account-a/*" } ]
}

使用此存储桶访问授权策略后,如果账户 B 中的某个用户删除或重新创建了 RoleFromAccountB 角色,即使重新创建的角色具有相同的名称,也无法继续访问 amzn-s3-demo-bucket-account-a 存储桶。这是因为,保存策略时,角色 ARN 会映射到该角色的唯一 ID。角色 ID 类似:AROADBQP57FF2AEXAMPLE。如果你删除了这个基于资源的策略所引用的角色,你会在策略的 Principal 元素中看到该角色的 ID。

这是特意设计的。如果使用基于资源的策略,只会允许创建策略时通过 Principal 指定的角色实例访问该资源。这有助于防止角色删除后,但没有更新授权策略,导致你的资源被意外访问。然而,这种方式也可能影响可用性,因为重新创建角色 RoleFromAccountB 时,系统会重新为角色分配一个新的 ID,因此该角色将无法继续访问该存储桶。在多种情况下,你可能会重新创建角色,包括使用“基础设施即代码”等工具时可能意外重新创建角色。

在下列情况下,你可以选择使用此方法:
  • 你是账户 A 和账户 B 中角色的所有者,并且能够控制这些角色的创建和删除。
  • 你希望当指定的角色 (RoleFromAccountB) 被删除后,账户 A 中的相关资源访问授权策略停止授予该角色访问权限。
  • 如果该角色 (RoleFromAccountB) 被删除后,你更关注细粒度访问控制,而不是潜在的可用性问题。

方法 2:在基于资源的策略中通过 Principal 元素指定要授予访问权限的账户

全部打开

在此示例中,我们将这个基于资源的策略中的 Principal 元素指定为要授予资源访问权限的账户号。在账户 A 中创建此基于资源的策略,允许账户 B 中任何用户或角色读取该存储桶中的对象。此外,需要在账户 B 中创建一个基于身份的策略,向账户 B 中的用户或角色授予 S3 访问权限。

注意:你可以将 Principal 元素设置为 "Principal": {"AWS": "111122223333"} 或 "Principal": {"AWS": "arn:aws:iam::111122223333:root"}。这两种设置方式具有相同的作用,并且长格式的 ARN 并不代表根用户。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccountInThePrincipalElement", "Principal": { "AWS": "111122223333" }, "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-account-a/*" } ]
}

这种基于资源的策略有助于避免在我们介绍方法 1 时所提及的潜在可用性问题。如果账户 B 中需要访问这个存储桶的角色被重建了,该角色在重建后仍然可以访问这个存储桶。这是因为你在 Principal 元素中指定的不是一个角色,而是一个账户。如果使用方法 2进行授权,你必须确认将访问控制决策权委托给账户 B 的所有者不会有任何风险。

这种方法明确地将访问控制决策权交给了另一账户(账户 B),账户 B 可以通过 IAM 来管理访问控制。如果账户 B 中的基于身份的策略允许这些主体访问 S3 资源,则他们就有权访问该存储桶。

在下列情况下,你可以选择使用此方法:
  • 你需要向账户 B 中的多个主体授予访问权限。
  • 你希望将访问权限决策权委托给访问主体所在的账户(账户 B)。
  • 你更关注易管理性和可用性,而非细粒度访问控制。

方法 3:使用 aws:PrincipalArn 条件为特定 IAM 角色授予访问权限

全部打开

此方法是在方法 2 的基础上进行了扩展,增加了一个条件,即仅向特定 IAM 角色授予访问权限。与方法 2 类似,将 Principal 元素值指定为账户号,同时使用 aws:PrincipalArn 条件键来限制账号 B 中主体,只向特定主体授权。

aws:PrincipalArn 条件键是一个全局条件键,用于核验发出访问请求的主体的 ARN 和策略中指定的 ARN 是否一致。请求上下文中返回的是 IAM 角色的 ARN,而不是拥有该角色身份的用户的 ARN。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccountInPrincipalAndRoleInPrincipalArn", "Principal": { "AWS": "111122223333" }, "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-account-a/*", "Condition": { "ArnEquals": { "aws:PrincipalArn": "arn:aws:iam::111122223333:role/RoleFromAccountB" } } } ]
}

该策略与方法 2 中的策略具有同等可用性优势,即,角色在重新创建后仍具有该资源的访问权限。因为只有通过 Principal 指定角色时,才会将角色 ARN 转换为角色的唯一 ID。对于在条件中指定的角色,系统不会将角色 ARN 转换为角色的唯一 ID。如果账户 B 中的角色 (RoleFromAccountB) 被意外或故意重建,该策略仍将继续授予该角色访问权限,因为该角色与账户 A 中基于资源的策略中的条件指定的角色 ARN 相匹配。因此,方法 3 能够既能保证可用性又能保证安全性。

在下列情况下,你可以选择使用此方法:
  • 你确定需要在角色 (RoleFromAccountB)被重建的情况下,策略仍然将继续向 aws:PrincipalArn 条件键中指定的角色授予访问权限。
  • 你不是账户 B(向其授予访问权限的目标账户)的所有者,也无法控制对应的角色何时会被重建。
  • 你希望在可用性和安全性之间取得平衡。

方法 4:向指定的 AWS Organizations 组织授予访问权限

全部打开

此方法针对的用例不同于前面所提及的用例,因此这个方法不是前述三种方法的替代方案。如果你想要与整个组织共享资源(以 S3 存储桶为例),但不希望与组织外部的任何人共享资源,请使用此方法。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccessToAnEntireOrganization", "Principal": { "AWS": "*" }, "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-account-a/*", "Condition": { "StringEquals": { "aws:PrincipalOrgId": "o-12345" }, "StringNotEquals": { "aws:PrincipalAccount": "${aws:ResourceAccount}" } } } ]
}

由于无法通过基于资源的策略中的 Principal 元素来指定组织,因此必须使用 aws:PrincipalOrgId 条件键来指定允许访问资源的组织。在此策略中,将 Principal 元素值指定为一个通配符,表示任何人都可以访问该存储桶。然后,制定相应的条件将“任何人”限制为那些仅属于指定组织,且根据基于身份的策略允许访问该资源的 AWS 账户主体。

接下来,添加一个附加的条件块,用于核验 aws:PrincipalAccount 条件键指定的主体和通过策略变量 aws:ResourceAccount 条件键指定的主体是否一致。此附加条件块是可选的。使用此条件块,可以在允许策略语句中不包含存储桶的所有者账户(账户 A)。之所以使用此附加条件块,是因为账户 A 中仍然需要有一个基于身份的策略明确允许账户 A 中的主体访问此存储桶。如果不使用 aws:PrincipalAccount 进行核验比较,则账户 A 中的主体无需通过基于身份的策略明确授权即可访问存储桶。当主体和资源位于同一账户中时,策略评估逻辑仅要求通过基于身份的策略或基于资源的策略(但非同时要求两者)来明确允许访问。

在下列情况下,你可以选择使用此方法:
  • 你需要允许整个组织访问你的资源。

总结

在选择用于授予跨账户访问权限的方法时,需要仔细考虑你的需求和使用场景。本文中讨论的四种方法各有优缺点。在了解了这些方法及其影响后,你可以根据实际情况选择最合适的跨 AWS 账户资源访问授权方法。请注意,务必定期审查和审计你的基于资源的策略,以确保它们符合你的安全和访问限制要求。