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

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).

Related

Giving customer AWS access to my AWS's specific s3 bucket?

How do i grant a customer read/write access to a specific S3 bucket in my AWS account without giving them access to any other buckets or resources?
They should be able to access this bucket from a powershell script in some ec2 instance of theirs.
found this policy
{
"Version": "2012-10-17",
"Id": "PolicyForBucketX",
"Statement": [
{
"Sid": "AllowCustomerRWAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::bucket-x/*"
}
]
}
Giving customer AWS access to my AWS's specific s3 bucket?
with this, they might be able to access s3 via their access key in powershell. However they might not be using access key hardcoded to use s3. They might be using STS with instance role for the ec2 to access their s3 resources.
Would this work still? Would they then have to add my bucket x into their instance role permissions buckets?
Any better way? I might/might not have details of their AWS resource IDs.
With Bucket policy and IAM policy (either for user or a role) you can restrict users/resources based on the requirement.
I agree with Maurice here as extent of restriction would heavily depend on what you specifically want to do.
You can also use CloudFront and restrict access to your bucket objects for users not managed by IAM.
In general you should think of access as two part task. On the side of the resource, you grant permissions to a resource, in this case you are doing that for a specific bucket (resource) for a cross account (principal). You're done.
Now, the identity that will access it will also needs permissions given to them by the account administrator (root) the same way. I.e. grant the user/role the permissions to
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject"
If they would like to use an instance which has AWS PowerShell installed, they can create an instance profile / role that has the above permissions, and they will be able to run the commands and access your bucket. That's right way to do it.
Regardless of how they access to the instance, when they make the api call from the instance to your bucket, AWS will first check to see if the caller (which could be instance profile or a role they assumed) has permissions to these actions (customer setup). It will then be checked to see if the resource allows these actions (your setup).

AWS S3 bucket policy to allow access to Cognito users

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.

Disable AWS S3 Management Console

Is it possible to disable AWS S3 management console for the security reasons?
We don't want anyone including root/admin users to access customer files directly from the AWS S3. We should just have programmatic access to the files stored in S3.
If this is not possible, is it possible to stop listing the directories inside the bucket for all users ?
This is a tricky one to implement, however the following should be able to fulfill the requirements.
Programmatic Access Only
You need to define exactly which actions should be denied you would not want to block access completely otherwise you might lose the ability to do anything.
If you're in AWS you should use IAM roles, and a VPC endpoint to connect to the S3 service. Both of these support the ability to control access within your S3 buckets Bucket Policy.
You would use this to deny List* actions where the source is not the VPC endpoint. You could also deny where its not a specific subset of roles.
This works for all programmatic use cases and for people who login as an IAM user from the console, however this does not deny access to the root user.
Also bear in mind for any IAM user/IAM role that they do not have access unless you explicitly give it to them via an IAM policy.
Denying Access To The Root User
There is currently only one way to deny access to the root user of an AWS account (although you should share these credentials with anyone, even within your company) as that is using a Service Control Policy.
To do this the account would need to be part of an AWS organisation (as an organisational unit). If/once it is you would create a SCP that denies access to the root principal for the specific actions that you want.
An example of this policy for you would be
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RestrictS3ForRoot",
"Effect": "Deny",
"Action": [
"s3:List*"
],
"Resource": [
"*"
],
"Condition": {
"StringLike": {
"aws:PrincipalArn": [
"arn:aws:iam::*:root"
]
}
}
}
]
}
Yes, it is possible to disable the Management Console: Don't give users a password.
When creating IAM Users, there are two ways to provide credentials:
Sign-in Credentials (for the Console)
Access Key (for API calls)
Only give users an Access Key and they won't be able to login to the console.
However, please note that when when using the Management Console, users have exactly the same permissions as using an Access Key. Thus, if they can do it in the console, then they can do it via an API call (if they have an Access Key).
If your goal is to prevent anyone from accessing customer files, then you can add a Bucket Policy with a Deny on s3:* for the bucket, where the Principal is not the customer.
Please note, however, that the Root login can remove such a policy.
If the customers really want to keep their own data private, then they would need to create their own AWS account and keep their files within it, without granting you access.

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.

S3 giving someone permission to read and write

I've created a s3 server which contain a large number of images. I'm now trying to create a bucket policy, which fits my needs. First of all i want everybody to have read permission, so they can see the images. However i also want to give a specific website the permission to upload and delete images. this website is not stored on a amazon server? how can i achieve this? so far i've created an bucket policy which enables everybody to see the images
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::examplebucket/*"
}
]
}
You can delegate access to your bucket. To do this, the other server will need AWS credentials.
If the other server were an EC2 instance that you owned then you could do this easily by launching it with an IAM role. If the other server were an EC2 instance that someone else owned, then you could delegate access to them by allowing them to assume an appropriate IAM role in your account. But for a non-EC2 server, as seems to be the case here, you will have to provide AWS credentials in some other fashion.
One way to do this is by adding an IAM user with a policy allowing s3:PutObject and s3:DeleteObject on resource "arn:aws:s3:::examplebucket/*", and then give the other server those credentials.
A better way would be to create an IAM role that has the same policy and then have the other server assume that role. The upside is that the credentials must be rotated periodically so if they are leaked then the window of exposure is smaller. To assume a role, however, the other server will still need to authenticate so will need some base IAM user credentials (unless you have some way to get credentials via identity federation). You could add a base IAM user who has permissions to assume the aforementioned role (but has no other permissions) and supply the base IAM user credentials to the other server. When using AssumeRole in this fashion you should require an external ID. You may also be able to restrict the entity assuming this role to the specific IP address(es) of the other server using a policy condition (not 100% sure if this is possible).
The Bucket Policy will work nicely to give everybody read-only access.
To give specific permissions to an application:
Create an IAM User for the application (this also creates access credentials)
Assign a policy to the IAM User that gives the desired permissions (very similar to a Bucket Policy)
The application then makes API calls to Amazon S3 using the supplied access credentials
See also: Amazon S3 Developer Guide