Amazon Web Service S3 Access Denied with seemingly good IAM policy - amazon-web-services

The following AWS Policy is meant to be bound to an IAM group and then added to users. This will grant every user in the group access to their own folder on Amazon S3.
Now the problem is that with this Policy users still get Access denied in their own folder, they can not list the buckets or perform any other operations.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucketname",
"Condition": {
"StringLike": {
"s3:prefix": [
"",
"home/",
"home/${aws:username}/"
]
}
}
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucketname/home/${aws:username}",
"arn:aws:s3:::bucketname/home/${aws:username}/*"
]
}
]
}
What I eventually would like is that the user is able to put and get files from their own folder, but not see any of the other folders or buckets, but that doesn't seem possible with this policy.
Ideas?

Apparantly it takes up to a few minutes for the policy to apply, policy validates fine now.

Related

Allow IAM user to access specific folder in AWS S3 Bucket to view and upload objects

I have multiple s3 buckets, i need to allow one s3 bucket folder access to IAM user to upload and view objects. can some one assist me how to do this.
If you wish to grant specific IAM User(s) access to particular folders within an Amazon S3 bucket, you can create an IAM Policy and attach it to the user.
From User policy examples - Amazon Simple Storage Service:
To grant each user access only to his or her folder, you can write a policy for each user and attach it individually. For example, you can attach the following policy to user Alice to allow her specific Amazon S3 permissions on the awsexamplebucket1/Alice folder.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::awsexamplebucket1/Alice/*"
},
{
"Sid": "AllowListBucketOfASpecificUserPrefix",
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": "arn:aws:s3:::awsexamplebucket1",
"Condition": {
"StringLike": {
"s3:prefix": [
"Alice/*"
]
}
}
}
]
}
If you want to do this for multiple users, the easiest way is to create a single policy and attach it to an IAM Group, the put the users in the group. This policy will grant them access to a folder with the same name as their username:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::awsexamplebucket1/${aws:username}/*"
},
{
"Sid": "AllowListBucketOfASpecificUserPrefix",
"Action": "s3:ListBucket",
"Effect": "Allow",
"Resource": "arn:aws:s3:::awsexamplebucket1",
"Condition": {
"StringLike": {
"s3:prefix": [
"${aws:username}/*"
]
}
}
},
]
}

AWS policy to allow access only to a specific bucket folder

I am trying to create an IAM policy to allow a user access only to a specific folder in an S3 bucket.
How do I do this using visual policy editor?
In the resource section if I mention the arn for the folder, the user is being denied access to the whole bucket.
Here is a policy that grants access to a specific folder within a bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["folder1/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/folder1/*"]
}
]
}
Things to note:
The ListBucket operation that allows listing a bucket is a permission on the bucket itself (not a path). To restrict which folders they can list, the folder must be specified via the s3:prefix.
The GetObject and PutObject operations operate on objects, so the folder can be referenced in the ARN.
It is also possible to use IAM Policy Elements: Variables and Tags to refer to a username. This policy can be applied to an IAM Group and will allow each user access to a folder with their own name:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["${aws:username}/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/${aws:username}/*"]
}
]
}

Can you use tags to give access to S3 Buckets?

I just tried adding tags to some buckets and then I created an inline IAM role policy that'd give that role access to the S3 buckets however that didn't work. I tried both iam:ResourceTag/tagName and s3:ResourceTag/tagName as conditionals but neither worked.
As everything looked just fine I started thinking that AWS might not have implemented this yet for S3. Is that the case? I tried reviewing documentation and indeed I didn't find anything about this use of tags working with S3.
For example the role HumanResources should have to all buckets tagged with HR, Recruitment etc. but no other buckets.
In looking at Actions, Resources, and Condition Keys for Amazon S3 - AWS Identity and Access Management, there does not appear to be the ability to specify a Bucket Tag in an IAM Policy.
One alternative is to use a wildcard in a bucket name. For example, you could grant permission to access:
acme-hr-1
You could grant permissions based on a bucket name of acme-hr-*.
Yes you can but you will need do on each S3 Resource Policy.
Here is an S3 Policy to grant access to the bucket for only IAM users and roles with a Tag department set to "hr".
To ensure HR employee only have access to these buckets you will need to remove all S3 access from their IAM user/role access polices.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyObjectOthers",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts",
"s3:DeleteObject*",
"s3:PutObject*",
"s3:GetObject*",
"s3:RestoreObject*"
],
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
],
"Condition": {
"StringNotLike": {
"aws:PrincipalTag/department": [
"hr"
]
}
}
},
{
"Sid": "DenyListOthers",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:ListBucket*"
],
"Resource": [
"arn:aws:s3:::BUCKET_NAME"
],
"Condition": {
"StringNotLike": {
"aws:PrincipalTag/department": [
"hr"
]
}
}
},
{
"Sid": "AllowObject",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AWS_ACCOUNT_NUMBER:root"
},
"Action": [
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts",
"s3:DeleteObject*",
"s3:PutObject*",
"s3:GetObject*",
"s3:RestoreObject*"
],
"Resource": [
"arn:aws:s3:::BUCKET_NAME/*"
],
"Condition": {
"StringLike": {
"aws:PrincipalTag/department": [
"hr"
]
}
}
},
{
"Sid": "AllowList",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AWS_ACCOUNT_NUMBER:root"
},
"Action": [
"s3:ListBucket*"
],
"Resource": [
"arn:aws:s3:::BUCKET_NAME"
],
"Condition": {
"StringLike": {
"aws:PrincipalTag/department": [
"hr"
]
}
}
}
]
}
Previous Wrong Answer
From: IAM Policy Elements: Variables and Tags - AWS Identity and Access Management
"Resource": ["arn:aws:s3:::bucket/${aws:PrincipalTag/department}"]
Also make sure to include the version at 2012-10-17.

What is Wrong With My AWS Policy?

I am trying to give a programmatic IAM user access to a single bucket.
I setup the following policy and attached it to the user:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::mybucket"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::mybucket/*"
]
}
]
}
Trying to programatically upload a file I got a 403.
I got this policy from here:
Writing IAM Policies: How to Grant Access to an Amazon S3 Bucket
I verified that everything else is working by then adding an AWS managed policy, AmazonS3FullAccess, after which my upload succeeded. But I would rather not give this user full access.
There are no other policies attached to this user.
Nothing is wrong with your policy. Make sure you're using the right bucket name in the IAM policy and to add the policy to the user.
You can test it with IAM Policy Simulator. Maybe you should consider the time to policies take effect, but it's "almost immediately". See this answer.
You can try this policy to give full access to a particular bucket:
{
"Version": "2012-10-17",
"Statement": [{
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<BUCKETNAME>/*"
]
},
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
}
]
}
Since you are providing Put, Get, Delete, You might as well provide full access to the particular bucket.

S3 Private Bucket

I'm trying to create a private S3 bucket with limited access. I only want myself as a user and an EC2 role to have access to the bucket. The purpose of the bucket is to store encrypted SSH keys that will be copied onto machines in an autoscaling group. Right now, when I run aws sync against the bucket, here is the output:
cogility#ip-10-10-200-113:~$ aws s3 sync s3://sshfolder.companycloud.com/cogility /home/cogility/.ssh
download failed: s3://sshfolder.companycloud.com/cogility/id_rsa to ../cogility/.ssh/id_rsa An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
download failed: s3://sshfolder.companycloud.com/cogility/id_rsa.pub to ../cogility/.ssh/id_rsa.pub An error occurred (AccessDenied) when calling the GetObject operation: Access Denied
I create the EC2 instances with an EC2 role with the following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"kms:List*",
"kms:Get*",
"kms:Describe*"
],
"Resource": "arn:aws:kms:us-west-2:0000000000:key/kms-id-01234567890"
},
{
"Sid": "",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::sshfolder.companycloud.com/*",
"arn:aws:s3:::sshfolder.companycloud.com"
]
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"elasticloadbalancing:*",
"ec2:*",
"cloudwatch:*",
"autoscaling:*"
],
"Resource": "*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"lambda:List*",
"lambda:Invoke*",
"lambda:Get*"
],
"Resource": "*"
}
]
}
And here is the bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::sshfolder.companycloud.com",
"arn:aws:s3:::sshfolder.companycloud.com/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAXXXXXXXXXXXXXXXXX", <-- autoscaling-ec2-role user id
"AROAXXXXXXXXXXXXXXXXX",
"AIDAXXXXXXXXXXXXXXXXX",
"AIDAXXXXXXXXXXXXXXXXX"
],
"aws:sourceVpce": "vpce-abc82480d"
},
"ArnNotLike": {
"aws:SourceArn": "arn:aws:sts::000000000000:assumed-role/autoscaling-ec2-role/"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::000000000000:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::sshfolder.companycloud.com",
"arn:aws:s3:::sshfolder.companycloud.com/*"
]
}
]
}
Any idea why I'm not able to access the S3 bucket from my EC2 instance?
Amazon S3 buckets are private by default. Therefore, one approach would be:
Do not use a Bucket Policy
Add permissions to your IAM User and the IAM Role to access the bucket
Alternatively:
Use a Bucket Policy to grant access to the IAM User and IAM Role
Both would be sufficient to meet your needs.
However, if you are further paranoid that somebody might accidentally grant access to the bucket (eg with s3:* and a principal of *), then your approach of explicitly Denying access to anyone other than that User & Role is a good approach.
deny trumps allow in your bucket policy. You need to use not principal to achieve this.
"Statement": [
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::000000000000:root"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::sshfolder.companycloud.com",
"arn:aws:s3:::sshfolder.companycloud.com/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAXXXXXXXXXXXXXXXXX", <-- autoscaling-ec2-role user id
"AROAXXXXXXXXXXXXXXXXX",
"AIDAXXXXXXXXXXXXXXXXX",
"AIDAXXXXXXXXXXXXXXXXX"
],
"aws:sourceVpce": "vpce-abc82480d"
},
"ArnNotLike": {
"aws:SourceArn": "arn:aws:sts::000000000000:assumed-role/autoscaling-ec2-role/"
}
}
}
]
It just inverts the principal element. You can similarly use NotAction and NotResource as appropriate. You could do away with your conditionals altogether and just use NotPrincipal for all of them, it's generally better practice than conditionals.
Here is a resource on it: https://aws.amazon.com/blogs/security/how-to-create-a-policy-that-whitelists-access-to-sensitive-amazon-s3-buckets/