AWS S3 bucket policy with condition - amazon-web-services

I am new to S3 bucket polices. In S3 documentation, I found one Bucket policy(attached below). I am not sure what does mean. Does it mean, No-one can do any action(put, read, delete,...) except this user:"AROAEXAMPLEID:*","AIDAEXAMPLEID","111111111111"? Can anyone please verify?
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAEXAMPLEID:*",
"AIDAEXAMPLEID",
"111111111111"
]
}
}
}
]
}

Lets break the policy part by part to help you better understand
"Principal": "*", - all users
"Action": "s3:*" - all actions related to s3
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
] - for my example buckets and its objects
Now lets understand condition
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAEXAMPLEID:*",
"AIDAEXAMPLEID",
"111111111111"
]
}
if string does not contain the mentioned userid which means this condition is true, if this condition is true since effect= Deny is true which means users which do no have the mentioned user id wont be able to perform s3 actions on these buckets.
If this condition is not true which means if it contains userid which are mentioned which means they will be able to perform all s3 operations on the mentioned bucket.

Related

Why does aws s3 bucketpolicy allow upload of objects?

I have this bucket policy( generated from policy generator).
{
"Id": "Policy1620290934586",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1620290801219",
"Action": [
"s3:PutObject"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::bucket-name/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "AES256"
},
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
},
"Principal": "*"
}
]
}
This policy will allow objects to be uploaded only when there is sse-s3 header is present with aes256 value.
Also i have enabled encryption settings for bucket wide using AWS KMS.
so when i am trying to upload a file with default bucket encryption, according to policy it should not allow that because it doest not have sse-s3 header, yet file upload is successful? why?
i have followed this article
Update :-
the following policy works, means when i am using default bucket encryption settings during upload its denies. why didn't the above policy work and why the latter policy works?
{
"Version": "2012-10-17",
"Id": "PutObjectPolicy",
"Statement": [
{
"Sid": "DenyIncorrectEncryptionHeader",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket-name/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
},
{
"Sid": "DenyUnencryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket-name/*",
"Condition": {
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
}
}
]
}
The null statement:
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
can be read as:
if s3:x-amz-server-side-encryption does not exist.
Thus, if I understand correctly the IAM logic, the situation is as follows:
First case:
Your Condition reads as:
if s3:x-amz-server-side-encryption does not exist AND is not equal to AES256.
Since you are using default encryption in the first try, there is no s3:x-amz-server-side-encryption key in the request. From docs:
A key that is not present in the request is considered a mismatch.
This means that your Condition is not satisfied and Deny does not apply.
Second case.
This one works, because by having two separate statements you are saying:
if s3:x-amz-server-side-encryption does not exist OR is not equal to AES256
So Deny will take effect in any case.

How to solve conditions do not apply to combination of actions and resources in statement?

I am trying to copy an s3 bucket from one account to another account. In order to do so, I am following the steps as described by aws. In step 4, the following policy is suggested:
{
"Statement": [
{
"Sid": "ExampleStmt",
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET",
"arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
},
"Principal": {
"AWS": [
"arn:aws:iam::222222222222:user/Jane"
]
}
}
]
}
However, when I try to do this (after replacing the example buckets and arn), I get the following error: Conditions do not apply to combination of actions and resources in statement.
How can I solve this error and make sure I can copy the s3 from one account to another?
The condition key you are using is not applicable to the actions you have specified.
PutObject
PubObjectAcl
ListBucket
You can checkout here Condition keys for Amazon S3 for various conditions being supported by S3.

Tried to allow lambda to access S3 with S3 resource based policy, why didn't it work?

I, apparently, naively, Tried to allow any lambda access to read from an S3 bucket.
Never mind if this is a good practice, but for the sake of understanding, I applied the resource policy at the bottom to the S3 bucket (buket, permissions tab, bucket policy).
I thought that his will allow any lambda to read from the bucket.
but it didn't work.
the only thing that did work, was to set the policy of the lambda to allow reading from this bucket.
My question is, what is the meaning of this S3 resource based policy? the ui allows this, so I assume it's something valid. but what?
thanks!
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
}
]
}
It doesn't work because your function assumes its execution role role.
Thus you have to add the function's role to bucket policy, not the lambda service:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "<your-function-execution-role-arn>"
},
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
}
]
}

AWS Macie - list of query fields

In the AWS Macie documentation, it shows an example of adding a basic alert.
The example query to add is s3_world_readability:"true"
Where do we find a list of valid fields that we can query on?
The docs refer to Constructing Queries in Macie, but nowhere do I see any listing of what fields I can query.
I'm trying to figure out whether I can create Macie alert if a Bucket doesn't have a bucket policy that enforces Server Side Encryption
Am I missing something obvious?
Update
Found out you can get some suggestions from the Macie console in the Research tab.
Using this pattern when selecting S3 bucket properties, I'm able to drill down into the bucket policy.
My Bucket policy is
{
"Version": "2008-10-17",
"Id": "Policy123456789",
"Statement": [
{
"Sid": "DenyIncorrectEncryptionHeader",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
},
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"Null": {
"s3:x-amz-server-side-encryption": "true"
}
}
}
]
}
I can use the following query in Macie and it will return the bucket with this policy
policy.Policy.Statement.Action:"s3:PutObject"
So if want to query bucket policies that match the Conditions forcing SSE, I try:
policy.Policy.Statement.Condition.StringNotEquals.s3\:x\-amz\-server\-side\-encryption:"AES256"
But I get nothing back. Is there a better way for me to query these properties?

S3 bucket policy: In a Public Bucket, make a sub-folder private

I have a bucket filled with contents that need to be mostly public. However, there is one folder (aka "prefix") that should only be accessible by an authenticated IAM user.
{
"Statement": [
{
"Sid": "AllowIAMUser",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket/prefix1/prefix2/private/*",
"Principal": {
"AWS": [
"arn:aws:iam::123456789012:user/bobbydroptables"
]
}
},
{
"Sid": "AllowAccessToAllExceptPrivate",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {
"StringNotLike": {
"s3:prefix": "prefix1/prefix2/private/"
}
},
"Principal": {
"AWS": [
"*"
]
}
}
]
}
When I try to save this policy I get the following error messages from AWS:
Conditions do not apply to combination of actions and resources in statement -
Condition "s3:prefix"
and action "s3:GetObject"
in statement "AllowAccessToAllExceptPrivate"
Obviously this error applies specifically to the second statement. Is it not possible to use the "s3:prefix" condition with the "s3:GetObject" action?
Is it possible to take one portion of a public bucket and make it accessible only to authenticated users?
In case it matters, this bucket will only be accessed read-only via api.
This question is similar to Amazon S3 bucket policy for public restrictions only, except I am trying to solve the problem by taking a different approach.
After much digging through AWS documentation, as well as many trial and error permutations in the policy editor, I think I have found an adequate solution.
Apparently, AWS provides an option called NotResource (not found in the Policy Generator currently).
The NotResource element lets you grant or deny access to all but a few
of your resources, by allowing you to specify only those resources to
which your policy should not be applied.
With this, I do not even need to play around with conditions. This means that the following statement will work in a bucket policy:
{
"Sid": "AllowAccessToAllExceptPrivate",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Effect": "Allow",
"NotResource": [
"arn:aws:s3:::bucket/prefix1/prefix2/private/*",
"arn:aws:s3:::bucket/prefix1/prefix2/private"
],
"Principal": {
"AWS": [
"*"
]
}
}