S3 Policy Help - Full access for IAM user. Public read only access for single folder - amazon-web-services

I have an IAM user created with a policy for my bucket. With "public block access" enabled I can interact with the bucket as expected through this user.
Now I need to make a single public read-only folder using bucket policies, but I am not having any luck. I created the below policy which should
Disable all access to all principles
Enable all access for my IAM user
Enable read-only access to specific folders for all users.
{
"Id": "Policy1676746531922",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1676745894018",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::bucket/*",
"Principal": "*"
},
{
"Sid": "Stmt1676746261470",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket/*",
"Principal": {
"AWS": [
"arn:aws:iam::000000000:user/bucket-user"
]
}
},
{
"Sid": "Stmt1676746523001",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket/read-only-folder",
"Principal": "*"
}
]
}
I guess you cannot layer up access in this way, but I am unsure how to construct what I need. If I go with a single read policy to open up one folder, I still seem to be able to access all other folders publically too:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/public/*"
}
]
}
I can access "/public" but can still access "/private" too.
I need a way first to lock down the entire bucket and then open up the folders I want to provide access for?

Your policy is failing because Deny always overrides an Allow.
The first statement in the policy will Deny access to the bucket for everyone (including you!).
Your second policy on arn:aws:s3:::bucket-name/public/* is the correct way to go. It will only grant anonymous access to that particular folder.
If you are able to access other folders, then either there are other policies that exist, or you are using "authenticated access" using your own AWS credentials. Make sure when you test it that you are putting a URL into a web browser that simply looks like: https://bucket-name.ap-southeast-2.s3.amazonaws.com/foo.txt

Related

Restrict public read to server access logging folder in S3

I have a public S3 bucket with read-only access. Then I enabled server access logging to the current bucket but I'm afraid that other users could view the access log anonymously for their own use so I put a deny policy to the /access-logs folder. However, server access logging now is not working since I put Deny effect to the statement as documented in here. Is there any method to enable logging while restrict the access folder only to the bucket owner?
{
"Version": "2012-10-17",
"Id": "S3-Console-Auto-Gen-Policy-1234567",
"Statement": [
{
"Sid": "S3PolicyStmt-DO-NOT-MODIFY-1234567",
"Effect": "Allow",
"Principal": {
"Service": "logging.s3.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::example-bucket/*"
},
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*"
},
{
"Sid": "RestrictAccessLOgs",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/access-logs/*"
}
]
}
You should not put the logs in the same bucket as Coward Anon user said. You can use one bucket to store logs from many different buckets but one should not store logs from itself.
Your target bucket should not have server access logging enabled. You can have logs delivered to any bucket that you own that is in the same Region as the source bucket, including the source bucket itself. However, this would cause an infinite loop of logs and is not recommended. For simpler log management, we recommend that you save access logs in a different bucket.
It's much simpler to do it and set your logs bucket to private (default).
Not recommended, this is just to get you to know about NotPrincipal
{
"Sid": "RestrictAccessLOgs",
"Effect": "Deny",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/access-logs/*",
"NotPrincipal": {
"Service": ["logging.s3.amazonaws.com"]
}
}

How to restrict all access to the AWS s3 bucket

I want to restrict aws s3 bucket to not get access from anywhere, I want block all access public, private, bucket, folder, file everything of that bucket after that then i want to create an access point of s3 then I want to give permission to an IAM user so that only that IAM user can perform all action but only that IAM user
now I am not sure what exactly I also enable or disable like public access or something
also, i don't know I have to give a policy to the bucket or access point
I want to restrict aws s3 bucket to not get access from anywhere, I want block all access public, private, bucket, folder, file everything of that bucket
Use this policy to restrict all access:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAll",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucket/*"
}
]
}
then i want to create an access point of s3 then I want to give permission to an IAM user so that only that IAM user can perform all action but only that IAM user
Use this policy to restrict all access except for one IAM user:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllExceptRole",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {
"StringNotEquals": {
"aws:PrincipalArn": "IAM-ROLE-ARN"
}
}
},
{
"Sid": "AllowRole",
"Effect": "Allow",
"Principal": "IAM-ROLE-ARN",
"Action": "s3:*",
"Resource": "arn:aws:s3:::bucket/*"
}
]
}

aws s3 can upload via cli and console but not nodejs sdk

The bucket is configured to have public access disabled, but with the following bucket policy:
{
"Version": "2012-10-17",
"Id": "Policy1571348371588",
"Statement": [
{
"Sid": "Stmt1571348370292",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::932534461852:user/test-user"
]
},
"Action": [
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::test.test.com",
"arn:aws:s3:::test.test.com/*"
]
}
]
}
The IAM is also attached with this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::*/*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::test.test.com"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": [
"s3:PutAccountPublicAccessBlock",
"s3:ListAllMyBuckets"
],
"Resource": "*"
}
]
}
The bucket's public access setting is:
Block all public access
On
Block public access to buckets and objects granted through new access control lists (ACLs)
On
Block public access to buckets and objects granted through any access control lists (ACLs)
On
Block public access to buckets and objects granted through new public bucket policies
On
Block public and cross-account access to buckets and objects through any public bucket policies
On
I have verified that the cli and the sdk are using the same access key and secret key, and I can use console and cli to upload files without problem, but when I try with node.js's aws-sdk: 2.551.0, I got access denied error.
Where can go wrong?
The problem is likely to be that your Node.js client is using the wrong credentials, is targeting the wrong bucket, or is invoking an action not allowed in the IAM policy. You haven't provided any code so we can't validate the latter.
Also, you don't need to allow the IAM user in an S3 bucket policy if the IAM user's policy allows the necessary S3 actions/resources, so you can remove the bucket policy.

AWS S3 Bucket policy public. How to make object private?

I've a bucket with GetObject available to everyone on full bucket(*). I want to make a few objects private(through Object level operation ACL), i.e. only the bucket owner should have read access to the object. I've gone through all available documentation, but couldn't find any possible way. Can anyone confirm is this possible or not?
You cannot use S3 Object ACLs because ACLs do not have a DENY.
You can modify your S3 policy to specify objects and deny access to individual items.
Example S3 Policy (notice that this policy forbids access to everyone for GetObject for two files):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mybucket/*"
},
{
"Sid": "DenyPublicReadGetObject",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::mybucket/block_this_file",
"arn:aws:s3:::mybucket/block_this_file_too"
]
}
]
}
If you want to add a condition so that certain users can still access the objects, add a condition after the Resource section like this. This condition will allow IAM users john.wayne and bob.hope to still call GetObject.
"Resource": [
"arn:aws:s3:::mybucket/block_this_file",
"arn:aws:s3:::mybucket/block_this_file_too"
],
"Condition": {
"StringNotEquals": {
"aws:username": [
"john.wayne",
"bob.hope"
]
}
}

How to set S3 bucket policy to (mostly) private when object acl is public?

I can't work out how to set my bucket policy to achieve what I want. Any help would be much appreciated! My desired rules are:
users in my account have access via user policies, so shouldn't need access specifically granted to them
anonymous users (or anyone outside my AWS account) should have no access, except:
one folder /temp_public should have a public GetObject (i.e. if you know the URL you can get the file)
these policies should override the object ACL on the files in the bucket, as the object ACLs are sometimes set to public read.
The reason for creating the bucket policy is that many of the objects in the bucket have a public read ACL (inadvertently set when the files were uploaded, but could also happen in future so I want to override the object ACL with the bucket ACL).
Ignoring the temp_public folder, I hoped I could just do this:
{
"Version": "2008-10-17",
"Id": "Policy123456789",
"Statement": [
{
"Sid": "Stmt1",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket-name/*"
}
]
}
(where 123456789012 is my AWS account number), but I get access denied for all users with that bucket policy. I guess the NotPrincipal isn't working in this case?
thanks for any suggestions!
Rory
UPDATE: cross-posted here on AWS forums, and answered!
Many thanks to IP from AWS Forums for this answer, which I've confirmed is working for me:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BucketName/temp_public/*"
}
]
}
This statement will give anyone Read access to objects inside temp_public folder, regardless ACLs on those files.
To override the public access on all other files, you should provide a +Deny+-type statement. The explicit Deny overrides any Allow access, so you must exclude already given permissions. so use NotResource as an exclusion mask (NOT FINAL YET, read below):
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
However, this will deny access to ALL users including your account too, because principal is set to "*". Therefore, you must exclude your account from this Deny (STILL NOT FINAL):
{
"Effect": "Deny",
"NotPrincipal": { "AWS": "arn:aws:iam::XXXXYYYYZZZZ:root" },
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
(where XXXXYYYYZZZZ is your 12-digit AWS account Id)
There's still problem: the statement above denies access to all IAM users (except root account).
You'd like to exclude all your IAM users too, but this is tricky. For some reasons, Amazon S3 doens't support wildcards for specifying IAM users in a bucket policy. You cannot write "arn:aws:iam::XXXXYYYYZZZZ:user/*" as Principal (it gives an error: "Invalid principal in policy"). You have to specify exact user names:
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::XXXXYYYYZZZZ:root",
"arn:aws:iam::XXXXYYYYZZZZ:user/user1",
"arn:aws:iam::XXXXYYYYZZZZ:user/user2",
"arn:aws:iam::XXXXYYYYZZZZ:user/user3",
"arn:aws:iam::XXXXYYYYZZZZ:user/user4" ]
}
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
NB from Rory: The S3 docs suggest you can use arn:aws:iam::XXXXYYYYZZZZ:root to cover all users in the account, but that just doesn't seem to work
So the final policy will look like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::BucketName/temp_public/*"
},
{
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::XXXXYYYYZZZZ:root",
"arn:aws:iam::XXXXYYYYZZZZ:user/user1",
"arn:aws:iam::XXXXYYYYZZZZ:user/user2",
"arn:aws:iam::XXXXYYYYZZZZ:user/user3",
"arn:aws:iam::XXXXYYYYZZZZ:user/user4" ]
}
"Action": "s3:GetObject",
"NotResource": "arn:aws:s3:::BucketName/temp_public/*"
}
]
}