Question: Why are IAM users from another AWS account getting Access Denied errors even though my bucket policy grants full access to that account?

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

Short descriptionIf your bucket policy already grants access to the other account, then 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 AWS 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.You turned on Requester Pays for the bucket.You passed a session policy that's blocking access to the bucket.

ResolutionNote: If you receive errors when running AWS Command Line Interface (AWS CLI) commands, make sure that you're using the most recent version.The user's IAM policy doesn't grant access to the bucketFor cross-account access, make sure that you grant bucket access in 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 can't access 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, look 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, then add a policy that grants the correct permissions. For example, the following IAM policy grants a user access to download objects (s3:GetObject) from DOC-EXAMPLE-BUCKET:{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "ExampleStmt",      "Action": "s3:GetObject",      "Effect": "Allow",      "Resource": [        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"      ]    }  ]}The object is encrypted by AWS KMS, and the user doesn't have access to the AWS KMS keyIf both the IAM policy (Account A) and bucket policy (Account B) grant cross-account access, then check the bucket for default encryption with AWS KMS. Or, check the object's properties for AWS KMS encryption. If an object is encrypted by an AWS KMS key, then the user must also have permissions to use the key.To grant an IAM user the permissions to download and upload to a bucket when using a KMS key for encryption, follow these steps:1.    Edit the KMS key policy to add a statement similar to the following one:Note: Enter the IAM user's Amazon Resource Name (ARN) as the Principal.{  "Sid": "ExampleStmt",  "Action": [    "kms:Decrypt",    "kms:GenerateDataKey"  ],  "Effect": "Allow",  "Principal": {    "AWS": "arn:aws:iam::111122223333:user/Jane"  },  "Resource": "*"}2.    If the KMS key belongs to the same account as the IAM user, then you don't need to update the key policy. 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 statement similar to the following one:Note: Enter the KMS key's ARN as the Resource.{  "Sid": "KMSAccess",  "Action": [    "kms:Decrypt",    "kms:GenerateDataKey"  ],  "Effect": "Allow",  "Resource": "arn:aws:kms:example-region-1:123456789098:key/111aa2bb-333c-4d44-5555-a111bb2c33dd"}A deny statement in the bucket policy or IAM policy is blocking the user's accessCheck 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 to check.3.    Choose the Permissions tab.4.    Choose Bucket policy.5.    Look 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, look 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 "Effect": "Deny" statements that incorrectly deny the user's access to the bucket.The VPC endpoint policy is blocking access to the bucketIf users access the bucket with an Amazon Elastic Compute Cloud (Amazon EC2) instance that's routed through a VPC endpoint, then 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 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": "*"    }  ]}Warning: The element "Principal": "*" grants everyone that uses the VPC endpoint access to the bucket. Make sure to restrict the scope of the Principal value as appropriate for your use case.The AWS Organizations service control policy is blocking access to the bucketIf the user's account has turned on AWS Organizations, then 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 Turning on all features in your organization.The object doesn't belong to the AWS account that owns the bucketBy 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.To resolve Access Denied errors from object ownership, try the following solutions:It's a best practice to turn off access control lists (ACLs) for your Amazon S3 buckets. To turn off ACLs, apply the bucket owner enforced setting for S3 Object Ownership. When you apply this setting, you own all the objects in your bucket and have full control over them.To enforce object ownership for new objects without turning off ACLs, apply the bucket owner preferred setting. When applying this setting, it's a best practice to update your bucket policy to require the bucket-owner-full-control canned ACL for all PUT requests to your bucket. The object owner can grant access to the bucket owner with a put-object-acl command:$ aws s3api put-object-acl --bucket examplebucket --key keyname --acl bucket-owner-full-controlNote: To access the object, the object owner must explicitly grant access to the bucket owner. Therefore, use the object owner account to run these commands.You turned on Requester Pays for the bucketIf you turned on Requester Pays for your bucket, then users from other accounts must specify the request-payer parameter when sending requests to your bucket. Otherwise, those users get an Access Denied error.To resolve this error, take the following actions:For DELETE, GET, HEAD, POST, and PUT requests, include x-amz-request-payer : requester in the header.For signed URLs, include x-amz-request-payer=requester in the request.For AWS CLI commands, include the --request-payer parameter. Example:$ aws s3 cp exampleobject.jpg s3://DOC-EXAMPLE-BUCKET/exampleobject.jpg --request-payer requesterYou passed a session policy that's blocking access to the bucketA session policy is an inline policy that you can quickly create and pass in the session during role assumption. You can pass the session policy to further scope the permissions of the role session. Session policies are advanced policies that you pass as a parameter when you programmatically create a temporary session for a role or federated user. The effective permissions of the session are the intersection of the role’s identity-based policies and the session policy. Therefore, make sure that the session policy that you passed isn't blocking access to the S3 bucket.

Related informationHow do I troubleshoot 403 Access Denied errors from Amazon S3?Why are cross-account users getting Access Denied errors when they try to access my bucket that's encrypted by a custom AWS KMS key?