denying access to S3 bucket except specific lambda - amazon-web-services

I am trying to add the below bucket policy that would deny access to the bucket for any (get, put, delete) operation except my AWS lambda. Can you please help why this is not working
{
"Version": "2012-10-17",
"Id": "Policy#####",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::#####-s3-file-upload/*"
],
"Condition": {
"ArnNotEquals": {
"aws:SourceArn": "arn:aws:lambda:us-east-1:5######1:function:temp_read_s3"
}
}
}
]
}

Step 1: Create lambda execution role for lambda.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::XXX-s3-file-upload",
"arn:aws:s3:::XXX-s3-file-upload/*"
]
}]
}
Step 2: Add that role to lambda
Step 3: Add that role to S3 policy to restrict only that role.
{
"Version": "2008-10-17",
"Statement": [{
"Sid": "S3 Access Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::2XXXXXXXXX:role/executionrole"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::sample_bucket",
"arn:aws:s3:::sample_bucket/*"
]
}]
}
This way you can restrict only specific lambda. For other lambda you can use different execution role.
Reference : https://aws.amazon.com/premiumsupport/knowledge-center/lambda-execution-role-s3-bucket/

solution for lambda is to add an assumed role. With a bit of digging and troubleshooting, I realized that the Lambda function assumes the role you provide, and that assumed role must also be added to the S3 bucket policy as below.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "2",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::55account_id111:role/iam_policy_role",
"arn:aws:sts::55account_id111:assumed-role/#####_lambda_role/lambda_function"
]
},
"Action": [ "s3:GetObject",
"s3:PutObject",
"s3:DeleteObject" ]
"Resource": [
"arn:aws:s3:::######-bucketName/*",
"arn:aws:s3:::######-bucketName"
]
}
]
}

Related

AWS IAM bucket permissions access denied

Has anyone encountered the situation when I use manage policies on a user, It works but when I use inline policy it says access denied. I am giving Read access to a bucket for IAM user that is it can only access that bucket.
Manage Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "*"
}
]
}
Inline Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": "arn:aws:s3:::mybucketname/*"
}
]
}
I also tried this
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3Permissions",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucketname/*",
"arn:aws:s3:::mybucketname"
]
}
]
}
Your last policy should be fine for direct access to the bucket as explained in:
How can I grant a user Amazon S3 console access to only a certain bucket or folder?
For console access, additional permissions are required, as shown in:
Writing IAM Policies: How to Grant Access to an Amazon S3 Bucket
Specifically the policy should like like:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::test"]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": ["arn:aws:s3:::test/*"]
}
]
}
Amazons3ReadonlyAccess has all the above permissions, your inline policy does not.

Restrict IAM user for a cross account role to a single bucket

I'll like my Iam policy used for a cross account to access just a single S3 bucket as in the example below but it fails with permission denied. The failure occurs when i switch to a cross account role on the console in AccountA and attempt to access the S3 bucket in accountB. However, I am able to view the S3 bucket in accountB when I change the "Resource" on the Iam policy to allow everything.
xx.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "mysid",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucket/*",
"arn:aws:s3:::mybucket/"
]
}
]
}
However, I am able to view the S3 bucket in accountB when I change the "Resource" on the Iam policy to allow everything. eg
xxx.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "mysid",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "*"
]
}
]
}
but this is not what i want.
other files used include:
xx.tpl
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "${Sid}",
"Effect": "${Effect}",
"Action": "${Action}",
"Resource": "${Resource}"
}
]
}
xx.tf
data "aws_iam_policy_document" "s3_write" {
count = length(var.s3_bucket_names)
statement {
actions = ["s3:PutObject", "s3:DeleteObject", "s3:DeleteObjectVersion", "s3:PutObjectAcl", "s3:List*", "s3:Get*", "s3:*"]
resources = ["arn:aws:s3:::${aws_s3_bucket.mybucket[count.index].id}/*", "arn:aws:s3:::${aws_s3_bucket.mybucket[count.index].id}"]
principals {
identifiers = var.principals
type = "AWS"
}
}
resource "aws_s3_bucket_policy" "s3_lb" {
count = length(var.s3_bucket_names)
bucket = aws_s3_bucket.mybucket[count.index].id
policy = data.aws_iam_policy_document.s3_write[count.index].json
}
s3 bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::xxxx:role/test-role1",
"arn:aws:iam::xxxx:role/test-role2",
"arn:aws:iam::xxxx:role/test-role3",
"arn:aws:iam::xxxx-other:role/s3-list-role"
]
},
"Action": [
"s3:PutObjectAcl",
"s3:PutObject",
"s3:List*",
"s3:Get*",
"s3:DeleteObjectVersion",
"s3:DeleteObject",
"s3:*"
],
"Resource": [
"arn:aws:s3:::mybucket/*",
"arn:aws:s3:::mybucket"
]
}
]
}
I changed this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "mysid",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucket/*",
"arn:aws:s3:::mybucket/"
]
}
]
}
To this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::mybucket"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::mybucket/*"
]
}
]
}
Giving my IAM user cross account access to both the console and CLI. The first allow statement is required for console cross account access.
If arn:aws:iam::xxxx:role/test-role1 has this policy attached, then a session with that role will get access to the bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "mysid",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucket/*",
"arn:aws:s3:::mybucket"
]
}
]
}
The S3 bucket policy grants this principal access. The problem is the trailing slash on the bucket ARN (second resource listed in the policy above.

Allow IAM user to access single s3 bucket

I am using inline policy for grant access to s3 bucket for IAM user
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1513073615000",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::newput-test"
]
}
]
}
but on extended s3 browser when I use the access key id and secret access key of particular IAM user is not listing my bucket.but when I pass * in resources It works fine
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1513073615000",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"*"
]
}
]
}
but the problem is its giving access to all the s3 bucket to IAM user.
but I want to give access only single bucket anybody have an idea how to achieve this.
Try something like this
{
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::mys3bucket",
"arn:aws:s3:::mys3bucket/*"
]
}
]
}
Its been explained here.
http://www.fizerkhan.com/blog/posts/Restrict-user-access-to-Single-S3-Bucket-using-Amazon-IAM.html

Restrict user access to Single S3 Bucket using Amazon IAM?

When you work with the team, you might want to restrict an access to a single S3 bucket to specific users. How can I achieve this?
The following code is not working. The user still has full permission.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::Privatebacket",
"arn:aws:s3:::Privatebacket/*"
]
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::YOUR-BUCKET",
"arn:aws:s3:::YOUR-BUCKET/*"
]
}
]
}
https://www.serverkaka.com/2018/05/grant-access-to-only-one-s3-bucket-to-aws-user.html
Try the below mentioned link. You can grant user specific folder permissions using IAM policies.
https://aws.amazon.com/blogs/security/writing-iam-policies-grant-access-to-user-specific-folders-in-an-amazon-s3-bucket/
You can add an inline policy for that IAM user. You can set a 'deny' policy to that specific s3 bucket.
Policy Document:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1497522841000",
"Effect": "Deny",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::mjzone-private"
]
}
]
}

S3 Bucket action doesn't apply to any resources

I'm following the instructions from this answer to generate the follow S3 bucket policy:
{
"Id": "Policy1495981680273",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1495981517155",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::surplace-audio",
"Principal": "*"
}
]
}
I get back the following error:
Action does not apply to any resource(s) in statement
What am I missing from my policy?
From IAM docs, http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Action
Some services do not let you specify actions for individual resources; instead, any actions that you list in the Action or NotAction element apply to all resources in that service. In these cases, you use the wildcard * in the Resource element.
With this information, resource should have a value like below:
"Resource": "arn:aws:s3:::surplace-audio/*"
Just removing the s3:ListBucket permission wasn't really a good enough solution for me, and probably isn't for many others.
If you want the s3:ListBucket permission, you need to just have the plain arn of the bucket (without the /* at the end) as this permission applies to the bucket itself and not items within the bucket.
As shown below, you have to have the s3:ListBucket permission as a separate statement from the permissions pertaining to items within the bucket like s3:GetObject and s3:PutObject:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Principal": {
"AWS": "[IAM ARN HERE]"
},
"Resource": "arn:aws:s3:::my-bucket-name"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Principal": {
"AWS": "[IAM ARN HERE]"
},
"Resource": "arn:aws:s3:::my-bucket-name/*"
}
]
}
Error Action does not apply to any resource(s) in statement
Simply it means that the action (you wrote in policy) doesn't apply to the resource. I was trying to make public my bucket so that anybody can download from my bucket. I was getting error until I remove ( "s3:ListBucket") from my statement.
{
"Id": "Policyxxxx961",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmtxxxxx4365",
"Action": [
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket-name/*",
"Principal": "*"
}
]
}
Because list bucket doesn't apply inside the bucket, thus by deleting this action policy worked fine.
Just ran into this issue and found a shorter solution for those that want to have ListBucket and GetObject in the same policy. The important thing is to list both the bucket-name and bucket-name/* under Resource.
{
"Id": "Policyxxxx961",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmtxxxxx4365",
"Action": [
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket-name",
"arn:aws:s3:::bucket-name/*"
],
"Principal": "*"
}
]
}
To fix this issue, what you need to do in policy rule, locate the Resource, and add your arn bucket in array, one with * and the second on without * at the end. This will fix the error.
{
"Version": "2012-10-17",
"Id": "Policy3783783783738",
"Statement": [
{
"Sid": "Stmt1615891730703",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::76367367633:user/magazine-demo-root-user"
},
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetBucketLocation",
"s3:DeleteObject",
"s3:AbortMultipartUpload",
"s3:Get*",
"s3:Put*"
],
"Resource": [
"arn:aws:s3:::magazine-demo",
"arn:aws:s3:::magazine-demo/*"
]
}
]
}
Just do one change in json policy resource.
"Resource": ["arn:aws:s3:::bucket-name/*"]
Note : Add /* after bucket-name
Ref Docs :
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html
I have also faced the similar issue while creating the bucket
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mrt9949"
]
}
]
}
I have changed the above code to
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mrt9949/*"
]
}
]
}
add /* to your bucket name it will solve the issue
Here my bucket name is mrt9949
In my case the solution to this error was trying to remove some of Actions that I was applying. Some of them are not relevant to, or cannot work with this resource.
In this case it wouldn't let me include these:
GetBucketAcl
ListBucket
ListBucketMultipartUploads
Whenever you are trying to apply use bucket policies. Remember this thing, If you are using actions like "s3:ListBucket", "s3:GetBucketPolicy", "s3:GetBucketAcl" etc. which are related to bucket, the resource attribute in policy should be mentioned as <"Resource": "arn:aws:s3:::bucket_name">.
Ex.
{
"Version": "2012-10-17",
"Id": "Policy1608224885249",
"Statement": [
{
"Sid": "Stmt1608226298927",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetBucketPolicy",
"s3:GetBucketAcl",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::bucket_name"
}
]
}
If you are using actions like "s3:GetObject", "s3:DeleteObject", "s3:GetObject" etc. which are related to object, the resource attribute in policy should be mentioned as <"Resource": "arn:aws:s3:::bucket_name/*">.
ex.
{
"Id": "Policy1608228066771",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1608228057071",
"Action": [
"s3:DeleteObject",
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::bucket_name/*",
"Principal": "*"
}
]
}
Finally if you are using actions like "s3:ListBucket", "s3:GetObject" etc. these actions are related to both bucket and object then the resource attribute in policy should be mentioned as <"Resource": ["arn:aws:s3:::bucket_name/*", "Resource": "arn:aws:s3:::bucket_name">.
ex.
{
"Version": "2012-10-17",
"Id": "Policy1608224885249",
"Statement": [
{
"Sid": "Stmt1608226298927",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::bucket_name",
"arn:aws:s3:::bucket_name/*"
]
}
] }
Go to Amazon S3 in your instance.
Go to Permissions -> Public Access tab.
Select Edit and uncheck Block all public access and save.
You will see 'Public' tag in Permission tab and Access Control List.
You might have several policy statements and this error is a very generic one. Best is to comment all other statements except any one (like just GetObject, or ListBuckets, Or PutObject) and execute the code and see. If it works fine, it means the ARN path is right. Else, the ARN should include the bucket name alone or a bucketname with /*.
Some resources like ListBucket accept ARN with the full name like "arn:aws:s3:::bucket_name", while GetObject or PutObject expects a /* after the bucket_name. Change the ARNs according to the service and it should work now!
You have to check the pattern of the arn defined under the Resource tag for the Policy-
"Resource": "arn:aws:s3:::s3mybucketname/*"
With the addition of "/*" at the end would help to resolve the issue if you face it even after having your Public Access Policy Unblocked for your Bucket.
From AWS > Documentation > AWS Identity and Access Management > User Guide
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_resource.html
It is clearly defined in a note, Some services do not let you specify actions for individual resources.
you use the wildcard * in the Resource element
"Resource": "arn:aws:s3:::surplace-audio/*"
You can also configure ListBuckets for each folder, like so
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSESPuts-1521238702575",
"Effect": "Allow",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::buckets.email/*",
"Condition": {
"StringEquals": {
"aws:Referer": "[red]"
}
}
},
{
"Sid": "Stmt1586754972129",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::596322993031:user/[red]"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::buckets.email",
"Condition": {
"StringEquals": {
"s3:delimiter": "/",
"s3:prefix": [
"",
"domain.co",
"domain.co/user"
]
}
}
},
{
"Sid": "Stmt1586754972129",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::596322993031:user/[red]"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::buckets.email",
"Condition": {
"StringLike": {
"s3:prefix": "domain.co/user/*"
}
}
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::596322993031:user/[red]"
},
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::buckets.email/domain.co/user/*"
}
]
}
These rules are used together with SES to receive an email, but allows an external user to view the files that were put in the bucket by SES.
I followed the instructions from here: https://aws.amazon.com/blogs/security/writing-iam-policies-grant-access-to-user-specific-folders-in-an-amazon-s3-bucket/
Also, you must specify prefix as domain.co/user/ WITH slash at the end when using the SDK, otherwise you'll get access denied. hope it helps anyone
This is so simple just add "/*" at the end. You have given only the root directory link, but the action needs to be applied to the object.
Type,
"Resource": "arn:aws:s3:::surplace-audio/*"
I found that my ListBuckets was not working because the IAM Principle did not have ListAllMyBuckets permission.