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
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
Top comments (0)