Simple Storage Service (Amazon S3) バケット内のオブジェクトへのクロスアカウントアクセスを提供するにはどうすればよいですか?
最終更新日: 2022 年 8 月 3 日
別の AWS アカウントに対して、Amazon Simple Storage Service (Amazon S3) バケットに保存されているオブジェクトへのアクセス権を付与したいと考えています。Amazon S3 バケットへのクロスアカウントアクセスを提供するにはどうすればよいですか?
簡単な説明
Simple Storage Service (Amazon S3) では、別の AWS アカウント (アカウント B) のユーザーに、自分のアカウント (アカウント A) が所有するオブジェクトに対する詳細なクロスアカウントアクセスを付与できます。
提供するアクセスのタイプに応じて、以下のいずれかのソリューションを使用して、オブジェクトへのクロスアカウントアクセスを付与します。
- S3 バケットオブジェクトへのプログラムによるアクセスのみのAWS Identity and Access Management (IAM) ポリシーとリソースベースのバケットポリシー
- S3 バケットオブジェクトへのプログラムによるアクセスのみのIAM ポリシーとリソースベースのアクセスコントロールリスト
注:[Bucket owner enforced] 設定を有効にすると、すべてのバケットとオブジェクトの ACL が無効になります。したがって、ACL を使用してクロスアカウントアクセスを付与することはできません。デフォルトでは、新しく作成されたすべてのバケットでは、[Bucket owner enforced] 設定が有効になっています。また、(ACL ではなく) IAM ポリシーとバケットポリシーを使用して、バケットとオブジェクトへのクロスアカウントアクセスを管理することもベストプラクティスです。詳しくは、オブジェクトの所有権を制御し、バケットの ACL を無効にするを参照してください。 - S3 バケットオブジェクトへのプログラムによるアクセスとコンソールアクセスのためのクロスアカウント IAM ロール
リクエスタが IAM プリンシパルの場合、そのプリンシパルを所有する AWS アカウントは IAM ポリシーを通じて S3 アクセス権限を付与する必要があります。特定のユースケースに基づいて、バケット所有者もバケットポリシーまたは ACL を通じてアクセス許可を付与する必要があります。アクセスが許可された後、クロスアカウントのバケットへのプログラムによるアクセスは、そのアカウントバケットにアクセスすることと同じです。
解決方法
IAM ポリシーとリソースベースのバケットポリシー
注: AWS Command Line Interface (AWS CLI) コマンドの実行中にエラーが発生した場合は、最新のバージョンの AWS CLI を使用していることを確認してください。
リソースベースのバケットポリシーを使用して、クロスアカウントアクセスコントロールを管理し、S3 オブジェクトのアクセス権限を監査します。バケットレベルでバケットポリシーを適用すると、次のような定義が可能です。
- バケット内のオブジェクトにアクセスできるのは誰ですか (Principal 要素を使用)
- どのオブジェクトにアクセスできるか (Resource 要素を使用)
- バケット内のオブジェクトにアクセスする方法 (Action 要素を使用)
バケットポリシーをバケットレベルで適用すると、複数のポリシーを使用してアクセスを制御することで、バケット内のさまざまなオブジェクトへの詳細なアクセスを定義できます。バケットポリシーを確認して、S3 バケット内のオブジェクトにアクセスできるユーザーを確認することもできます。
バケットポリシーを使用して S3 バケットへのアクセスを管理するには、以下のステップに従います。
注: Account 変数をアカウントに置き換えてください。
1. アカウント A で S3 バケットを作成します。
2. アカウント B で IAM ロールまたはユーザーを作成します。
3. アカウント B の IAM ロールに、特定のバケットに対してオブジェクトのダウンロード (GET Object) およびアップロード (PUT Object) を行うアクセス権限を付与します。次の IAM ポリシーを使用して、アカウント B の IAM ロールに PutObjectAcl を呼び出すアクセス許可を付与し、バケット所有者にオブジェクトのアクセス許可を付与します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::AccountABucketName/*"
}
]
}
注:ユーザー変数 (アカウント ID、バケット名、ARN など) を含めるようにポリシーを更新してください。また、アカウント A の特定のバケットフォルダへのアクセスを制限できます。特定のバケットフォルダへのアクセスを制限するには、「arn:aws:s3:::AccountABucketName/FolderName/*」のように、resource 要素にフォルダ名を定義します。詳細については、IAM ポリシーを使用して特定のフォルダへのユーザー固有のアクセスを許可するにはどうしたらよいですか? を参照してください。
AWS CLI コマンド例の create-policy を使用して、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/*"
]
}
]
}
AWS CLI コマンド例の put-bucket-policy を使用して、Simple Storage Service (Amazon S3) バケットポリシーを作成することもできます。
注: 「Resource」: 「arn:aws:s3:::AccountABucketName/FolderName/*」など、リソース要素で特定の S3 バケットフォルダを定義して、より制限されたアクセスを許可できます。条件を指定して s3:PutObject アクセス許可を使用することで、バケット所有者は他のアカウントによってアップロードされたオブジェクトを完全に制御できます。その後、特定のヘッダーで ACL を適用すると、PutObject API 呼び出し内で渡されます。詳細については、バケット所有者にフルコントロールを与えることを条件として s3:PutObject のアクセス許可を付与するを参照してください。
IAM ポリシーとリソースベースの ACL
ACL が IAM や S3 バケットのポリシーよりも適切にニーズを満たす場合は、オブジェクト ACL を使って特定のシナリオでのアクセス許可を管理します。詳細については、ACL ベースのアクセスポリシー (バケットおよびオブジェクト ACL) の使用が適する場合を参照してください。Amazon S3 ACL では、READ、WRITE、READ_ACP、WRITE_ACP、および FULL_CONTROL のアクセス権限セットのみを定義できます。Amazon S3 ACL のアクセス許可を与えられるユーザーは、AWS アカウントまたは事前定義された Amazon S3 グループのうちから 1 つのみを使用できます。AWS アカウントの E メールアドレスまたは正規ユーザー ID を指定する場合、ACL はアクセス許可を与えられるユーザーの AWS アカウントにあるすべてのエンティティに適用されます。例えば、ACL を使用して、個々の IAM ユーザーまたはロールへのアクセスを制限することはできません。また、同じプレフィックスを共有する異なるオブジェクトに ACL を適用することはできません。
注意: バケット所有者は、ACL アクセス許可を与えられるユーザーがアップロードしたオブジェクトを完全に制御できない場合があります。これは、ACL が承認する S3 オペレーションの条件を ACL がサポートしていないことに起因します。
バケットとオブジェクト ACL を使用して S3 バケットへのアクセスを管理するには、以下の手順通りに実行します。
1. アカウント B で IAM ロールまたはユーザーを作成します。次に、必要な Amazon S3 オペレーションを実行するアクセス許可をそのロールまたはユーザーに付与します。PutObject と GetObject を呼び出すユーザーには、リソースベースのポリシーと IAM ポリシーセクションにリストされているアクセス許可が必要です。
2. 少なくともアカウント B の WRITE アクセス権限を含めるようにバケット ACL を設定します。これにより、アカウント B の IAM ロールまたはユーザーは、アカウント A が所有するバケットにオブジェクトをアップロード (PutObject 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> WRITE </Permission>
</Grant>
...
</AccessControlList>
</AccessControlPolicy>
注: CanonicalUserID を確認するには、「AWS アカウントの正規ユーザー ID を知る方法」をご参照ください。
3. 少なくともアカウント B の READ アクセス許可を含めるようにオブジェクト ACL を設定します。これにより、アカウント 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 を変更する必要があります。詳細については、「Simple Storage Service (Amazon S3) がオブジェクトオペレーションのリクエストを許可する方法」をご参照ください。
クロスアカウント IAM ロールを使用して S3 バケットへのアクセスを管理するには、以下のステップに従います。
1. アカウント A で IAM ロールを作成します。次に、必要な S3 オペレーションを実行するアクセス許可をロールに付与します。ロールの信頼ポリシーで、アカウント B のロールまたはユーザーに、アカウント A のロールを引き受けるアクセス権限を付与します。
注: IAM ロールには、ロールを引き受けることができるプリンシパルと条件を定義する信頼ポリシーが必要です。IAM ロールは、ロールを引き受けるプリンシパルが実行できるアクセス権限と、どのリソースに対して実行できるかを定義する複数のアクセス権限ポリシー (インラインおよびアタッチ) を持つことができます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AccountB:user/AccountBUserName"
},
"Action": "sts:AssumeRole"
}
]
}
AWS CLI コマンド例の create-role を使用して、信頼ポリシーを使用してロールを作成することもできます。
次のアクセスポリシーでは、このロールを引き受けたユーザーが、プログラムで Simple Storage Service (Amazon S3) コンソールを使用してオブジェクトのダウンロードとアップロードを許可します。詳細については、IAM ポリシーを使用して特定のフォルダへのユーザー固有のアクセスを許可するにはどうしたらよいですか? を参照してください。
注: プログラムによるアクセスのみが必要な場合は、次のポリシーのステートメントから最初の 2 つを削除できます。
{
"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/*"
}
]
}
AWS CLI コマンド例の create-policy を使用して、IAM アイデンティティベースのポリシーを作成することもできます。
2. アカウント B の IAM ロールまたはユーザーに、アカウント A で作成した IAM ロールを引き受けるアクセス権限を付与します。
注: 次のサンプルポリシーは、IAM ユーザーまたはロールのアクセス権限ポリシーとして追加する必要があります。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::AccountA:role/AccountARole"
}
}
AWS CLI コマンド例の create-policy を使用して、IAM アイデンティティベースのポリシーを作成することもできます。
3. アカウント B のロールから、アカウント A のロールをプログラムで引き受けることで、アカウント B の IAM エンティティが必要な S3 オペレーションを実行できるようにします。詳細については、ロールの切り替え (コンソール) を参照してください。
注意: アカウント A の IAM ロールを引き受けると、Amazon S3 オペレーションはアクセスポリシーによって決まります。IAM ロールは、アカウント A のローカル IAM エンティティによって行われた API 呼び出しと見なされます。クロスアカウントアクセス用のバケットポリシーまたは ACL は必要ありません。詳細については、Amazon S3 アクションをご参照ください。