私のバケットポリシーは、別の AWS アカウントへのフルアクセスを許可します。そのアカウントの IAM ユーザーにまだアクセス拒否エラーが表示されるのはなぜですか?

最終更新日: 2020 年 11 月 5 日

私の Amazon Simple Storage Service (Amazon S3) バケットのポリシーは、別の AWS アカウントへのフルアクセスを許可します。しかし、そのアカウントの AWS Identity and Access Management (IAM) ユーザーが私のバケットにアクセスしようとすると、アクセス拒否エラーが発生します。どうすれば解決できますか?

簡単な説明

バケットポリシーでもう一方のアカウントへのアクセスがすでに許可されている場合、クロスアカウントユーザーは次の理由でアクセス拒否エラーを受け取る可能性があります。

  • ユーザーの IAM ポリシーがバケットへのアクセスを許可していない。
  • オブジェクトが AWS Key Management Service (AWS KMS) によって暗号化されており、ユーザーは KMS キーにアクセスできない。
  • バケットポリシーまたは IAM ポリシーの拒否ステートメントがユーザーのアクセスをブロックしている。
  • Amazon Virtual Private Cloud (Amazon VPC) エンドポイントポリシーがバケットへのアクセスをブロックしている。
  • AWS Organizations サービスコントロールポリシーがバケットへのアクセスをブロックしている。
  • オブジェクトがバケットを所有する AWS アカウントに属していない。
  • バケットでリクエスタ支払いが有効になっている。

解決方法

ユーザーの IAM ポリシーがバケットへのアクセスを許可していない

クロスアカウントアクセスでは、アカウント A の IAM ポリシーとアカウント B のバケットポリシーの両方でユーザーにバケットアクセスを許可する必要があります。

アカウント A でユーザーの IAM ポリシーを確認するには、次の手順に従ってください。

1.    IAM コンソールを開きます。

2.    コンソールから、バケットにアクセスする必要がある IAM ユーザーまたはロールを開きます。

3.    IAM ユーザーまたはロールの [Permissions] (アクセス許可) タブで各ポリシーを展開し、その JSON ポリシードキュメントを表示します。

4.    JSON ポリシー文書で、バケット名を持つポリシーを探します。次に、そのポリシーがバケットに対する正しい S3 アクションを許可することを確認します。

5.    IAM ユーザーまたはロールがバケットへのアクセスを許可していない場合は、正しいアクセス許可を付与するポリシーを追加してください。たとえば、次の IAM ポリシーは、DOC-EXAMPLE-BUCKET からオブジェクト (s3:GetObject) をダウンロードするためのアクセス権限をユーザーに付与します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ExampleStmt",
      "Action": "s3:GetObject",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ]
    }
  ]
}

オブジェクトが AWS KMS によって暗号化されており、ユーザーは KMS キーにアクセスできない

アカウント A の IAM ポリシーとアカウント B のバケットポリシーの両方がクロスアカウントアクセスを許可する場合は、AWS KMS によるデフォルトの暗号化についてバケットをチェックします。または、AWS KMS 暗号化のオブジェクトのプロパティを確認します。オブジェクトが AWS KMS キーで暗号化されている場合、ユーザーはそのキーを使用するためのアクセス許可も必要です。

暗号化に KMS キーを使用しているときに、バケットにダウンロードしてアップロードするアクセス許可を IAM ユーザーに付与するには、次の手順に従います。

1.    KMS キーポリシーを編集して、次のようなステートメントを追加します。

注: IAM ユーザーの Amazon リソースネーム (ARN) を Principal として入力してください。

{
   "Sid": "Allow use of the key",
   "Effect": "Allow",
   "Principal": {
     "AWS": [
       "arn:aws:iam::111122223333:user/Jane",
     ]
   },
   "Action": [
     "kms:Encrypt",
     "kms:Decrypt",
     "kms:ReEncrypt*",
     "kms:GenerateDataKey*",
     "kms:DescribeKey"
   ],
   "Resource": "*"
 }

2.    KMS キーが IAM ユーザーと同じアカウントに属している場合、キーポリシー内のステートメントはユーザーにキーへのアクセスを許可するのに十分です。KMS キーが IAM ユーザーとは異なるアカウントに属している場合は、IAM ユーザーのアクセス許可を更新する必要があります。次のような IAM ポリシーを追加します。

注: KMS キーの ARN をリソースとして入力してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ExampleStmt3",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:GenerateDataKey",
                "kms:ReEncrypt*"
            ],
            "Resource": "arn:aws:kms:example-region-1:123456789098:key/a1b2c3d4-e5f6-7890-g1h2-123456789abc"
        }
    ]
}

バケットポリシーまたは IAM ポリシーの拒否ステートメントがユーザーのアクセスをブロックしている

ユーザーのバケットへのアクセスを明示的に拒否するステートメントがないか、バケットポリシーとユーザーの IAM ポリシーの両方を確認してください。

バケットポリシーを確認するには、次の手順を実行してください。

1.    Amazon S3 コンソールを開きます。

2.    バケットのリストから、確認したいバケットポリシーを持つバケットを開きます。

3.    [ ] タブを選択します。

4.    [Bucket Policy] を選択します。

5.    "Effect": "Deny" のあるステートメントを探します。

6.    バケットポリシーを変更して、ユーザーのバケットへのアクセスを拒否している "Effect": "Deny" ステートメントを編集または削除します。

ユーザーの IAM ポリシーを確認するには、次の手順に従ってください。

1.    IAM コンソールを開きます。

2.    コンソールから、バケットにアクセスできない IAM ユーザーまたはロールを開きます。

3.    IAM ユーザーまたはロールの [Permissions] (アクセス許可) タブで、各ポリシーを展開して JSON ポリシードキュメントを表示します。

4.    JSON ポリシー文書で、"Effect": "Deny" を含むステートメントで S3 バケットに関連するポリシーを探します。

5.    ユーザーの IAM アクセス許可ポリシーを変更して、ユーザーのバケットへのアクセスを誤って拒否している "Effect": "Deny" ステートメントを編集または削除します。

VPC エンドポイントポリシーがバケットへのアクセスをブロックしている

ユーザーが VPC エンドポイントを通じてルーティングされた Amazon Elastic Compute Cloud (Amazon EC2) インスタンスでバケットにアクセスする場合は、VPC エンドポイントポリシーを確認してください。VPC エンドポイントポリシーに S3 バケットにアクセスするための正しいアクセス許可が含まれていることを確認してください。

たとえば、次の VPC エンドポイントポリシーは、DOC-EXAMPLE-BUCKET へのアクセスを許可しています。

{
  "Id": "Policy1234567890123",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1234567890123",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ],
      "Principal": "*"
    }
  ]
}

警告: エレメント "Principal": "*" は、VPC エンドポイントを使用するすべてのユーザーにバケットへのアクセスを許可します。使用するユースケースに応じて、Principal 値をスコープダウンしてください。 

AWS Organizations サービスコントロールポリシーがバケットへのアクセスをブロックしている

ユーザーのアカウントで AWS Organizations が有効になっている場合は、サービスコントロールポリシーを調べて、Amazon S3 へのアクセスが許可されていることを確認してください。たとえば、次のポリシーは、Amazon S3 へのアクセスを明示的に拒否して、アクセス拒否エラーが表示されます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "s3:*",
            "Resource": "*"
        }
    ]
}

AWS Organizations の機能の詳細については、組織内のすべての機能の有効化を参照してください。

オブジェクトはバケットを所有する AWS アカウントに属していない

デフォルトでは、S3 オブジェクトの所有者はそれをアップロードした AWS アカウントになります。これは、バケット所有者が別のアカウントである場合にも当てはまります。オブジェクトの所有者が別のアカウントである場合、バケットのアクセス許可は自動的にオブジェクトに適用されません。これは、別のアカウントのバケットに送信されたサービスログで発生する可能性があります。サービスログの例には、AWS CloudTrail ログAmazon Virtual Private Cloud (Amazon VPC) フローログが含まれます。

オブジェクトの所有権によるアクセス拒否エラーを解決するには、以下の手順に従います。

1.    オブジェクト所有者は、バケット所有者にオブジェクトのフルコントロールを明示的に付与する必要があります。

2.    次に、所有権の変更を適用するには、バケット所有者がオブジェクトをそれ自体にコピーする必要があります。これを行うには、バケット所有者は、以下のように、AWS コマンドラインインターフェイス (AWS CLI) を使用して cp コマンドを実行できます。

aws s3 cp s3://DOC-EXAMPLE-BUCKET/awsexampleobject  s3://DOC-EXAMPLE-BUCKET/awsexampleobject  --metadata-directive REPLACE

注: AWS CLI コマンドの実行時にエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください

バケット所有者がオブジェクトをそれ自体にコピーすると、そのオブジェクトはバケット所有者のアカウントに属します。 

バケットで有効化されているリクエスタ支払い

バケットでリクエスタ支払いが有効化されているのであれば、他のアカウントのユーザーは自分のバケットにリクエストを送信するとき、request-payer パラメータを指定する必要があります。それ以外の場合は、それらのユーザーには、アクセス拒否エラーが表示されます。

GET、HEAD、または POST リクエストの場合、ユーザーはヘッダーに x-amz-request-payer パラメータを含める必要があります。REST リクエストの場合、ユーザーはリクエストに x-amz-request-payer パラメータを含める必要があります。

AWS CLI コマンドの場合、ユーザーは次のように --request-payer パラメータを含める必要があります。

aws s3 cp exampleobject.jpg s3://DOC-EXAMPLE-BUCKET/exampleobject.jpg --request-payer requester