I have an S3 bucket that has in its policy permission for my CloudFront origin access identity:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <mine>"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<my-bucket>/*"
}
]
}
Additionally I've created a group and attached the AmazonS3FullAccess managed policy to it and added an IAM user to that group. The managed policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
However when that user tries to add anything to the bucket, I get a 403 (access denied). I'm unsure if any other operations work, I haven't written code to try them. It's only when I specifically allow that user's ARN access to the bucket directly in the bucket policy that they're allowed to add objects. What am I missing? It seems like the above group policy should allow members of that group access to all operations in all buckets, but it doesn't do that.
EDIT: After a whole bunch more poring over documentation, I think I've figured out that Amazon doesn't intend for groups to be used this way. They want you to use roles instead, which you can assign to an EC2 instance for automagic credential management. That's fine, but then I can't figure out how to test my code (using the aws-sdk Ruby gem) locally. Amazon says to define environment variables for your access ID and key - but what access ID and key? There's no such thing for a role...
Try replacing (in your policy):
"Resource": "arn:aws:s3:::<my-bucket>/*"
with:
"Resource": ["arn:aws:s3:::<my-bucket>", "arn:aws:s3:::<my-bucket>/*",]
and:
"Principal": {"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <mine>"},
with:
"Principal": {"AWS": "arn:aws:iam::ACCOUNT_ID:user/USERNAME"},
Related
Be default our users have full S3 access via IAM, I have one bucket however that I need to limit access to one specific user, and block all other users.
I followed this guide here https://aws.amazon.com/premiumsupport/knowledge-center/explicit-deny-principal-elements-s3/
and made this bucket policy -
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::XXXXXXXXXXXX:user/USERWHONEEDSACCESS"
]
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::NAMEOFBUCKET/*"
},
{
"Sid": "",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::NAMEOFBUCKET/*",
"Condition": {
"StringNotLike": {
"aws:userid": "USERWHONEEDSACCESS:*"
}
}
}
]
}
However it no worky. Any suggestions?
You can try the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Principal": {
"AWS": [
"arn:aws:iam::XXXXXXXXXXXX:user/USERWHONEEDSACCESS"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::nameofbucket/*",
"arn:aws:s3:::nameofbucket"
],
"Effect": "Allow"
},
{
"NotPrincipal": {
"AWS": [
"arn:aws:iam::XXXXXXXXXXXX:user/USERWHONEEDSACCESS"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::nameofbucket/*",
"arn:aws:s3:::nameofbucket"
],
"Effect": "Deny"
}
]
}
In the How to Restrict Amazon S3 Bucket Access to a Specific IAM Role blog post you can read more about using NotPrincipal and restricting access to a single IAM User, specifically:
You can use the NotPrincipal element of an IAM or S3 bucket policy to limit resource access to a specific set of users. This element allows you to block all users who are not defined in its value array, even if they have an Allow in their own IAM user policies.
To generate this policy code snippet, I used this: https://asecure.cloud/a/s3_restrict_iam_user/ and I pre-filled the iamPrincipal and bucketName parameters with your example values.
While #Rigerta 's answer will work, I think it's worthy to explain why and how you can make your policy work
If you notice, in your policy you're specifying that only that user will be able to access all objects in your bucket
"Resource": "arn:aws:s3:::NAMEOFBUCKET/*"
However, the way IAM permissions work for S3 buckets is a bit tricky. Yes, that user has access to all objects and if he/she tries to push/pull an object via cli the operation will probably succeed, although via AWS console the bucket is unreachable. It's because the user has only access to the objects in the bucket, not the bucket itself
Therefore, you need to add the bucket to your resources. Changing
"Resource": "arn:aws:s3:::NAMEOFBUCKET/*"
by
"Resource": ["arn:aws:s3:::NAMEOFBUCKET/*", "arn:aws:s3:::NAMEOFBUCKET"]
should make it work.
You can check this blogpost for an example of an IAM policy for accessing a bucket. Notice how different actions are granted to different resources
Make sure that you are using an IAM unique identifier in your condition (it should start with the letters AIDA for IAM users).
"StringNotLike": {
"aws:userid": "AIDAXXXXXXXXXXXXX:*"
}
I suspect that you have written the username in your condition because you use the same placeholder as in the Principal. The IAM User Id is distinct from the username and the arn and cannot be found through the Console, but you can for example retrieve it with the aws cli get-user command.
I'm trying to add multiple CloudFront distributions to a secured bucket
I saw another StackOverflow post where you add multiple users like this, but I'm getting the Invalid principal in policy error
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity **************",
"arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity **************"
]
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
How can I add multiple principles?
Your policy is correct. However, the error Invalid principal in policy often indicates that the principles simply don't exist yet. Make sure that you've already created two OAI users and you are using their IDs correctly in your policy.
For one AWS S3 bucket, I would like to deny access to everyone except for one specific IAM role. I created a role-based policy to allow access and that works. But other IAM users are also able to access objects and I want to prevent this. I tried adding a bucket policy like this, which denies everyone except this principal and then allows this principal. But this policy blocks access to everyone including that role.
The other IAM users I am trying to block are attached to the built-in AdminstratorAccess policy.
{
"Version": "2012-10-17",
"Id": "PolicySecretBucket",
"Statement": [
{
"Sid": "StmtDenyAll",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::********:role/service-role/my-role"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*"
},
{
"Sid": "StmtAllowLambdaBot",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::********:role/service-role/my-role"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
this is how I would do it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyExampleBucket",
"arn:aws:s3:::MyExampleBucket/*"
],
"Condition": {
"StringNotLike": {
"aws:userId": [
"AROAEXAMPLEID:*",
"ACCOUNT NUMBER"
]
}
}
}
]
}
this is how it works.
the user's will have an IAM policy which allows s3.* actions
we will deny all the s3 actions for the bucket MyExampleBucket for any user id but the user id of the role (and the user id of the root account in case if the role is deleted) using the bucket policy
to get the user id of the role:
aws iam get-role --role-name ROLE-NAME
And finally, why yours does not work: https://serverfault.com/a/988136
reference:
https://aws.amazon.com/blogs/security/how-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/
Denying access to a specific bucket is actually quite difficult.
For example, an Administrator might have permissions to assume the Role, so they can still access the bucket.
You would also need to review all policies to ensure that only authorized people can use iam:PassRole to assume the role via an Amazon EC2 instance.
An safer approach would be to put the bucket in a separate AWS Account. Then, only give cross-account access to specific users (not a Role). This way, the default is that Admins have zero access and you then grant access to the desired people. There are less ways to "get around" this type of access.
I have an IAM Role for my Federated Identity Pool in Cognito. I want to give this role access to my Elasticsearch domain.
I added an inline policy to give read access to my Elasticsearch domain name using the new visual editor. I've attached this policy below.
I'm confused how to configure the access policy now for the Elasticsearch domain to give access to my IAM Role.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "es:ListTags",
"Resource": "arn:aws:es:us-west-2:ACCOUNT_ID:domain/DOMAIN_NAME"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "es:ESHttpPost",
"Resource": "*"
}
]
}
EDIT: I was still never able to figure this out. We also tried locking things down with a VPN but then we were not able to access services like Kibana.
Currently I have group with a policy that looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1449507915000",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::artmakeit",
"arn:aws:s3:::artmakeit/*"
]
},
{
"Sid": "ListAllBuckets",
"Action": "s3:ListAllMyBuckets",
"Effect": "Allow",
"Resource": "*"
}
]
}
So, the IAM user, my client, can access his bucket correctly. But I am wondering if I can only let him see his bucket and not the complete list of my buckets. Is there a way to achieve this? I guess I should change the ListAllBuckets permission, but I don't know what to write instead, any ideas?
If users intend to access their buckets via the AWS Management Console, then they require the ListAllBuckets permission.
It is not possible to 'hide' the complete bucket list when using the console -- either they see them all or none at all.
Access via other methods (eg the AWS Command-Line Interface (CLI) or an API call) does not require that this permission be assigned.