Understanding Cross-Account AWS S3 Bucket Permissions

When you first create an S3 bucket in your AWS account, public access is disabled by default. Even instances inside of your account cannot access the S3 bucket unless they have the appropriate role associated with them (this role would need to have S3 permissions).

Creating a role with S3 permissions and assigning it to an instance in your AWS account is simple enough, but what if you want to share the bucket with another AWS account without making it public?

An easy way to do this is to go into the Permissions tab of your S3 bucket and then click on the Bucket Policy button to bring up the bucket policy editor. Once there, you could assign a policy such as the following:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Example permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:root"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my-test-bucket",
                "arn:aws:s3:::my-test-bucket/*"
            ]
        }
    ]
}

The above policy is granting AWS acccount 111122223333 all S3 permissions on the bucket my-test-bucket.

Please note that 111122223333 from the above snippet is just an example AWS account ID. You can find the account ID for your account (in this case, it would be the ID of the account you are trying to grant permission to) by simply navigating to the top right corner of the AWS console, clicking on your account name, and going to My Account.

Keep in mind that, for simplicity, The Action section in the above bucket policy is set as follows:

            "Action": "s3:*"

This statement is allowing all actions on the S3 bucket. This can be edited/restricted to just list, get, etc. For more information, you can see the AWS docs.

Keep in mind that you must assign the permission to the bucket as well as the objects inside of the bucket, hence the following:

            "Resource": [
                "arn:aws:s3:::my-test-bucket",
                "arn:aws:s3:::my-test-bucket/*"

Finally, remember that just because you have granted S3 permissions to another account doesn't mean any instance in that account can interact with your S3 bucket. The instances in that account must still be assigned an appropriate role with S3 permissions to pull or push data to your bucket.