My bucket policy grants full access to another AWS account. Why are IAM users from that account still getting Access Denied errors?

Last updated: 2019-07-08

The policy of my Amazon Simple Storage Service (Amazon S3) bucket grants full access to another AWS account. But when AWS Identity and Access Management (IAM) users from that account try to access my bucket, they get an Access Denied error. How can I fix this? 

Short Description

If your bucket policy already grants access to the other account, cross-account users can get Access Denied errors for these reasons:

  • The user's IAM policy doesn't grant access to the bucket.
  • The object is encrypted by AWS Key Management Service (AWS KMS), and the user doesn't have access to the KMS key.
  • A deny statement in the bucket policy or IAM policy is blocking the user's access.
  • The Amazon Virtual Private Cloud (Amazon VPC) endpoint policy is blocking access to the bucket.
  • The AWS Organizations service control policy is blocking access to the bucket.
  • The object doesn't belong to the AWS account that owns the bucket.
  • Requester Pays enabled on bucket.

Resolution

The user's IAM policy doesn't grant access to the bucket

For cross-account access, the user must be granted bucket access in both the IAM policy in Account A and the bucket policy in Account B.

Follow these steps to check the user's IAM policy in Account A:

1.    Open the IAM console.

2.    From the console, open the IAM user or role that should have access to the bucket.

3.    In the Permissions tab of the IAM user or role, expand each policy to view its JSON policy document.

4.    In the JSON policy documents, search for policies with the bucket's name. Then, confirm that those policies allow the correct S3 actions on the bucket.

5.    If the IAM user or role doesn't grant access to the bucket, add a policy that grants the correct permissions. For example, the following IAM policy grants a user access to all S3 actions on awsexamplebucket:

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

The object is encrypted by AWS KMS, and the user doesn't have access to the KMS key

If both the IAM policy in Account A and the bucket policy in Account B grant cross-account access, then check the object's properties for encryption. If an object is encrypted by an AWS KMS key, then the user also needs permissions to use the key.

Follow these steps to grant the IAM user permissions to the KMS key:

1.    Edit the KMS key policy to add a statement similar to the following:

Note: Enter the IAM user's Amazon Resource Name (ARN) as the 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.    If the KMS key belongs to the same account as the IAM user, then the statement in the key policy is enough to grant the user access to the key. If the KMS key belongs to a different account than the IAM user, then you must also update the IAM user's permissions. Add an IAM policy similar to the following:

Note: Enter the KMS key's ARN as the Resource.

{
    "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"
        }
    ]
}

A deny statement in the bucket policy or IAM policy is blocking the user's access

Check both the bucket policy and the user's IAM policies for any statements that explicitly deny the user's access to the bucket.

Follow these steps to check the bucket policy:

1.    Open the Amazon S3 console.

2.    From the list of buckets, open the bucket with the bucket policy that you want check.

3.    Choose the Permissions tab.

4.    Choose Bucket policy.

5.    Search for statements with "Effect": "Deny".

6.    Modify the bucket policy to edit or remove any "Effect": "Deny" statements that are denying the user's access to the bucket.

Follow these steps to check the user's IAM policies:

1.    Open the IAM console.

2.    From the console, open the IAM user or role that can't access the bucket.

3.    In the Permissions tab of the IAM user or role, expand each policy to view the JSON policy documents.

4.    In the JSON policy documents, search for policies related to the S3 bucket with statements that contain "Effect": "Deny".

5.    Modify the user's IAM permissions policies to edit or remove any "Effect": "Deny" statements that are incorrectly denying the user's access to the bucket.

The VPC endpoint policy is blocking access to the bucket

If users access the bucket with an Amazon Elastic Compute Cloud (Amazon EC2) instance routed through a VPC endpoint, check the VPC endpoint policy. Confirm that the VPC endpoint policy includes the correct permissions to access the S3 bucket.

For example, the following VPC endpoint policy allows access to awsexamplebucket:

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

The AWS Organizations service control policy is blocking access to the bucket

If the user's account has AWS Organizations enabled, check the service control policies to be sure that access to Amazon S3 is allowed. For example, the following policy explicitly denies access to Amazon S3 and results in an Access Denied error.

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

For more information on the features of AWS Organizations, see Enabling All Features in Your Organization.

The object doesn't belong to the AWS account that owns the bucket

By default, an S3 object is owned by the AWS account that uploaded it. This is true even when the bucket is owned by another account. The bucket's permissions don't automatically apply to an object when the object is owned by a different account. This can happen with service logs that are sent to a bucket in another account. Examples of service logs include AWS CloudTrail logs or Amazon Virtual Private Cloud (Amazon VPC) flow logs.

To resolve Access Denied errors from object ownership, the object owner must explicitly grant ownership to the bucket owner. For instructions, see Why can't I access an object that was uploaded to my Amazon S3 bucket by another AWS account?

Requester Pays enabled on bucket

If your bucket has Requester Pays enabled, then users from other accounts must specify the request-payer parameter when they send requests to your bucket. Otherwise, those users get an Access Denied error.

For GET, HEAD, or POST requests, the user must include the x-amz-request-payer parameter in the header. For REST requests, the user must include the x-amz-request-payer parameter in the request.

For AWS Command Line Interface (AWS CLI) commands, the user must include the --request-payer parameter, similar to the following:

aws s3 cp exampleobject.jpg s3://awsexamplebucket/exampleobject.jpg --request-payer requester