Allow S3 bucket operations based on EC2 role - amazon-web-services

Our EC2s are secured using IAM roles. When trying to run an AWS console command such as aws s3 cp I am seeing:
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
If allowed based on specific users that are given keys, there are no issues. This just isn't working with roles.
Here is the bucket ACL:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Public",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "Devs",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::1234567890:user/DevUser"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/something-privileged/*"
},
{
"Sid": "EC2s",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:role/EC2Role"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/something-privileged/*"
},
]
}
As you can see, we want the public to generally be able to fetch objects that we link to. This works.
We want devs to be able to access a specific hidden folder in the bucket using their AWS keys. This works.
We want EC2s to be able to run aws-cli commands on that same hidden folder using only the assigned security role. This does not work.
I also tried "Effect": "Deny", "NotPrincipal": { ... } on the EC2 statement but that didn't work either.
What's wrong with this ACL?

You have a Deny statement in this where the principal is not that specific IAM user. In any AWS privilege a deny will always override an allow which is the scenario happening here.
To allow this here you will need to include the IAM role arn in the NotPrincipal statement as well. This would look like the below statement.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Public",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "Devs",
"Effect": "Deny",
"NotPrincipal": {
"AWS": ["arn:aws:iam::1234567890:user/DevUser", "arn:aws:iam::1234567890:role/EC2Role"]
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/something-privileged/*"
}
]
}

Related

SLR Policy to grant user permission to create Organization

I want to have an IAM user that has the ability to create an IAM Organization and nothing more.
To achieve this, I need to create a policy that is using SLR.
I am attaching the policy to the group that my IAM belongs to.
If I use the general SLR permission policy I can create an Organization with any user.
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "arn:aws:iam::*:role/aws-service-role/*"
}
When I specify the exact user resource that I want to have those permissions I can't do it anymore.
this is the template provided in the aws docs
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "arn:aws:iam::*:role/aws-service-role/SERVICE-NAME.amazonaws.com/SERVICE-LINKED-ROLE-NAME-PREFIX*",
"Condition": {"StringLike": {"iam:AWSServiceName": "SERVICE-NAME.amazonaws.com"}}
},
this is mine
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "arn:aws:iam::000056397000:user/root_name:role/aws-service-role/organizations.amazonaws.com/*"
}
the error I get is:
An error occurred (AccessDeniedForDependencyException) when calling the CreateOrganization operation: The
request failed because your credentials do not have permission to create the service-linked role required
by AWS Organizations.
What am I missing?
I found a work around.
Not ideal, maybe someone has a better idea.
Group with 2 policies
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "arn:aws:iam::*:role/aws-service-role/organizations.amazonaws.com/AWSServiceRoleForOrganizations*",
"Condition": {
"StringLike": {
"iam:AWSServiceName": "organizations.amazonaws.com"
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "organizations:CreateOrganization",
"Resource": "*"
}
]
}

AWS Lambda S3 Access Denied

I have a lambda function using a role with the following policy excerpt
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::ipwl-lambda-config/*",
"arn:aws:s3:::ipwl-lambda-config"
]
}
My bucket policy looks like the following
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::ipwl-lambda-config/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
},
{
"Sid": "AllowLambda",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountid:role/iam_for_lambda"
},
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::ipwl-lambda-config/*",
"arn:aws:s3:::ipwl-lambda-config"
]
}
]
}
I've allowed GetObject and ListBucket on both the role and the bucket policy. However when my function runs
s3_obj = s3_res.Object(s3_bucket, s3_object)
I get
[ERROR] ClientError: An error occurred (AccessDenied) when calling the
GetObject operation: Access Denied
What more permissions do I have to add? The object is there, I can get it when I run the code locally using an admin role.
Update
I've checked to make sure the bucket and object names are correct dozens of times. The exception is actually coming from the second line here according to the stacktrace
s3_res = boto3.resource('s3')
s3_obj = s3_res.Object(s3_bucket, s3_object)
data = s3_obj.get()['Body'].read()
KMS should only be a factor for PutObject. We have a support account so I may check with them and update with their findings.
To download a KMS-encrypted object from S3, you not only need to be able to get the object. You also need to be able to decrypt the AWS KMS key.
Here's an example of an IAM policy that your Lambda function should have:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "s3get",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::ipwl-lambda-config/*"
},
{
"Sid": "kmsdecrypt",
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:example-region-1:123456789012:key/example-key-id"
}
]
}
The key policy also needs to allow the IAM role to decrypt the key, something like this:
{
"Sid": "kmsdecrypt",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/xyz"
},
"Action": "kms:Decrypt",
"Resource": "*"
}

Why is this bucket policy being shown as public

I am relatively new to AWS.
So recently, we creates an AWS S3 bucket through the AWS console. Then we set the following policy on the bucket:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AddJPGImageFilter",
"Effect": "Allow",
"Principal": {
"AWS": "IAM user ARN"
},
"Action": "s3:PutObject",
"Resource": "bucket_name/*.jpg"
},
{
"Sid": "AddJPEGImageFilter",
"Effect": "Allow",
"Principal": {
"AWS": ""IAM user ARN""
},
"Action": "s3:PutObject",
"Resource": "bucket_name/*.jpeg"
},
{
"Sid": "AddPNGImageFilter",
"Effect": "Allow",
"Principal": {
"AWS": ""IAM user ARN""
},
"Action": "s3:PutObject",
"Resource": "bucket_name/*.png"
}
]
}
Now from what I understand the above policy means the resource would be accessible (with the S3:PutObject action allowed) to only the IAM user ARN mentioned in the Principal.
For it to be public, the Principal would need to be *.
Is my understanding correct ?
If yes, why is the AWS console still showing the above bucket as Public ?
AWS web console has page caching issues. Try logout, clear your cache and re-login again.
Thanks
Sanjog

Amazon CLI won't allow me to list objects

I'm trying to copy contents of an S3 bucket to another bucket on another account, and I wanted to use the CLI to do this. So I set up a bucket policy on the source bucket, allowing a IAM user in the destination account to perform all S3 actions, but it keeps complaining that the ListObjects operation is denied.
I've tried Google, but I can't tell what would be the problem with my policy compared to the solutions I find. Even if I make the source bucket public (and can list it in a browser), it still gives me access denied.
What to do, what to do? Here's my bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAll",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123123123123:user/USER"
},
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::SOURCE",
"arn:aws:s3:::SOURCE/*"
]
}
]
}
Please try using below policy,
{
"Version": "2008-10-17",
"Id": "Policy1357935677554",
"Statement": [
{
"Sid": "CrossAccountList",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::examplebucket"
},
{
"Sid": "CrossAccountS3",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::examplebucket/*"
}
]
}
You can read the full steps here
Another read here

S3 policy - public write but only authenticated read

What I am trying to do is to let (anonymous) users share files to a specified bucket. However, they should not be possible to READ the files, which are already there (and for all I care not even the ones they submitted themselves). The only account which should be able to list/get objects from the bucket should be the bucket owner.
Here is what I got so far:
{
"Version": "2012-10-17",
"Id": "PutOnlyPolicy",
"Statement": [
{
"Sid": "Allow_PublicPut",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::myputbucket/*"
},
{
"Sid": "Deny_Read",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::myputbucket/*"
},
{
"Sid": "Allow_BucketOwnerRead",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::myAWSAccountID:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::myputbucket/*"
}
]
}
The above Policy enables me to write files to the bucket (f.e. via the android app S3anywhere), but I can't GET the objects, not even with my authenticated account.
Do you have any hints on how I could accomplish this? Thanks!
Anonymous users are not able to read a bucket content by default. So you should have only these lines in your policy:
{
"Version": "2012-10-17",
"Id": "PutOnlyPolicy",
"Statement": [
{
"Sid": "Allow_PublicPut",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::myputbucket/*"
}
]
}
The deny statement in your policy takes precedence over everything else. The default is to deny everything that isn't specifically allowed, so you should be able to just remove the deny statement and all will work the way you want.
Policy looks good, I guess that problem into Principal, you can look how it use into documentation http://docs.aws.amazon.com/AmazonS3/latest/dev/s3-bucket-user-policy-specifying-principal-intro.html. Probably you should use AccountNumber-WithoutHyphens