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
Related
I generated the below code using S3 policy generator, when I paste the code in AWS S3 edit policy console it shows error. Pls help
{
"Id": "Policy1611491895768",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1611491893687",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::aws-landing-zone-configuration-756692330110-ap-south-1",
"Principal": {
"AWS": [
"\"AWS\": \"arn:aws:iam::756692330110::user/aravindkumar.s#gmail.com\""
]
}
}
]
}
There are few issues,
GetObject is applicable only to bucket objects not bucket , so, Resouce should contain /* at the end.
Principle is not formatted right.
Here is updated policy
{
"Version": "2012-10-17",
"Id": "Policy1611491895768",
"Statement": [
{
"Sid": "Stmt1611491893687",
"Effect": "Allow",
"Principal": {
"AWS": ["arn:aws:iam::756692330110:user/aravindkumar.s#gmail.com"]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::aws-landing-zone-configuration-756692330110-ap-south-1/*"
}
]
}
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/*"
}
]
}
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": "*"
}
I am trying to give all permissions on a single s3 bucket but a single folder. I am trying to use explicit deny the folder name being Beijing path is like
buck123-test/china/Beijing/. bucket name is buck123-test.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1561641021576",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::buck123-test"
},
{
"Sid": "Stmt1561639869054",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::buck123-test/china/Beijing"
}
]
}
how can i achieve my requirement as the above policy is not working
Your policy is missing Allow actions for objects in your bucket.
What about ? (not tested myself, let's report if this works)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1561641021576",
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::buck123-test", "arn:aws:s3:::buck123-test/*"]
},
{
"Sid": "Stmt1561639869054",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::buck123-test/china/Beijing/*"
}
]
}
Note that you need the two resources. The bucket name only resource is required for ListBucket and other bucket level operations. The /* resource is required for object level operations like Put and Get
Revised answer, you were missing some critical pieces to the policy document, try this as it should work, but I have not tested this.
You can add additional actions if you want to allow users to GetObject, PutObject etc.
{
"Id": "Policy1561648158487",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1561648106618",
"Action": "s3:*",
"Effect": "Deny",
"Resource": "arn:aws:s3:::buck123-test/china/Beijing/*",
"Principal": "*"
},
{
"Sid": "Stmt1561648156125",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::buck123-test/*",
"Principal": "*"
}
]
}
I'm building an app that lets Everyone to upload to my S3 bucket, but for security purposes I need to disable the ability to delete from the bucket. Since upload/delete permissions are bundled together in the AWS settings, how can I allow one and prevent the other?
SOLUTION:
remove the Access Policy and add a bucket policy with this:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket_name/*"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::<bucket_name>/*"
}
]
}
Read this article about the difference between ACL's and IAM policies:
https://blogs.aws.amazon.com/security/post/TxPOJBY6FE360K/IAM-policies-and-Bucket-Policies-and-ACLs-Oh-My-Controlling-Access-to-S3-Resourc
You want to create an IAM policy similar to this, not use an ACL:
{
"Statement": [
{
"Action": [
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::<bucket>/<optional_key>",
"Principal": {
"AWS": ["*"]
}
}
]
}