AWS IAM Conditional Policies - amazon-web-services

I am trying to provide access to an IAM policy on the condition that that specific resource has some tag key/value pair. It does not seem to be working, despite following the AWS documentation.
The IAM policy is as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/environment": "dev"
}
}
}
]
}
And I have a S3 bucket (named my-bucket-name) with the tag: environment = dev. Can anyone explain to me why the following command fails?
$ aws s3 ls s3://my-bucket-name
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
$ aws s3 cp s3://my-bucket-name/file.json .
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
UPDATE: based off of #Dennis Traub and #jarmod responses, I edited this slightly to add the tag to the object in the S3 bucket, and I'm still unable to read the object. I also tried changing the condition to "s3:RequestObjectTag/environment": "dev" and still no-go.

If I remember correctly, Amazon S3 does not support condition keys based on bucket tags, only on object tags. That’s why it doesn’t work.

Building off of #Dennis Traub's answer, to get this to work with a specific object in the bucket, the IAM policy must leverage the "s3:ExistingObjectTag/environment": "dev" condition. The following policy worked for me:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*",
"Condition": {
"StringEquals": {
"s3:ExistingObjectTag/environment": "dev"
}
}
}
]
}

Related

Can't copy from from an S3 bucket in another account

Added an update (an EDIT) at the bottom
Info
I have two AWS accounts. One with an S3 bucket and a second one that needs access to it.
On the account with the S3 bucket, the bucket policy looks like this:
{
"Sid": "DelegateS3ToSecAcc",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Second-AWS-ACC-ID:root"
},
"Action": [
"s3:List*",
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::BUCKET-NAME/*",
"arn:aws:s3:::BUCKET-NAME"
]
},
In the second account, that tries to get the file from S3, I've attached the following IAM Policy (There are other policies too but this should give it access):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"s3-object-lambda:Get*",
"s3-object-lambda:List*"
],
"Resource": "*"
}
]
}
Problem
Despite everything, when I run the following command:
aws s3 cp s3://BUCKET-NAME/path/to/file/copied/from/URI.txt .
I get:
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
Did I do something wrong? What did I miss? All my web the web results suggested making sure in the bucket policy I have /* and that the IAM policy allows S3 access but it's already there.
EDIT: aws s3 ls works on the file! It means it just relates to permissions somehow. It works from another AWS that may have uploaded the file. Just need to figure out how to open it up.
The aws s3 cp command does lots of weird stuff, including (it seems) calling head-object.
Try calling the pure S3 API instead:
aws s3api get-object --bucket BUCKET-NAME --key path/to/file/copied/from/URI.txt .

Terraform not able to init with a user with attached Policy document with full access

I have my terraform backend as s3. I get the below error while init:
Error refreshing state: AccessDenied: Access Denied
status code: 403, request id: EYE1JFR2028Y8WA, host id: TSfI4l7i0cSR+tBczEA5nbolYrbBNhieEYItTeN831SUcJ2EZtT91szja0u735Hk9EdWAc=
I am running terraform by exporting these three credentials of a user AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION. That user has a policy document attached which is:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::test-tf-state"
]
}
]
}
I have cross checked bucket arn it is correct yet i get 403 AccessDenied error.
While I put "/*" as suffix in arn terraform init works successfully, example policy below:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::test-tf-state/*"
]
}
]
}
I can't understand this behaviour.
When your resource is:
"arn:aws:s3:::test-tf-state"
this refers only to bucket, not objects in the bucket. This only allows you to perform operations on a bucket, not the objects inside the bucket, nor upload objects to it. But TF must be able to upload and read objects from the bucket.
In contrast, when you have:
"arn:aws:s3:::test-tf-state/*"
then your permissions apply to objects in a bucket. This allows you to put, get or delete these objects.

Uploading to AWS S3 bucket from a profile in a different environment

I have access to one of two AWS environments and I've created a protected S3 bucket in it to upload files to from an account in the one that I do not. The environment and the account that I don't have access to are what a project's CI uses.
environment I have access to: env1
environment I do not have access to: env2
account I do not have access to: user/ci
bucket name: content
S3 bucket policy:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
...
},
{
"Sid": "Allow access to bucket from profile in env1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:user/ci"
},
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket*"
],
"Resource": "arn:aws:s3:::content"
},
{
"Sid": "Allow access to bucket items from profile in env1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:user/ci"
},
"Action": [
"s3:Get*",
"s3:PutObject",
"s3:ListMultipartUploadParts"
],
"Resource": [
"arn:aws:s3:::content",
"arn:aws:s3:::content/*"
]
}
]
}
From inside a container that's configured for env1 and user/ci I'm testing with the command
aws s3 sync content/ s3://content/
and I get the error:
fatal error: An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
I have two questions:
Am I even using the correct aws command to upload the data to the bucket?
Am I missing something from my bucket policy?
For the latter, I've basically followed what a load of examples and answers online have suggested.
To test your policy, I did the following:
Created an IAM User with no policies
Created an Amazon S3 bucket
Attached your Bucket Policy to the bucket, and updated the ARN and bucket name
Tested access to the bucket with:
aws s3 ls s3://bucketname
aws s3 sync folder/ s3://bucketname/folder/
It worked fine.
Therefore, the policy you display appears to be giving all necessary permissions. It is possible that you have something else that is Denying access on the bucket.
The solution was to given the ACL
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::content",
"arn:aws:s3:::content/*"
]
}
]
}
to user/ci in env1.

An error occurred (MalformedPolicy) when calling the PutBucketPolicy operation: Policy has invalid resource

I am trying to make my s3 bucket public through cil, made changes everywhere but still getting error
"An error occurred (MalformedPolicy) when calling the PutBucketPolicy operation: Policy has invalid resource"
{
"Id": "MyPolicy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadForGetBucketObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::task1y/*"
}
]
}
Can anyone suggest me how to solve this issue?
From the documentation the policy should match the below where examplebucket is the bucket name you're attaching the policy to.
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"PublicRead",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::examplebucket/*"]
}
]
}
This error you're receiving indicates that the bucket you're attaching this policy does not share the same name. In other words your resource can only be attached to a bucket named task1y.
Some resources like ListBucket accept the arn with the full name like "arn:aws:s3:::bucket_name", while GetObject or PutObjects expects a /* after the bucket_name. Change the ARNs according to the service and it should work now!

S3 AccessDenied doesn't match policy

I have the following policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "StmtXXX",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::MYBUCKET"
]
}
]
}
(yes, I intend to scope back the s3:* when I get it working)
The following list bucket operation works OK:
$ aws s3 ls s3://MYBUCKET/test --profile MYPROFILE --region eu-west-1
2016-11-30 15:21:13 16712119 test
But a PUT won't work
$ aws s3 cp /tmp/test2 s3://MYBUCKET/test2 --profile MYPROFILE --region eu-west-1
upload failed: ../../../../tmp/test2 to s3://MYBUCKET/test2
A client error (AccessDenied) occurred when calling the CreateMultipartUpload operation: Access Denied
Parameter validation failed:
Invalid type for parameter UploadId, value: None, type: <type 'NoneType'>, valid types: <type 'basestring'>
I've tried this in the IAM Policy Simulator and it seems like it should work. I've verified that the keys correspond to the correct user.
(I've also tried with my own credentials and the operations work fine, so I don't think it's a syntax error)
Should this work? Any ideas why it isn't?
You need to enter the bucket contents as a resource separately from the bucket itself if you are specifying the bucket and object actions in the same statement
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "StmtXXX",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::MYBUCKET",
"arn:aws:s3:::MYBUCKET/*"
]
}
]
}
The answer to this seems to be that the IAM policy can take some time to propagate. This went from not working, to being intermittent, to working.
So if you face an inexplicable situation, wait a few minutes.