DEV Community

Alan RodrΓ­guez
Alan RodrΓ­guez

Posted on

Cross Account Access to S3 Buckets in AWS

There may be cases when you want to read/write to an S3 bucket in a different AWS account, this is something that you can easily achieve by adding some tweaks to the S3 bucket policies and updating a user policy.

Scenario

Cross-account access overview

Let's think of a possible scenario, we will assume that we have two AWS Accounts, AWS account A and AWS account B.

You already have an access key in account A and want to write files to one or multiple S3 buckets in account B, you prefer to keep using the same access key that is used to write to multiple accounts instead of creating a new access key in account B, since that might complicate our code and make key rotations more complicated.

There may be more reasons why you want to do this, but the bottom line is to be able to access buckets in multiple AWS Accounts with a single user/access key.

Prerequisites

  • Have more than one AWS Account
  • Permission to update bucket policies in account A
  • Permission to update user policies in account B
  • ARN of user in account B, you can find it by calling aws sts get-caller-identity in the CLI

Getting Started

As an example, we will give read and write permissions for an S3 bucket in account A to a user in account B.

Attach bucket policy to account A bucket granting access to account B

The first step is to attach a bucket policy to the bucket we want to access, you can add the policy in the permissions section of the bucket, bucket name > permissions > bucket policy:

Add the following policy, fill {ACCOUNT_B_USER_ARN} with your user ARN and feel free to set the Action to the actions you want to allow.

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Sid": "Read and Write Account Permissions",
         "Effect": "Allow",
         "Principal": {
            "AWS": "{ACCOUNT_B_USER_ARN}"
         },
         "Action": [
            "s3:PutObjectAcl",
            "s3:PutObject",
            "s3:List*",
            "s3:Get*"
         ],
         "Resource": [
            "arn:aws:s3:::account_a_bucket"
         ]
      }
   ]
}

With this policy we're letting the bucket know that a new user will have the given permissions. In our case add, get and list objects to account_a_bucket.

Now we test our new permissions, you can try to list objects using the console:

aws s3 ls s3://account_a_bucket --profile AccountBUser

You should get an AccessDenied error. This is fine, it means that we still need to give permissions to Account B User through a policy.

Add policy to account B user

To access account_a_bucket, we attach a policy in account B to the account B user

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:PutObjectAcl",
                "s3:PutObject",
                "s3:List*",
                "s3:Get*"
            ],
            "Resource": [
                "arn:aws:s3:::account_a_bucket/*",
                "arn:aws:s3:::account_a_bucket"
            ]
        }
    ]
}

Save and test again, you should now have access to account_a_bucket

aws s3 ls s3://account_a_bucket --profile AccountBUser

Best practices

In the previous example, we gave permissions from the bucket policy directly to a user, but it's a better practice to give permissions in the bucket policy to root in the account B, that way the root user can delegate the required access to users in its account using policies and no changes are required in account A

Overview with root granting access

Additional Documentation

AWS: Bucket Owner Granting Cross-Account Bucket Permissions

Top comments (0)