如何提供对 Amazon S3 存储桶中的对象的跨账户访问权限?

上次更新时间:2020 年 9 月 3 日

我想授权其他 AWS 账户访问 Amazon Simple Storage Service (Amazon S3) 存储桶中存储的对象。如何提供对 Amazon S3 存储桶的跨账户访问权限?

简短描述

您可以使用下面的任意一种方法,授予对 S3 存储桶中存储对象的跨账户访问权限:

  • 使用基于资源的策略和 AWS Identity and Access Management (IAM) 策略,仅以编程方式访问 S3 存储桶对象
  • 使用基于资源的访问控制列表 (ACL) 和 IAM 策略,仅以编程方式访问 S3 存储桶对象
  • 使用跨账户 IAM 角色,以编程方式和通过控制台访问 S3 存储桶对象

根据您要提供的访问类型使用以下一种解决方法,从而授予对 S3 存储桶中存储对象的精细跨账户访问权限。在下面的示例中,您将向另一个 AWS 账户(账户 B)中的用户授予访问权限,从而允许这些用户管理您的账户(账户 A)拥有的 S3 存储桶中的对象。

注意:请务必更新策略以包含您的账户 ID、存储桶名称、ARN 等信息。

解决方法

基于资源的策略和 IAM 策略

使用存储桶策略来管理跨账户控制并审计 S3 对象的权限。如果您在存储桶级别应用存储桶策略,则可以定义拥有访问权限的人(委托人元素)、他们可以访问的对象(资源元素)以及他们访问对象的方式(操作元素)。如果您在存储桶级别应用存储桶策略,将可以为存储桶中的不同对象定义精细访问权限。您还可以检查存储桶策略,以了解谁有权访问 S3 存储桶中的对象。要使用存储桶策略来管理对 S3 存储桶的访问,请遵循以下步骤:

1.    在账户 A 中创建一个 Amazon S3 存储桶

2.    在账户 B 中创建一个 IAM 角色或用户

3.    使用此 IAM 策略向账户 B 中的 IAM 角色或用户授予从特定 S3 存储桶下载 (GET Object) 对象以及向该存储桶上传 (PUT Object) 对象的权限。此策略还将向账户 B 中的 IAM 角色或用户授予调用 (PUT Object acl) 的权限,以向存储桶拥有者授予对象权限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
  "s3:PutObject",
  "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::AccountABucketName/*"

        }
    ]
}

注意:您可以定义资源元素中的文件夹名称,从而限制对账户 A 中特定存储桶文件夹的访问权限,例如“arn:aws:s3:::AccountABucketName/FolderName/*”。有关更多信息,请参阅如何使用 IAM 策略向特定用户授予对特定文件夹的访问权限?

4.    配置账户 A 的存储桶策略以向您在账户 B 中创建的 IAM 角色或用户授予权限。使用此存储桶策略向用户授予对账户 A 所拥有存储桶中的对象的 GetObject 和 PutObject 权限:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::AccountB:user/AccountBUserName"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::AccountABucketName/*"
            ]
        }
    ]
}

注意:您可以通过定义资源元素中的特定 S3 文件夹来提供精细访问权限,从而进一步限制访问权限,例如“arn:aws:s3:::AccountABucketName/FolderName/*”。通过使用附条件的 s3:PutObject 权限,存储桶拥有者将能够完全控制其他账户上传的对象。然后执行 ACL,从而在 PutObject API 调用中传递特定的标头。有关更多信息,请参阅授予 s3:PutObject 权限,并指定一个条件以要求存储桶拥有者获得完全控制权

基于资源的访问控制列表 (ACL) 和 IAM 策略

使用对象 ACL 来管理权限,这种方法仅针对特定的情形,并且仅在 ACL 比 IAM 和 S3 存储桶策略更能满足您的需求时使用。有关更多信息,请参阅何时使用基于 ACL 的访问策略(存储桶和对象 ACL)。Amazon S3 ACL 仅允许用户定义以下权限集:READ、WRITE、READ_ACP、WRITE_ACP 和 FULL_CONTROL。您仅可以将 AWS 账户或某个预定义的 Amazon S3 组作为 Amazon S3 ACL 的被授权者。指定某个 AWS 账户的电子邮件地址或规范用户 ID 时,ACL 将适用于被授权 AWS 账户中的所有实体。您不能使用 ACL 将访问权限限定为个别 IAM 用户或角色。您不能将 ACL 应用到具有相同前缀的不同对象。

注意:存储桶拥有者可能不会拥有 ACL 被授权者上传的对象的完全控制权限。这是因为 ACL 不支持 ACL 授权的 S3 操作的条件。

要使用存储桶和对象 ACL 来管理对 S3 存储桶的访问,请遵循以下步骤:

1.    在账户 B 中创建一个 IAM 角色或用户。然后向该该角色或用户授予执行所需 Amazon S3 操作的权限。调用 PutObject 和 GetObject 的用户需要具有基于资源的策略和 IAM 策略部分中列出的权限。

2.    配置存储桶 ACL 以至少包含账户 B 的 WRITE 权限。这可确保账户 B 的 IAM 角色或用户可以将对象上传(调用 PutObject API)到账户 A 拥有的存储桶:

...
<AccessControlPolicy>
  <Owner>
    <ID> AccountACanonicalUserID </ID>
    <DisplayName> AccountADisplayName </DisplayName>
  </Owner>
  <AccessControlList>
...
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
        <ID> AccountBCanonicalUserID </ID>
        <DisplayName> AccountBDisplayName </DisplayName>
      </Grantee>
      <Permission> WRITE </Permission>
    </Grant>
    ...
  </AccessControlList>
</AccessControlPolicy>

注意:要查找您规范用户 ID,请参阅查找 AWS 账户的规范用户 ID

3.    配置对象 ACL 以至少包含账户 B 的 READ 权限。这将确保账户 B 中的 IAM 角色或用户能够从账户 A 拥有的存储桶下载对象(调用 GetObject API):

...
<AccessControlPolicy>
  <Owner>
    <ID> AccountACanonicalUserID </ID>
    <DisplayName> AccountADisplayName </DisplayName>
  </Owner>
  <AccessControlList>
...
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
        <ID> AccountBCanonicalUserID </ID>
        <DisplayName> AccountBDisplayName </DisplayName>
      </Grantee>
      <Permission> READ </Permission>
    </Grant>
    ...
  </AccessControlList>
</AccessControlPolicy>

ACL 权限因将应用 ACL 的 S3 资源、存储桶或对象而异。有关更多信息,请参阅访问控制列表 (ACL) 概述。您可以在创建存储桶时配置存储桶和对象 ACL,也可以在向现有存储桶上传对象时进行配置。要了解更多信息,请参阅管理 ACL

跨账户 IAM 角色

并非所有 AWS 服务都支持基于资源的策略。这意味着您可以在向多个服务提供跨账户访问权限时,使用跨账户 IAM 角色来集中管理权限。使用跨账户 IAM 角色可以简化预置过程,轻松实现对多个 S3 存储桶中存储的 S3 对象的跨账户访问,无需为 S3 存储桶管理多个策略。此方法允许跨账户访问由其他 AWS 账户或 AWS 服务拥有或上传的对象。如果您不使用跨账户 IAM 角色,则必须修改对象 ACL。有关更多信息,请参阅 Amazon S3 如何授权对象操作的请求

要使用跨账户 IAM 角色来管理对 S3 存储桶的访问,请遵循以下步骤:

1.    在账户 A 中创建一个 IAM 角色。然后,向该角色授予执行所需 S3 操作的权限。在角色的信任策略中,向账户 B 中的某个角色或用户授予中代入账户 A 中角色的权限:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::AccountB:user/AccountBUserName"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

下面的访问策略允许代入该角色的用户通过编程方式以及 Amazon S3 控制台下载和上传对象。有关更多信息,请参阅如何使用 IAM 策略向特定用户授予对特定文件夹的访问权限?

注意:如果只需要编程访问,可以移除上述策略中的前两个语句:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::*"
            ]
        },
        {
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::AccountABucketName"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::AccountABucketName/*"
        }
    ]
}

2.    向账户 B 中的 IAM 角色或用户授予代入您在账户 A 中创建的 IAM 角色的权限。

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::AccountA:role/AccountARole"
  }
}

3.    从账户 B 中的角色或用户代入账户 A 中的角色,以便账户 B 中的 IAM 实体可以执行所需的 S3 操作。有关更多信息,请参阅切换到角色(控制台)

注意:通过代入账户 A 中的 IAM 角色,访问策略将会确定 Amazon S3 操作。该 IAM 角色将被视为账户 A 中的本地 IAM 实体发起的一次 API 调用。跨账户访问无需存储桶策略或 ACL。有关更多信息,请参阅 Amazon S3 操作