Roles and policies for accessing S3 buckets through a sidecar in the same account
Every sidecar deployed has an IAM role, which in the above picture is shown as SidecarHostRole. To access an S3 bucket in the same account as the sidecar, follow these steps:
Create Role1 with a policy to give access to a bucket or a set of buckets in the same account.
Establish trust relationship between SidecarHostRole and Role1.
Configure a bucket policy to restrict access to selected roles/users (including sidecar).
Examples
Role1 Policy
This is a sample policy that gives Role1 full access to Bucket1:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "arn:aws:s3:::Bucket1", "arn:aws:s3:::Bucket1/*" ] } ] }
Trust relationship between SidecarHostRole and Role1
A trust relationship should be added in Role1, so that the sidecar can assume Role1. Here is an example:
aws iam get-role --role-name Role1 --profile account1-admin { "Role": { "Path": "/", "RoleName": "Role1", "RoleId": "AROAQ2RMKOMXM52O5WTUI", "Arn": "arn:aws:iam::Account1:role/Role1", "CreateDate": "2021-02-09T08:12:28+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::Account1:role/mysidecar-SidecarHostRole-4OQ187ZRHIFD" }, "Action": "sts:AssumeRole" } ] }, "Description": "Allows EC2 instances to call AWS services on your behalf.", "MaxSessionDuration": 3600, "RoleLastUsed": { "LastUsedDate": "2021-07-14T19:02:25+00:00", "Region": "us-west-2" } } }
Bucket policy
Below we show a sample policy that denies access to “bucket1” to all except those in the condition block under “aws:userId”.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::bucket1", "arn:aws:s3:::bucket1/*" ], "Condition": { "StringNotLike": { "aws:userId": [ "AROAQ2RMKOMXM52O5WTUI:*", "AROAQ2RMKOMXIHD7FQ4TP:*", "AIDAIT6NIQ72FNQG3QUQ6", "Account1" ] } } } ] }
The condition block above lists the RoleIds, userIds that need to have access. In this aws:userId list you can specify:
RoleId of a role that the sidecar can assume
RoleId of the SSO users
UserId of IAM
An account number so that an admin always has access to the bucket. Note that putting the account number of the account in which the bucket is present will ensure that admin can always access it, even if the roles were to be deleted.
Note: When writing a Deny policy like the one shown above, please make sure that you do not lose access to the bucket. You can ensure that by including the userId of the admin or root user in the condition block above.
Note that roleIds in the list are specified with wildcard characters. This is essential to allow access to the assumed roles. For example, the value, "AROAQ2RMKOMXM52O5WTUI:*" means the role with roleId AROAQ2RMKOMXM52O5WTUI and its assumed roles.
Commands to obtain the userId are described at the end of this document.
Roles and policies for accessing cross-account S3 buckets through a sidecar
To provide sidecar access to an S3 bucket in another account (here shown as Account2), follow these steps:
In Account2
Create Role2 with a policy to give access to a bucket or a set of buckets in Account2
Establish trust relationship between Role2 and SidecarHostRole (alternatively Account1)
Configure bucket policy to restrict access to selected roles/users (including the sidecar)
In Account1
Add a policy to the SidecarHostRole giving permission to assume Role2
Examples
Role2 Policy (in Account2)
This is a sample policy that gives Role2 full access to Bucket2:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": [ "arn:aws:s3:::Bucket2", "arn:aws:s3:::Bucket2/*" ] } ] }
Trust relationship between Role2 and SidecarHostRole
Role2 needs to have a trust relationship defined with Account1 where the sidecar is deployed. For example:
aws iam get-role --role-name Role2 --profile account2-admin { "Role": { "Path": "/", "RoleName": "Role2", "RoleId": "AROA5PNG7WG36GM5FQEKN", "Arn": "arn:aws:iam::926452527543:role/Role2", "CreateDate": "2021-04-25T05:33:04+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::Account1:role/mysidecar-SidecarHostRole-4OQ187ZRHIFD" }, "Action": "sts:AssumeRole", "Condition": {} } ] }, "Description": "Used for s3 cross account access", "MaxSessionDuration": 3600, "RoleLastUsed": { "LastUsedDate": "2021-07-15T07:06:49+00:00", "Region": "us-west-2" } } }
Bucket Policy
The following sample bucket policy restricts access to the bucket to a select few including the sidecar role. Note that this policy denies access to all except for the role assumed by the sidecar and a select few others.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::Bucket2", "arn:aws:s3:::Bucket2/*" ], "Condition": { "StringNotLike": { "aws:userId": [ "AROA5PNG7WG36GM5FQEKN:*", "AROA5PNG7WG35HCUDFEE2:*", "AROA5PNG7WG3WRQPNM2FH:*", "Account2" ] } } } ] }
The condition block above lists the RoleIds, userIds that need to have access. In this aws:userId list you can specify:
RoleID of a role that sidecar can assume,
RoleId of the SSO users,
UserId of IAM
Account number so that the admin always has access to the bucket. Note that putting the account number of the account in which the bucket is present will ensure that admin can always access it, even if roles were to be deleted.
Note that roleIds in the list are specified with wildcard characters, this is essential to allow access to the assumed roles. For example, the entry, "AROA5PNG7WG36GM5FQEKN:*" means the role with roleId AROA5PNG7WG36GM5FQEKN and its assumed roles.
Note: When writing a Deny policy like the one shown above, make sure that you do not lose access to the bucket. You can ensure that by including the userId of the admin or root user in the condition block above.
Commands to obtain userId are described at the end of this document.
Update SidecarHostRole Policy (in Account1)
Add a policy in the SidecarHostRole giving permission to assume Role2:
{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::Account2:role/Role2" } }
Appendix
Getting userId for Sidecar Roles
For roles, use RoleId for userId. The following is an example command:
aws iam get-role --role-name cyral-c0b7ax-sidecar_role { "Role": { "Path": "/", "RoleName": "cyral-c0b7ax-sidecar_role", "RoleId": "AROAQ2RMKOMXJJMJCWPCJ", "Arn": "arn:aws:iam::057001276206:role/cyral-c0b7ax-sidecar_role", "CreateDate": "2021-06-22T04:57:11+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "MaxSessionDuration": 3600, "RoleLastUsed": { "LastUsedDate": "2021-07-14T21:45:45+00:00", "Region": "us-west-2" } } }
Getting the userId for an IAM user
For IAM, the userId can be obtained using the following command:
aws iam get-user --user-name SOMEUSER { "User": { "Path": "/", "UserName": "SOMEUSER", "UserId": "AIDAITXXXXXXXXXXXXXXX", "Arn": "arn:aws:iam::ACCOUNT:user/SOMEUSER", "CreateDate": "2019-01-22T18:56:56+00:00", "PasswordLastUsed": "2021-07-14T18:01:44+00:00" } }
Getting the userId for an SSO user
In case of an SSO user, the userId is the RoleId of the role they assume.
aws iam get-role --role-name AWSReservedSSO_AWSAdministratorAccess_41d0c7fb5e5b2dfa { "Role": { "Path": "/aws-reserved/sso.amazonaws.com/us-west-2/", "RoleName": "AWSReservedSSO_AWSAdministratorAccess_41d0c7fb5e5b2dfa", "RoleId": "AROAQ2RMKOMXIHD7FQ4TP", "Arn": "arn:aws:iam::057001276206:role/aws-reserved/sso.amazonaws.com/us-west-2/AWSReservedSSO_AWSAdministratorAccess_41d0c7fb5e5b2dfa", "CreateDate": "2020-09-29T17:27:58+00:00", "AssumeRolePolicyDocument": { ... }, "Description": "Provides full access to AWS services and resources", "MaxSessionDuration": 43200, "RoleLastUsed": { "LastUsedDate": "2021-07-14T21:38:57+00:00", "Region": "us-west-2" } } }