I’m an upcoming aws developer and I am trying to understand the best practices. I have a mobile application and all the users will upload photos of their recipes through the app. I am trying to find a way to give limited access to my s3 bucket to my app for users to upload the images. Is there a way to do that with hard coding credentials on my app? So the bucket is private and all objects are private but my app needs to be put in the bucket. I don't know which to pick like AWS Cognito or S3 pre-signed URLs for the app to get limited access. Also, the solution should scale multi-region i.e on an Active-Active deployment it should be routed to the Closest Bucket t the user.
Thank you
Related
I have a static React App I have deployed using Cloudfront - hosted within an S3 Bucket. I would like the user to have the option to upload files in the future, through this app, to the bucket but I am a little confused on the permissions side.
I have created the Bucket with the CDK like so...
val siteBucket = Bucket(
this, "SiteBucket",
BucketProps.builder()
.bucketName(SITE_DOMAIN_NAME)
.websiteIndexDocument("index.html")
.publicReadAccess(true)
.removalPolicy(DESTROY)
.build()
)
I have additional config using the CDK to hook up the CloudFrontWebDistribution and to route the traffic to my domain.
My understanding of the above is that .publicReadAccess(true) allows my Bucket to be accessible to the wider internet - but that it doesn't grant any rights to upload to the bucket.
However, how do I use the CDK to grant permissions for only my static webapp to upload to the Bucket - but not for anyone else to upload?
(I've been reviewing this https://docs.aws.amazon.com/cdk/v2/guide/permissions.html but unsure of the best practise e.g. can my app have a role or permissions assigned to when the app itself is just the contents of a bucket. Do I need to create an Access Point? But again, how do I limit my app to have permissions - is this even possible with a static app or do I need a backend/Lambda to invoke first?)
Thanks!
For one, you don't need publicReadAccess. You can just grant access to the OAI.
https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-access-to-amazon-s3/
This is a pretty good starting point for the page though:
https://aws.amazon.com/blogs/storage/allowing-external-users-to-securely-and-directly-upload-files-to-amazon-s3/
Not sure you necessarily want to use the same bucket to upload to and host your site.
I am trying to understand access security as it relates to Amazon S3. I want to host some files in an S3 bucket, using CloudFront to access it via my domain. I need to limit access to certain companies/individuals. In addition I need to manage that access individually.
A second access model is project based, where I need to make a library of files available to a particular project team, and I need to be able to add and remove team members in an ad hoc manner, and then close access for the whole project at some point. The bucket in question might be the same for both scenarios.
I assume something like this is possible in AWS, but all I can find (and understand) on the AWS site involves using IAM to control access via the AWS console. I don't see any indication that I could create an IAM user, add them to an IAM group, give the group read only access to the bucket and then provide the name and password via System.Net.WebClient in PowerShell to actually download the available file. Am I missing something, and this IS possible? Or am I not correct in my assumption that this can be done with AWS?
I did find Amazon CloudFront vs. S3 --> restrict access by domain? - Stack Overflow that talks about using CloudFront to limit access by Domain, but that won't work in a WfH scenario, as those home machines won't be on the corporate domain, but the corporate BIM Manager needs to manage access to content libraries for the WfH staff. I REALLY hope I am not running into an example of AWS just not being ready for the current reality.
Content stored in Amazon S3 is private by default. There are several ways that access can be granted:
Use a bucket policy to make the entire bucket (or a directory within it) publicly accessible to everyone. This is good for websites where anyone can read the content.
Assign permission to IAM Users to grant access only to users or applications that need to access to the bucket. This is typically used within your organization. Never create an IAM User for somebody outside your organization.
Create presigned URLs to grant temporary access to private objects. This is typically used by applications to grant web-based access to content stored in Amazon S3.
To provide an example for pre-signed URLs, imagine that you have a photo-sharing website. Photos provided by users are private. The flow would be:
A user logs in. The application confirms their identity against a database or an authentication service (eg Login with Google).
When the user wants to view a photo, the application first checks whether they are entitled to view the photo (eg it is their photo). If they are entitled to view the photo, the application generates a pre-signed URL and returns it as a link, or embeds the link in an HTML page (eg in a <img> tag).
When the user accesses the link, the browser sends the URL request to Amazon S3, which verifies the encrypted signature in the signed URL. If if it is correct and the link has not yet expired, the photo is returned and is displayed in the web browser.
Users can also share photos with other users. When another user accesses a photo, the application checks the database to confirm that it was shared with the user. If so, it provides a pre-signed URL to access the photo.
This architecture has the application perform all of the logic around Access Permissions. It is very flexible since you can write whatever rules you want, and then the user is sent to Amazon S3 to obtain the file. Think of it like buying theater tickets online -- you just show the ticket and the door and you are allowed to sit in the seat. That's what Amazon S3 is doing -- it is checking the ticket (signed URL) and then giving you access to the file.
See: Amazon S3 pre-signed URLs
Mobile apps
Another common architecture is to generate temporary credentials using the AWS Security Token Service (STS). This is typically done with mobile apps. The flow is:
A user logs into a mobile app. The app sends the login details to a back-end application, which verifies the user's identity.
The back-end app then uses AWS STS to generate temporary credentials and assigns permissions to the credentials, such as being permitted to access a certain directory within an Amazon S3 bucket. (The permissions can actually be for anything in AWS, such as launching computers or creating databases.)
The back-end app sends these temporary credentials back to the mobile app.
The mobile app then uses those credentials to make calls directly to Amazon S3 to access files.
Amazon S3 checks the credentials being used and, if they have permission for the files being requests, grants access. This can be done for uploads, downloads, listing files, etc.
This architecture takes advantage of the fact that mobile apps are quite powerful and they can communicate directly with AWS services such as Amazon S3. The permissions granted are based upon the user who logs in. These permissions are determined by the back-end application, which you would code. Think of it like a temporary employee who has been granted a building access pass for the day, but they can only access certain areas.
See: IAM Role Archives - Jayendra's Blog
The above architectures are building blocks for how you wish to develop your applications. Every application is different, just like the two use-cases in your question. You can securely incorporate Amazon S3 in your applications while maintaining full control of how access is granted. Your applications can then concentrate on the business logic of controlling access, without having to actually serve the content (which is left up to Amazon S3). It's like selling the tickets without having to run the theater.
You ask whether Amazon S3 is "ready for the current reality". Many of the popular web sites you use every day run on AWS, and you probably never realize it.
If you are willing to issue IAM User credentials (max 5000 per account), the steps would be:
Create an IAM User for each user and select Programmatic access
This will provide an Access Key and Secret Key that you can provide to each user
Attach permissions to each IAM User, or put the users in an IAM Group and attach permissions to the IAM Group
Each user can run aws configure on their computer (using the AWS Command-Line Interface (CLI) to store their Access Key and Secret Key
They can then use the AWS CLI to upload/download files
If you want the users to be able to access via the Amazon S3 management console, you will need to provide some additional permissions: Grant a User Amazon S3 Console Access to Only a Certain Bucket
Alternatively, users could use a program like CyberDuck for an easy Drag & Drop interface to Amazon S3. Cyberduck will also ask for the Access Key and Secret Key.
I wanted to know if I can accomplish my aim of uploading files or large files from my mobile application to my s3 bucket without login into my amazon console. If there is no way to do this, then. How can I upload files once logged in without the annoying web view? Se what others tried.
Should I upload files to Amazon S3 from mobile devices or from my server? Thanks.
What I need to achieve:
Upload files to S3 with no hassles.
Download files when needed with no hassles.
Able to upload large files on S3.
I really don't want to mess with access key and authentication key. Well if I can at least hide them form onlookers that will be fine.
If you can share all the possible file upload implementation in the mobile application scenario that will be great thanks.
You can use SDK for AWS. It must be an application developed in some programming language available for AWS and be able to access the credentials to connect to S3 and work like an interface between the app and the S3 bucket.
All AWS services can be accessed programmatically via an API. In fact, this is the recommended method for using AWS services.
Mobile applications can certainly communicate directly with Amazon S3.
You will want to secure data stored in S3 so that only authorized and authenticated users can access it. This can be accomplished by having the mobile application authenticate with your own back-end service that handles authentication. Alternatively, you could use Amazon Cognito to handle authentication. This way, your app will handle authentication with AWS and users will never see AWS-specific credentials.
We are building a custom application (using LoopBack) that will need to store many large files coming from multiple users, so naturally we're looking at S3. We've done something similar before, with clients uploading files to the server which then processes and uploads them to S3 under one AWS account, but for this new app, we're looking to allow the clients (using a custom iOS app) to use the iOS S3 SDK to upload directly to their own bucket or folder. User accounts will be created on the server.
Is there any way to handle S3 authentication/authorization using custom code? For example, could the iOS client request a temporary token allowing them to upload to a specific S3 bucket or folder? Or would we need to create unique IAM users for each user in our system?
Is that a terrible idea? It sounds like a terrible idea. :)
I found a similar question here but there was no conclusive answer.
Update: I found this article on Temporary Security Credentials that looks very promising. It also suggests using Cognito, which I've never used, if building a mobile app.
Cognito is the way to go. You should definetly not create IAM users for this. IAM is for managing access to the aws services programatically or from the console. Moreover you would need to hardcode the IAM access keys in the ios app, which is not a best practice.
https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_cognito.html
If users of your application are already authenticated, you could generate a pre-signed S3 url on your backend using your credentials. This URL can then be returned to the application and used to upload a file.
It would circumvent having to create individual IAM users/permissions and/or managing bucket policies.
Check out the docs on it here.
Not sure how relevant to your situation.
You can create a role that allows upload to s3 and use SAML web-based identity to authenticate and allow privileges to assume the role and get temp credentials and token.
This will keep very limited time authenticated to S3 upload. ie until the temp credentials expire.
I have data from multiple users inside a single S3 account. My desktop app has an authentication system which let the app know who the user is and which folder to access on S3. but the desktop app has the access code to the whole S3 folder.
somebody told me this is not secure since a hacker could break the request from the app to the S3 and use the credentials to download all the data.
Is this true? and if so how can I avoid it? (he said I need to a client server in the AWS cloud but this isn't clear to me... )
btw. I am using Boto python library to access S3.
thanks
I just found this:
Don't store your AWS secret key in the app. A determined hacker would be able to find it eventially. One idea is that you have a web service hosted somewhere whose sole purpose is to sign the client's S3 requests using the secret key, those requests are then relayed to the S3 service. Therefore you get your users to authenticate agaist your web service using credentials that you control. To re-iterate: the clients talk directly to S3, but get their requests "rubber-stamped"/approved by you.
I don't see S3 necessarily as a flat structure - if you use filesystem notation "folder/subfolder/file.ext" for the keys.
Vanity URLs are supported by S3 see http://docs.amazonwebservices.com/AmazonS3/2006-03-01/VirtualHosting.html - basically the URL "http://s3.amazonaws.com/mybucket/myfile.ext" becomes "http://mybucket.s3.amazonaws.com/myfile.ext" and you can then setup a CNAME in your DNS that maps "www.myname.com" to "mybucket.s3.amazonaws.com" which results in "http://www.myname.com/myfile.ext"
Perfect timing! AWS just announced a feature yesterday that's likely to help you here: Variables in IAM policies.
What you would do is create an IAM account for each of your users. This will allow you to have a separate access key and secret key for each user. Then you would assign a policy to your bucket that restricts access to a portion of the bucket, based on username. (The example that I linked to above has good example of this use case).