You can have one AWS account see the contents of the S3 bucket of another entirely separate account if you configure it correct. Note that S3 buckets are unique across the whole AWS estate, irrespective of who owns it. This was for historical reasons, it seems.
Anyway, to have account Emrys (say) read the bucket of account Odin (say), run the commands below.
Note, that all of this can be run from the same command line if you have Emrys as your [default] account and [odin] as Odin's in ~/.aws/config and credentials. You'll need source_profile = odin in config to point to the correct credentials.
First, we say create a role in Odin that Emrys will assume:
aws iam create-role --role-name S3ReadWriteRoleEmrys --assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::EMRYS_ID:root"
} ,
"Action": "sts:AssumeRole"
}
]
}' --profile odin
Then we create a policy and attach it to the role.
aws iam create-policy --policy-name ReadOdinS3IAMPolicy --policy-document file://emrys-policy.json --profile odin
aws iam attach-role-policy --role-name S3ReadWriteRoleEmrys --policy-arn arn:aws:iam::ODIN_ID:policy/ReadOdinS3IAMPolicy --profile odin
Note that emrys-policy.json is just a collection of s3 Actions that act on a Resource that is Odin's bucket - nothing special.
Then in the Emrys real estate, we
aws iam create-policy \
--policy-name AssumeOdinRole \
--policy-document file://assume-account-odin-role.json
aws iam attach-user-policy \
--user-name MY_USER \
--policy-arn arn:aws:iam::EMRYS_ID:policy/AssumeOdinRole
where assume-account-odin-role.json just contains the sts:AssumeRole for Odin's S3ReadWriteRoleEmrys.
Finally, we get the temporary credentials to read the bucket with:
aws sts assume-role \
--role-arn arn:aws:iam::ODIN_ID:role/S3ReadWriteRoleEmrys \
--role-session-name s3-access
Just paste the output of this into your AWS environment variables.
"In addition, IAM roles can also have a special type of a resource-based policy attached to them, called an IAM role trust policy. An IAM role trust policy can be written just like any other resource-based policy, by specifying the principals that are allowed to assume the role in question... Any principal that is allowed to access a role is called a trusted entity for that role." [1]
Note that the key in the Prinicipal map is significant as it defines the category of the identity. It can be
- a Service that is allowed to assume a role (eg, EKS)
- AWS which indicates an IAM user or role or an assumed role (see below). Note that root does not indicate the most powerful user as in Unix. On the contrary, it means anybody legitimately associated with this account.
- Federated which means it's a provider external to the native AWS ecosystem.
STS is the system an identity must apply if it wishes to assume a role. This system checks that the identity is indeed allowed to do this.
An assumed role looks like this:
arn:aws:sts::123456789012:assumed-role/S3ReadWriteRoleSF/snowflake
where S3ReadWriteRoleSF is the normal, IAM role name and snowflake is the session name. This session name is merely a tag and has no intrinsic permissions (although it may be used in Condition/StringEquals). This will be set in --role-session-name (see above) when assuming the role.
[1] Security and Microservice Architecture on AWS