AWS S3 bucket policy to allow access to Cognito users - amazon-web-services

I want to create a S3 bucket policy that can prevent public access but only allows who sign up my app thru Cognito to be able to upload object thru app.
Current block public access setting:
Current bucket policy I have:
{
"Version": "2012-10-17",
"Id": "Policy1593320409523",
"Statement": [
{
"Sid": "Stmt1593320397284",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::358110801253:role/Cognito_katebUnauth_Role",
"arn:aws:iam::358110801253:role/service-role/transcribe-role-k5easa7b",
"arn:aws:iam::358110801253:role/Cognito_katebAuth_Role"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::va-raw-audio-to-transcribe/*",
"arn:aws:s3:::va-raw-audio-to-transcribe"
]
}
]
}

Amazon S3 buckets are private by default. Thus, there is no need to "restrict" access. Instead, select an appropriate way to "grant" access to desired users.
When users authenticate via AWS Cognito, the are provided credentials that are linked to an IAM Role. Therefore:
Do not assign permissions via a Bucket Policy - This is normally used to grant public access to all users
Instead, add the permissions to the IAM Role used by Cognito for those authenticated users
You have listed 3 roles in your question. Therefore, add appropriate permissions to each of those 3 IAM Roles so that they can access the desired bucket(s).
Also, be very careful about the permissions you grant. The policy in your Question is granting s3:*, which means the users can delete all objects and can even delete the bucket itself! Always grant minimal permissions so that they have sufficient access, but no more than required.
For example, if you only want to allow them to upload, they would only need s3:PutObject permission.

Related

Why bucket policy does not provide IAM user to list s3 buckets even bucket policy is set for the user?

I have created bucket poc-work from admin account, and under this policy I have set policy like below:
{
"Version": "2012-10-17",
"Id": "Policy1620674317608",
"Statement": [
{
"Sid": "Stmt1321974214233",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accound-id:user/iam-user"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::poc-work",
"arn:aws:s3:::poc-work/*"
]
}
]
}
I have not attached any aws managed policy like s3readonly to IAM user , but I am under assumption that setting bucket policy should make bucket visible to IAM user . But when IAM user log in and check for s3 service there is error message:
You don't have permissions to list buckets
I have below queries:
can't I create bucket policy that enables list s3 buckets ?
Is it necessary to attach policy already defined browsing on IAM console and then rest of operations control with bucket policy ?
You are giving the user permission for one bucket, but if the user is going through the console the user needs the ListAllBuckets permission to see all the buckets that exist in the account. So you do need to add permissions to the IAM user as well--not just the one bucket.
Also see:
https://acloud.guru/forums/s3-masterclass/discussion/-L6X96Lo37ZnG_g6wiEg/ListBucket%20vs%20ListAllMyBuckets
https://stackoverflow.com/a/30961920/230055
https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html#using-with-s3-actions-related-to-buckets
https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-walkthroughs-managing-access-example1.html
The 1st link says:
ListAllMyBuckets is required for seeing the list of buckets via the
AWS console. It is a MUST if you plan to use the console for S3
administration. If you don't have this permission you basically won't
see any of the buckets in the S3 console despite whatever other
permissions you have configured and therefore can't take any action
upon them.

AWS S3 bucket - Allow download files to every IAM and Users from specific AWS Account

Look for a policy for S3 bucket that will allow all IAM roles and users from different account, to be able to download files from the bucket that is located in my AWS account.
Thanks for help
You can apply object level permissions to another account via a bucket policy.
By using the principal of the root of the account, every IAM entity in that account is able to interact with the bucket using the permissions in your bucket policy.
An example bucket policy using the root of the account is below.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AccountB-ID:root"
},
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::awsexamplebucket1"
]
}
]
}
More information is available in the Bucket owner granting cross-account bucket permissions documentation
Fo that, you would need to provide a cross-account access to the objects in your buckets by giving the IAM role or user in the second Account permission to download (GET Object) objects from the needed bucket.
The following AWS post
https://aws.amazon.com/premiumsupport/knowledge-center/cross-account-access-s3/ provides details on how to define the IAM policy.
In your case, you just need the Get object permission.

S3 Bucket Policy to allow S3 Access to Current Authenicated user in AWS Console?

I have an application where I am using Cognito to authenticate users and giving temporary access to AWS Console but that user is able to see all other buckets, I want that user just should be able to see or access buckets created by him.
Currently, I have given S3FullAccess Policy to Cognito users. Can anyone suggest which policy I should attach?
As per my R&D, I can some policies are there that can restrict particular user or allow particular user but my users will be dynamic, so I cannot hard-code the values and also policies like allowing/restricting access to particular buckets, I want only users who create buckets should be able to access not other users.
This is something which i found
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucket-name",
"Condition": {
"StringLike": {
"s3:prefix": [
"",
"home/",
"home/${aws:userid}/*"
]
}
}
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket-name/home/${aws:userid}",
"arn:aws:s3:::bucket-name/home/${aws:userid}/*"
]
}
]
}
But this is listing all buckets and the only accessible bucket is what put in the code above, I want for new user, it should show nothing and as it creates, it should show that only
This is not going to be easy and you will need to create your own policy and enforce some conventions. You have 3 options.
But first, if each user just needs their own S3 space look at S3 Prefix [here](
https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-authentication-part-3-roles-and-policies/) Also, you can do this on the S3 resource bucket. I have a template for doing this here in gitlab
Now back to answering your question.
Option 1; They will need to set a tag when they create the bucket where an "owner" tag is equal to their identity. I striked this one out because despite being listed in the IAM policy I'm pretty sure it doesn't work with S3.
Option 2: The prefix of the bucket name is equal to their identity.
Then you can use the feature of variables and tags in IAM Policy. Read here
Note that coginto users are web federated identities so the variable aws:username is not aviable for you. Use the aws:userid variable and the value will be role id:caller-specified-role-name where role id is the unique id of the role and the caller-specified-role-name is specified by the RoleSessionName parameter passed to the AssumeRoleWithWebIdentity request
Option 3: Use IAM Access Policy
I can not find a link to the how to at the moment. But from here is a detailed description.
Q: How do I control what a federated user is allowed to do when signed in to the console?
When you request temporary security credentials for your federated
user using an AssumeRole API, you can optionally include an access
policy with the request. The federated user’s privileges are the
intersection of permissions granted by the access policy passed with
the request and the access policy attached to the IAM role that was
assumed. The access policy passed with the request cannot elevate the
privileges associated with the IAM role being assumed. When you
request temporary security credentials for your federated user using
the GetFederationToken API, you must provide an access control policy
with the request. The federated user’s privileges are the intersection
of the permissions granted by the access policy passed with the
request and the access policy attached to the IAM user that was used
to make the request. The access policy passed with the request cannot
elevate the privileges associated with the IAM user used to make the
request. These federated user permissions apply to both API access and
actions taken within the AWS Management Console.
The nice thing about this approach is you programmatically create the access policy.

AWS S3 - Assign limited permission to bucket & create IAM who can access that bucket only

I'm developing a mobile application & i want to upload/get/delete a file in AWS S3 bucket.
But I'm very concern about the security problem.
S3 Bucket: It should not be public and only authorize IAM user can access who have the permission to access my bucket.
So, need help to configure permission of my S3 bucket & create an IAM user.
That is not how you authorize access for mobile applications. Yes, you can create IAM user, generate access key and secret access key, store those keys in the application code and configure right permissions for the IAM user. Then you don't even need to configure bucket policy. By default, bucket is private and only IAM users in your account with appropriate permissions are able to access it. If you allow IAM user to access specific S3 bucket then you would need to configure explicit deny on bucket policy to override it.
But the above approach is against every security good practice. What you really want to do is to create IAM role that allows access to the bucket and assume that role from within the application. You can set up Cognito + web federation (or some other web federation provider) for your users and ask STS service to generate short lived credentials using sts:assumeRoleWithWebIdentity command.
As for the IAM permissions, you will need to allow s3:PutObject, s3:GetObject and s3:DeleteObject so the policy can look something like this.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "<arn-of-your-bucket>"
}
]
}
You can be even more granular and allow Cognito users to access only "their" folder inside of a bucket if you need to.
As for the role, you just need to attach the above policy to it and configure trust relationship between the role and web identity provider (as mentioned above, this can be Cognito or any OpenID provider).

One IAM Role across multiple AWS accounts

For security reasons, we have a pre-prod and a prod AWS account. We're now beginning to use IAM Roles for S3 access to js/css files through django-storage / boto.
While this is working correctly on a per account basis, now a need has risen where the QA instance needs to access one S3 bucket on a the prod account.
Is there a way to have one IAM role that can grant access to the pre-prod And prod S3 buckets? As I'm writing it seems impossible, but it never hearts to ask!
Here's the AWS doc on this: http://docs.aws.amazon.com/AmazonS3/latest/dev/example-walkthroughs-managing-access-example2.html
Essentially, you have to delegate permissions to one account from the other account using the Principal block of your Bucket's IAM policy, and then set up your IAM user in the second account as normal.
Example bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Example permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account-ID>:root"
},
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::<bucket-name>"
]
}
]
}
This works well for read-only access, but there can be issues with write access. Primarily, the account writing the object will still be the owner of that object. When dealing with Write permissions, you'll usually want to make sure the account owning the bucket still has the ability to access objects written by the other account, which requires the object to be written with a particular header: x-amz-grant-full-control
You can set up your bucket policy so that the bucket will not accept cross-account objects that do not supply this header. There's an example of that at the bottom of this page: http://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html (under "Granting Cross-Account Permissions to Upload Objects While Ensuring the Bucket Owner Has Full Control")
This makes use of a conditional Deny clause in the bucket policy, like so:
{
"Sid":"112",
"Effect":"Deny",
"Principal":{"AWS":"1111111111" },
"Action":"s3:PutObject",
"Resource":"arn:aws:s3:::examplebucket/*",
"Condition": {
"StringNotEquals": {"s3:x-amz-grant-full-control":["emailAddress=xyz#amazon.com"]}
}
}
I generally avoid cross-account object writes, myself...they are quite fiddly to set up.