IAM Policy and S3 Policy - amazon-web-services

If I have an IAM role that gives access to a bucket, does that bucket ALSO need a bucket policy to specify that the role has access? Can I just have one or the other?
Example:
I have an IAM role that says
{
"Action": [
"s3:Get*",
"s3:Put*",
"s3:DeleteObject",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::bucketname/*"
],
"Effect": "Allow"
}
The bucket has a policy attached but it doesn't include anything about the role with the above statement. There are no deny statements in the bucket policy. Should the role be able to access the files?

Typically, you do not need to provide an S3 bucket policy.
Whenever you make a request to S3, the authorization decision depends on the union of all the IAM policies, S3 bucket policies, and S3 ACLs that apply.
The order of policy evaluation is:
Is there an explicit Deny? Result is deny.
Is there an explicit Allow? Result is allow.
(implicit default) Result is deny.

Here is an interesting article from AWS comparing IAM Policy vs Bucket Policy vs ACL
If you’re more interested in “What can this user do in AWS?” then IAM
policies are probably the way to go. You can easily answer this by
looking up an IAM user and then examining their IAM policies to see
what rights they have.
If you’re more interested in “Who can access
this S3 bucket?” then S3 bucket policies will likely suit you better.
You can easily answer this by looking up a bucket and examining the
bucket policy.
https://aws.amazon.com/blogs/security/iam-policies-and-bucket-policies-and-acls-oh-my-controlling-access-to-s3-resources/

Related

Access denied when principal set to aws lambda.amazonaws.com

I access a bucket with a lambda function and i get an "Access Denied" error, when i access it with a lambda function via boto3. If i set principal to "*" in the Bucket, all works fine. What is the issue?
"Sid": "DenyIncorrectEncryptionHeader",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
...
In the bucket policy, the principal to give allow permission to should be the lambda execution role and not the lambda service (lambda.amazonaws.com).
Adding more details, if the lambda execution role is in the same AWS account as the bucket, then an allow permission in the role should suffice. As long as there is no explicit deny in the bucket policy.
However, if the role and bucket are in separate accounts, the role has to have allow permission and the bucket policy has to give allow permission to the role.
The steps would be:
Create an IAM Role with a use-case of Lambda (this creates a Trust Policy that allows the AWS Lambda service to assume the role)
Add a Policy to the IAM Role that grants the required Amazon S3 permissions
Configure the AWS Lambda function to use this IAM Role
There is no need to use an Amazon S3 Bucket Policy for your stated requirements.
As a general rule, Bucket Policies are used when granting permission to everyone, and IAM policies should be used when granting access to specific Users or Groups. (However, there can be other situations for using Bucket Policies, such as granting cross-account 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

AWS: What is the relationship between S3 bucket policies and user policies?

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

AWS S3 Bucket Policy - Principle Syntax

Right now I have my policy defined on my S3 bucket but it seems like the principles I have defined are root and when someone under an account who isn't root isn't falling into the allow part of the policy
"Principal": {
"AWS": [
"arn:aws:iam::123:root",
"arn:aws:iam::456:root",
"arn:aws:iam::789:root",
"arn:aws:iam::101:root"
]
},
I tired to specify it as
"arn:aws:iam::123:*"
but that doesn't work.
I also tried arn:aws:iam::123:user/sample#yahoo.com but that too doesn't seem to be correct as it fails with Invalid principal in policy
When granting cross-account permissions, you need both of:
A bucket policy on Bucket-A in Account-A (as above)
Permissions on the users in their own account to access Bucket-A (which can include wide permissions such as s3:*, but that's rarely a good idea)
Not only does the bucket need to permit access, but the users in the originating account must be granted permission to use S3 for the desired actions (eg s3:GetObject) on Bucket-A (or all buckets).
See: Bucket Owner Granting Cross-Account Bucket Permissions - Amazon Simple Storage Service

AWS S3 Bucket Policy to block access to all but one directory, even if user has full S3 permissions

I'm not entirely sure if this is possible, but I would like to create a setup similar to what is described in:
https://aws.amazon.com/blogs/security/writing-iam-policies-grant-access-to-user-specific-folders-in-an-amazon-s3-bucket/
by creating an S3 bucket with a subdirectory for each AWS user accessible only to that user.
My question is: is it possible to go a step further and specifically block users that might otherwise have full S3 permissions from being able to read from subdirectories that don't belong to them?
This solution would be ideal for me, except that several users have */* on S3 which I believe will override this policy for them, allowing them to see other users' data. Ideally this would be a bucket policy rather than an IAM group/role so that any user in the account automatically has these permissions applied without needing to be added to a group.
When an IAM user/role accesses an S3 bucket, all of the following policies are applied:
The user's or role's IAM policies,
If the user is in any groups, all of those group's policies, and
If the bucket being accessed has a bucket policy, that policy.
All of those policies work as follows:
All commands are denied, unless
There is an explicit allow in any policy, unless
There is an explicit deny in any policy.
Basically, what this means is that by default, access is denied, unless you add an "Allow" statement to a policy (IAM user/role, group, or bucket). But if you explicitly add a "Deny" statement (in any affecting policy), that "Deny" statement will overrule any other "Allow" statement.
Knowing this, you can apply a bucket policy to your S3 bucket with the correct "Deny" statements. These policy statements would overrule any other policy statements, applying to anyone accessing the bucket (even the super-est of super users).
So, you can try something like this:
{
"Version": "2012-10-17",
"Id": "blah",
"Statement": [
{
"Sid": "DenyListingOfUserFolder",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::block-test",
"Condition": {
"StringNotLike": {
"s3:prefix": [
"",
"home/",
"home/${aws:username}/*"
]
}
}
}
]
}
This policy will deny anyone from listing the contents from any folder aside from the root folder, "home" folder, and "home/their user name" folder.
Be careful when working with "Deny" staetments. The wrong policy could lock you out of your own bucket and you'll need AWS support to remove the policy for you.