Connecting Amazon S3 bucket to Other Server - IAM - amazon-web-services

I am trying to connect Amazon S3 to other services through Bucket policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"arn:aws:iam::ACCOUNT-ID:user/augmen",
}
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetObject"
],
"Resource": ["arn:aws:s3:::rajatv.input",
"arn:aws:s3:::rajatv.input/*"]
}
]
}
Still getting errors like:
This policy contains invalid Json
Invalid Bucket syntax
No Resources

It appears that you are wanting to give bucket access to a specific IAM User. If so, the best way is to put a policy on the IAM User themselves, so that the permissions apply only to them.
This policy would grant bucket access to whichever user has it as an IAM policy. To add it, go to the user, Add Inline Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PermitBucketAccess",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::rajatv.input",
"arn:aws:s3:::rajatv.input/*"
]
}
]
}
Bucket Policies, which are applied to the bucket itself, are best used to grant access to everyone, whereas an IAM policy is best for granting permissions to specific IAM Users, Groups and Roles.

Principal needs to have this format:
"Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},

Related

AWS Bucket Policy - limit access to a bucket with bucket policy

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.

Getting error: "Has prohibited field Principal", when creating policy

I want to create a policy to allow everyone to read my S3 bucket, this is the policy that I have created (I am following this guide):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::my-s3-bucket/*",
"Principal": "*"
}
]
}
I cannot create this policy, this is the error that I am getting:
This policy contains the following error: Has prohibited field
Principal For more information about the IAM policy grammar, see AWS
IAM Policies
The problem was, I was creating the new Policy in IAM. I had to add the policy in S3, as a bucket Policy:
Select S3 Bucket -> Permissions -> Bucket Policy: paste the policy here
Note: If you want to grant read permission to anonymous user at the bucket level, then you need to turn off the following two settings.
I have generated the policy which you want using the Policy Generator.
{
"Id": "Policy1567210887639",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1567210883302",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-s3-bucket/*",
"Principal": "*"
}
]
}
Check if this works for you.

AWS IAM Policy Issues writing to s3 bucket for Grafana alerts

Having some issues with AWS permissions and policies for grafana to be able to upload images. First off I tried with a custom policy attached to my user based on the requirements here https://grafana.com/docs/installation/configuration/#access-key.
Here's the policy:
custom policy with locked down permissions and bucket name
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::myclient-grafana-images"
}
]
}
This unfortunately didn't work and can see an access denied error in my grafana logs. The user is trying to write an image to the bucket and ended up adding the AWS predefined policy for s3 full access. This managed to get it working
s3 full access policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
The question is trying to lock the policy down just to the bucket that I need. I've tried creating a new policy with the full access policy and updated the wildcard to reference the s3 arn but that didn't work either.
Any suggestions on the best way to lock down the policies.
The PutObject and PutObjectAcl actions work on objects, not buckets.
This means that your Resource key should represent objects. ARN for objects start with the bucket name but are followed by a / and a path.
You should adapt your policy in the following way if you want to be able to put any object in your bucket (note the /*):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::myclient-grafana-images/*"
}
]
}

AWS. Get list of Permissions for IAM user

I have some question about IAM permissions. I have IAM User. who has such minimal permissions
1) For IAM:
{
"Version": "2010-12-14",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:ChangePassword"
],
"Resource": [
"arn:aws:iam::*:user/${aws:username}"
]
},
{
"Effect": "Allow",
"Action": [
"iam:GetAccountPasswordPolicy"
],
"Resource": "*"
}
]
}
2) For S3
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1234567890123",
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:ListBucket",
"s3:PutObject"
],
"Resource": [
"*"
]
}
]
}
And I need to write some Api, using Java SDK, which be ablle to check if user has this minimal permissions, but on this level of access, I can not get my own permissions, policies, roles. It is possible to do so with this level of access?
Using AWS java sdk you can get IAM permissions of yours and other IAM users. But you need to have required AWS resource permission.
For ex http://docs.aws.amazon.com/cli/latest/reference/iam/list-user-policies.html
To list other user policies you should have IAM:list-user-policies.
Likewise whatever AWS resources you try to access require permissions to query the resource. Your permissions can be set directly to you in permissions or role with permissions have been assigned to you.
I had an issue with identifying IAM user permission and I had to write an API that had to be responsible for that. So used AWS java SDK, IAM module, where such ability had already presented. I used simulatePrincipalPolicy request

S3 bucket policy, how to ALLOW a IAM group from another account?

I have one S3 bucket in one AWS account (say arn:aws:s3:::my-test-bucket), that needs to be accessed by a IAM group that is defined in another AWS account (say arn:aws:iam::1111222333444:group/mygroup). The following access policy refuses to save, and tells that arn:aws:s3:::my-test-bucket is an invalid principal.
{
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:List*",
"s3:Get*"
],
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111222333444:group/mygroup"
},
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Sid": "allow-put-for-dedicated-group"
}
],
}
I have tested by replacing the group with one of the users of the other account and this works:
{
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:List*",
"s3:Get*"
],
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1111222333444:user/me"
},
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Sid": "allow-put-for-dedicated-user"
}
],
}
The group is existing, I do not understand why it says it is an invalid principal. In fact it does not accept any group of my other account.
Does anyone have an explanation (and possibly a solution) to this behaviour?
Thanks in advance,
Cheers
IAM groups are not valid principals in S3 bucket policies. See this AWS forum post and this SO post for more discussion.
Here's one idea: create an IAM role (for example cross-account-s3) in account #1 (the account with the S3 bucket). That role should have a policy that allows the appropriate S3 bucket access and it should have a trust relationship that says account #2 is trusted for sts:AssumeRole. Then in account #2, delegate permission to assume the cross-account-s3 role to the relevant IAM group. This requires you to trust the IAM admins in the 2nd account to not allow the wrong users to assume the cross-account-s3 role.
As jarmod said, IAM groups are not valid principles. Also jarmod's solution will work. However it is possible to reference the role that is assumed in the S3 bucket policy. This allows you to deny actions unless they are performed by that role, which then provides the visibility of who has access that you wanted or could be used to further limit the access provided. The role reference is via the Role ID, which can be obtained by the following AWS CLI command: aws iam get-role --role-name ROLE_NAME --profile PROFILE_NAME, where ROLE_NAME is the name of the role created with sts:AssumeRole and PROFILE_NAME is the AWS profile setup to access the role.
Something like the following could then be used for the S3 bucket policy:
{
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:PutObject",
"s3:List*",
"s3:Get*"
],
"Effect": "Deny",
"Principal": "*"
"Resource": [
"arn:aws:s3:::my-test-bucket",
"arn:aws:s3:::my-test-bucket/*"
],
"Sid": "deny-put-for-anyone-but-dedicated-role",
"Condition": {
"StringNotLike": {
"aws:userId": [
"ROLE_ID:*"
]
}
}
}
],
}
More details about this can be found in this blog post, which includes using userId to limit access to a user.