AWS: What is the relationship between S3 bucket policies and user policies? - amazon-web-services

What is (or should be) the relationship between a S3 bucket policy and its designated administrator's user policy?
E.g. suppose I've newly created a bucket:
$ aws --profile admin --endpoint-url http://localhost:4572 s3 mb s3://foo
make_bucket: foo
I want user bucket_admin to be able to administer the bucket (not necessarily exclusively). To do this, should I create/apply a bucket policy along the lines of:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:*"],
"Principal": { "AWS": "arn:aws:iam::000000000000:user/bucket_admin" },
"Resource": "arn:aws:s3:::foo/*"
}
]
}
...or create/apply a user policy along the lines of:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect":"Allow",
"Action":["s3:*"],
"Resource":["arn:aws:s3:::foo/*"]
}
]
}
?

Your bucket policy applies to only one principle, the bucket_admin user. It can't be used by a role, other IAM user or a group, if you want to have more identities being able to administer the bucket.
The IAM policy does not have a principle by definition. It means you have to attach it to an identity, such as IAM role, user or group. This gives you more flexibility on how to distribute the permissions to the bucket. It can be only the bucket_admin, or you can create a group of bucket admins, or have role which can be assumed by an EC2 instance.
Also with IAM policy it is easier to check who/what is using it. You just go to IAM console, and to Policy Usage and you will get a list of all identities which use the policy. With bucket policies, you have to go manually over all buckets and inspect their policies to check who can be admin of buckets.
Good general comparison of resource vs IAM policies is here:
Identity-Based Policies and Resource-Based Policies
Also useful read as IAM policies can be attached to roles:
How IAM Roles Differ from Resource-based Policies

In addition to #Marcin's answer, which is great...
We use bucket policies mostly for bucket-level checks - ensure the traffic is SSL, ensure the traffic originates from a specific VPC, etc.
Using roles attached to IAM users is an easier way of controlling user access.
The exception is where a user is trying to access a bucket in another account - in this case, both a bucket policy and an IAM policy is needed https://docs.aws.amazon.com/AmazonS3/latest/dev/example-walkthroughs-managing-access-example2.html

Related

Why bucket policy does not provide IAM user to list s3 buckets even bucket policy is set for the user?

I have created bucket poc-work from admin account, and under this policy I have set policy like below:
{
"Version": "2012-10-17",
"Id": "Policy1620674317608",
"Statement": [
{
"Sid": "Stmt1321974214233",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accound-id:user/iam-user"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::poc-work",
"arn:aws:s3:::poc-work/*"
]
}
]
}
I have not attached any aws managed policy like s3readonly to IAM user , but I am under assumption that setting bucket policy should make bucket visible to IAM user . But when IAM user log in and check for s3 service there is error message:
You don't have permissions to list buckets
I have below queries:
can't I create bucket policy that enables list s3 buckets ?
Is it necessary to attach policy already defined browsing on IAM console and then rest of operations control with bucket policy ?
You are giving the user permission for one bucket, but if the user is going through the console the user needs the ListAllBuckets permission to see all the buckets that exist in the account. So you do need to add permissions to the IAM user as well--not just the one bucket.
Also see:
https://acloud.guru/forums/s3-masterclass/discussion/-L6X96Lo37ZnG_g6wiEg/ListBucket%20vs%20ListAllMyBuckets
https://stackoverflow.com/a/30961920/230055
https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-buckets
https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-walkthroughs-managing-access-example1.html
The 1st link says:
ListAllMyBuckets is required for seeing the list of buckets via the
AWS console. It is a MUST if you plan to use the console for S3
administration. If you don't have this permission you basically won't
see any of the buckets in the S3 console despite whatever other
permissions you have configured and therefore can't take any action
upon them.

Can IAM user assume a role, if the user is not described in the Trust policy of the role?

Can a role be assumed if it does not have a Trust policy?
If a given IAM user has an attached identity based policy saying that he/she can call sts:AssumeRole for a given role (inside the same account), but the user is not described in the Trust policy of this role, will he/she be able to assume the role?
Usually only the resource based policy or the identity based policy should be enough to give rights for the user, but is it different for the roles?
Thanks
will he/she be able to assume the role?
Yes, of course she/he will be able to do it, as long the trust policy allows the account to assume the role. For example, a role has to have the trust policy of:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "<account-number>"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
This way, your IAM user does not need to be explicitly listed in the trust policy, but trust policy is required and at least you should specify the account which can assume it. But the drawback is that any IAM user or role from the <account-number> account that has sts:AssumeRole permissions can assume the role.
it does not have a Trust policy?
Trust policy is required, so you can't have a role without such such a policy.
Update
Lets assume you have a role with a trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxx:user/UserA"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
The role can be assumed only by userA. UserB will not be able to assume this policy, regardless of his permissions.
A Trust Policy specifies the "Principal" which can assume the role it is attached to. That principal can be various different types of entity, such as an AWS service (e.g. to create a role applied to EC2 instances), or the identifier of another AWS account (to grant cross-account access). It cannot be omitted or be a wildcard.
If the principal identifies an AWS account, then it is trusting the AWS account as a whole. In a sense, all users in that account have been included in the trust policy, but to assume the role they also need permission to make the appropriate AssumeRole API call. This delegates responsibility to the administrator of the other AWS account to decide which users should be able to assume the role.
This can be used to create a hierarchical arrangement of accounts:
All users are created in a single AWS account, which has no other resources.
The actual resources - EC2 instances, S3 buckets, etc - are in separate AWS accounts.
Each account defines roles granting access to some of these services, with a trust policy listing the central account as the Principal. These roles do not list individual users or groups as trusted, they just define sets of permissions.
The users in the central account are each granted AssumeRole access to an appropriate subset of the roles in the different accounts. The effect is similar to using Groups or Managed Policies to grant multiple users the same access.

Give S3 Full access cross account

I have two amazon accounts Account-A and Account-B. I want to give Account-B full control to all S3 related operations in Account-A for example Account-B can create/delete/list buckets belonging to Account-A.
Can you point me to how it's done? So far I was only able to find how to grant cross account access to a single S3 bucket but not to all S3 functionalities.
Start with the AWS doc walkthrough, then set the bucket policy as (my changes from the doc have // comments):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AccountB-ID:root"
},
"Action": [
"s3:*", // ALL S3 actions
],
"Resource": [
"*" // ALL resources with an 's3:' operation
]
}
]
}
There are two ways to assign cross-account permissions for Amazon S3:
Using Bucket Policies
Add a Bucket Policy to each desired bucket that grants permission to the other account
Add permissions to the desired IAM Users and IAM Roles in Account-B that allow them to access the buckets in Account-A
Note that the permissions are required in both directions.
The downside to this method is that the Bucket Policy must be applied to every bucket that you want to make available. Also, this will not work for creating new buckets since there is no bucket policy to grant access.
Using an IAM Role
Create an IAM Role in Account-A (Role-A) that has all desired S3 permissions, and a Trust Policies that trusts Account-B
From Account-B, call AssumeRole() on Role-A
Use the returned credentials to manage S3 resources in Account-A
This does not require any Bucket Policies, but has the requirement to call AssumeRole().
See also: Provide cross-account access to objects in S3 buckets

understanding kms policy?

I have a IAM group called group-dev and couple of users attached to this group, I have custom IAM policy(below). Does this IAM policy alone be sufficient for users in that group to encrypt and list kms keys?
Basically My goal is to create IAM group with policy attached to couple of users, and when new users are added i don't want to go about do double work like adding them to group and then adding them to kms key policy. So would it work with the below policies ?
IAM group inline policy
{
"Action": [
"kms:List*",
"kms:Encrypt",
"kms:Decrypt",
"kms:Describe*",
"kms:Get*"
],
"Effect": "Allow",
"Resource": "*"
},
kms policy
{
"Id": "key-consolepolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxx:root"
},
"Action": "kms:*",
"Resource": "*"
}
Below are snippets from aws doc: https://docs.amazonaws.cn/en_us/kms/latest/developerguide/kms-dg.pdf#page=95&zoom=100,96,105
Allowing multiple IAM users to access a CMK
IAM groups are not valid principals in a key policy. To allow multiple IAM users to access a CMK, do one of
the following:
• Add each IAM user to the key policy. This approach requires that you update the key policy each time
the list of authorized users changes.
• Ensure that the key policy includes the statement that enables IAM policies to allow access to the
CMK (p. 72). Then create an IAM policy that allows access to the CMK, and then attach that policy to
an IAM group that contains the authorized IAM users. Using this approach, you don't need to change
any policies when the list of authorized users changes. Instead, you only need to add or remove those
users from the appropriate IAM group.
Looks like there are contradicting statements, or is it something i misunderstood?
. Enables IAM policies to allow access to the CMK.
IAM policies by themselves are not sufficient to allow access to a CMK. However, you can use them
in combination with a CMK's key policy if the key policy enables it. Giving the AWS account full
access to the CMK does this; it enables you to use IAM policies to give IAM users and roles in the
account access to the CMK. It does not by itself give any IAM users or roles access to the CMK, but it
enables you to use IAM policies to do so. For more information, see Managing access to AWS KMS
CMKs (p. 69).
First to compare how these work together each CMK (Customer Managed Key) is created with a key policy that restricts which principal (the caller of the action i.e. IAM Role/IAM User/Service) can access it (and the permissions that the principal will have). It does not matter whichever IAM permissions you grant, if your key policy does not allow the permission no IAM user (including the root user) can perform the action.
The IAM policy attached to the users will grant the maximum permissions that the user can perform. When the action is evaluated the key policy permissions are evaluated as well, if the permission is allowed in both policies the principal will be allowed to perform the action.
So in summary, for KMS both the key policy and the IAM policy permissions must allow access. The permissions you have would allow the users to have the majority of access to the KMS key.

Am I allowed to connect to arbitrary RDS DB instances if given the RDS DbiResourceId?

I am checking the steps of setting up IAM auth in RDS: https://aws.amazon.com/premiumsupport/knowledge-center/users-connect-rds-iam/ And one of the steps is to attach the IAM role with proper permission: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:us-east-2:1234567890:dbuser:db-ABCDEFGHIJKL01234/db_user"
]
}
]
}
The resource follows this format:
arn:aws:rds-db:region:account-id:dbuser:DbiResourceId/db-user-name
If I understand correctly, as long as I know someone's account-id, DbiResourceId and db-user-name (or maybe db-user-name as I can use wildcard?), then I am able to connect to that DB instance, right?
This sounds insecure. Did I miss anything?
No this would not be possible. The only want to interact with this resource would be to assume a role in the target account.
You can use an IAM role to allow someone (a trusted principal) in a different account to access resources in your account. Roles are the primary way to grant cross-account access. However, with some AWS services, you can attach a policy directly to a resource (instead of using a role as a proxy). To learn the difference between roles and resource-based policies for cross-account access, see How IAM Roles Differ from Resource-based Policies in the IAM User Guide